From b94363417231d5c90536b5de2b6c218591e170df Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Thu, 3 Nov 2022 15:23:07 -0600 Subject: [PATCH 01/31] update chromium MD5 checksum (#144553) * update chromium MD5 checksum * only update md5 for intel --- x-pack/plugins/screenshotting/server/browsers/chromium/paths.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/screenshotting/server/browsers/chromium/paths.ts b/x-pack/plugins/screenshotting/server/browsers/chromium/paths.ts index a04308c27dd8e..8ac6469696612 100644 --- a/x-pack/plugins/screenshotting/server/browsers/chromium/paths.ts +++ b/x-pack/plugins/screenshotting/server/browsers/chromium/paths.ts @@ -45,7 +45,7 @@ export class ChromiumArchivePaths { platform: 'darwin', architecture: 'x64', archiveFilename: 'chrome-mac.zip', - archiveChecksum: '5afc0d49865d55b69ea1ff65b9cc5794', + archiveChecksum: 'dd4d44ad97ba2fef5dc47d7f2a39ccaa', binaryChecksum: '4a7a663b2656d66ce975b00a30df3ab4', binaryRelativePath: 'chrome-mac/Chromium.app/Contents/MacOS/Chromium', location: 'common', From 22be0dfecfce0bebfe0cfa0f79c959d8d2a71c47 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Thu, 3 Nov 2022 20:16:24 -0400 Subject: [PATCH 02/31] [Synthetics] project monitors - POST create/update (#143578) * unskip monitor state scoping tests * add describe.only * unskip monitor state scoping test * add retry logic * mark old project monitor formatter as legacy * add new create project monitor api * [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' * Update x-pack/plugins/synthetics/server/synthetics_service/project_monitor/project_monitor_formatter.ts * Update x-pack/plugins/synthetics/server/synthetics_service/project_monitor/project_monitor_formatter.ts * error handling * update route verb * [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' * add request limit * adjust verb in tests * [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' * [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' * seperate create and update actions * Revert "seperate create and update actions" This reverts commit abe30ee8ee62854466ab9f7dfaf05c9473642ab2. * update api paths and verbs * update test * add unit testing * adjust imports * update legacy project monitor formatter * [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' * update import * [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' * update tests Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../synthetics/common/constants/rest_api.ts | 2 + .../monitor_types_project.ts | 6 + .../plugins/synthetics/server/routes/index.ts | 4 +- .../monitor_cruds/add_monitor_project.ts | 54 +- .../add_monitor_project_legacy.ts | 84 + .../monitor_cruds/delete_monitor_project.ts | 2 +- .../project_monitor_formatter.test.ts | 72 - .../project_monitor_formatter.ts | 291 +-- .../project_monitor_formatter_legacy.test.ts | 653 +++++ .../project_monitor_formatter_legacy.ts | 534 +++++ .../apis/synthetics/add_monitor_project.ts | 1468 +++--------- .../synthetics/add_monitor_project_legacy.ts | 2127 +++++++++++++++++ .../apis/synthetics/delete_monitor_project.ts | 14 +- .../apis/synthetics/get_monitor_project.ts | 14 +- .../api_integration/apis/synthetics/index.ts | 1 + .../uptime/rest/sample_data/test_policy.ts | 26 +- 16 files changed, 3939 insertions(+), 1413 deletions(-) create mode 100644 x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor_project_legacy.ts create mode 100644 x-pack/plugins/synthetics/server/synthetics_service/project_monitor/project_monitor_formatter_legacy.test.ts create mode 100644 x-pack/plugins/synthetics/server/synthetics_service/project_monitor/project_monitor_formatter_legacy.ts create mode 100644 x-pack/test/api_integration/apis/synthetics/add_monitor_project_legacy.ts diff --git a/x-pack/plugins/synthetics/common/constants/rest_api.ts b/x-pack/plugins/synthetics/common/constants/rest_api.ts index 33bd608d8f5ec..eaf3ba8c36b14 100644 --- a/x-pack/plugins/synthetics/common/constants/rest_api.ts +++ b/x-pack/plugins/synthetics/common/constants/rest_api.ts @@ -49,5 +49,7 @@ export enum API_URLS { // Project monitor public endpoint SYNTHETICS_MONITORS_PROJECT = '/api/synthetics/project/{projectName}/monitors', + SYNTHETICS_MONITORS_PROJECT_UPDATE = '/api/synthetics/project/{projectName}/monitors/_bulk_update', + SYNTHETICS_MONITORS_PROJECT_DELETE = '/api/synthetics/project/{projectName}/monitors/_bulk_delete', SYNTHETICS_MONITORS_PROJECT_LEGACY = '/api/synthetics/service/project/monitors', } diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_project.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_project.ts index ef5f6a23b4413..b5ce7c06200fc 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_project.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types_project.ts @@ -45,6 +45,10 @@ export const ProjectMonitorCodec = t.intersection([ ]); export const ProjectMonitorsRequestCodec = t.interface({ + monitors: t.array(ProjectMonitorCodec), +}); + +export const LegacyProjectMonitorsRequestCodec = t.interface({ project: t.string, keep_stale: t.boolean, monitors: t.array(ProjectMonitorCodec), @@ -69,6 +73,8 @@ export type ProjectMonitorThrottlingConfig = t.TypeOf; +export type LegacyProjectMonitorsRequest = t.TypeOf; + export type ProjectMonitorsRequest = t.TypeOf; export type ProjectMonitorsResponse = t.TypeOf; diff --git a/x-pack/plugins/synthetics/server/routes/index.ts b/x-pack/plugins/synthetics/server/routes/index.ts index c1c06215c8c16..546dda039ba22 100644 --- a/x-pack/plugins/synthetics/server/routes/index.ts +++ b/x-pack/plugins/synthetics/server/routes/index.ts @@ -27,6 +27,7 @@ import { installIndexTemplatesRoute } from './synthetics_service/install_index_t import { editSyntheticsMonitorRoute } from './monitor_cruds/edit_monitor'; import { addSyntheticsMonitorRoute } from './monitor_cruds/add_monitor'; import { addSyntheticsProjectMonitorRoute } from './monitor_cruds/add_monitor_project'; +import { addSyntheticsProjectMonitorRouteLegacy } from './monitor_cruds/add_monitor_project_legacy'; import { syntheticsGetPingsRoute } from './pings'; import { createGetCurrentStatusRoute } from './status/current_status'; import { @@ -37,6 +38,7 @@ import { getHasZipUrlMonitorRoute } from './fleet/get_has_zip_url_monitors'; export const syntheticsAppRestApiRoutes: SyntheticsRestApiRouteFactory[] = [ addSyntheticsMonitorRoute, + addSyntheticsProjectMonitorRoute, getSyntheticsEnablementRoute, deleteSyntheticsMonitorRoute, deleteSyntheticsMonitorProjectRoute, @@ -59,5 +61,5 @@ export const syntheticsAppRestApiRoutes: SyntheticsRestApiRouteFactory[] = [ ]; export const syntheticsAppStreamingApiRoutes: SyntheticsStreamingRouteFactory[] = [ - addSyntheticsProjectMonitorRoute, + addSyntheticsProjectMonitorRouteLegacy, ]; diff --git a/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor_project.ts b/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor_project.ts index 533690de30bed..0d1eea6cf419d 100644 --- a/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor_project.ts +++ b/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor_project.ts @@ -5,25 +5,24 @@ * 2.0. */ import { schema } from '@kbn/config-schema'; -import { UMServerLibs } from '../../legacy_uptime/lib/lib'; +import { i18n } from '@kbn/i18n'; import { ProjectMonitor } from '../../../common/runtime_types'; -import { SyntheticsStreamingRouteFactory } from '../../legacy_uptime/routes/types'; +import { SyntheticsRestApiRouteFactory } from '../../legacy_uptime/routes/types'; import { API_URLS } from '../../../common/constants'; import { getAllLocations } from '../../synthetics_service/get_all_locations'; import { ProjectMonitorFormatter } from '../../synthetics_service/project_monitor/project_monitor_formatter'; const MAX_PAYLOAD_SIZE = 1048576 * 20; // 20MiB -export const addSyntheticsProjectMonitorRoute: SyntheticsStreamingRouteFactory = ( - libs: UMServerLibs -) => ({ +export const addSyntheticsProjectMonitorRoute: SyntheticsRestApiRouteFactory = () => ({ method: 'PUT', - path: API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY, + path: API_URLS.SYNTHETICS_MONITORS_PROJECT_UPDATE, validate: { + params: schema.object({ + projectName: schema.string(), + }), body: schema.object({ - project: schema.string(), - keep_stale: schema.boolean(), monitors: schema.arrayOf(schema.any()), }), }, @@ -34,15 +33,25 @@ export const addSyntheticsProjectMonitorRoute: SyntheticsStreamingRouteFactory = }, handler: async ({ request, + response, savedObjectsClient, server, syntheticsMonitorClient, - subject, }): Promise => { + const { projectName } = request.params; + const decodedProjectName = decodeURI(projectName); + const monitors = (request.body?.monitors as ProjectMonitor[]) || []; + const spaceId = server.spaces.spacesService.getSpaceId(request); + + if (monitors.length > 250) { + return response.badRequest({ + body: { + message: REQUEST_TOO_LARGE, + }, + }); + } + try { - const monitors = (request.body?.monitors as ProjectMonitor[]) || []; - const spaceId = server.spaces.spacesService.getSpaceId(request); - const { keep_stale: keepStale, project: projectId } = request.body || {}; const { publicLocations, privateLocations } = await getAllLocations( server, syntheticsMonitorClient, @@ -51,9 +60,8 @@ export const addSyntheticsProjectMonitorRoute: SyntheticsStreamingRouteFactory = const encryptedSavedObjectsClient = server.encryptedSavedObjects.getClient(); const pushMonitorFormatter = new ProjectMonitorFormatter({ - projectId, + projectId: decodedProjectName, spaceId, - keepStale, locations: publicLocations, privateLocations, encryptedSavedObjectsClient, @@ -62,23 +70,23 @@ export const addSyntheticsProjectMonitorRoute: SyntheticsStreamingRouteFactory = server, syntheticsMonitorClient, request, - subject, }); await pushMonitorFormatter.configureAllProjectMonitors(); - subject?.next({ + return { createdMonitors: pushMonitorFormatter.createdMonitors, updatedMonitors: pushMonitorFormatter.updatedMonitors, - staleMonitors: pushMonitorFormatter.staleMonitors, - deletedMonitors: pushMonitorFormatter.deletedMonitors, failedMonitors: pushMonitorFormatter.failedMonitors, - failedStaleMonitors: pushMonitorFormatter.failedStaleMonitors, - }); + }; } catch (error) { - subject?.error(error); - } finally { - subject?.complete(); + server.logger.error(`Error adding monitors to project ${decodedProjectName}`); + throw error; } }, }); + +export const REQUEST_TOO_LARGE = i18n.translate('xpack.synthetics.server.project.delete.toolarge', { + defaultMessage: + 'Delete request payload is too large. Please send a max of 250 monitors to delete per request', +}); diff --git a/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor_project_legacy.ts b/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor_project_legacy.ts new file mode 100644 index 0000000000000..f8f29e46c1fad --- /dev/null +++ b/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor_project_legacy.ts @@ -0,0 +1,84 @@ +/* + * 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 { schema } from '@kbn/config-schema'; +import { UMServerLibs } from '../../legacy_uptime/lib/lib'; +import { ProjectMonitor } from '../../../common/runtime_types'; + +import { SyntheticsStreamingRouteFactory } from '../../legacy_uptime/routes/types'; +import { API_URLS } from '../../../common/constants'; +import { getAllLocations } from '../../synthetics_service/get_all_locations'; +import { ProjectMonitorFormatterLegacy } from '../../synthetics_service/project_monitor/project_monitor_formatter_legacy'; + +const MAX_PAYLOAD_SIZE = 1048576 * 20; // 20MiB + +export const addSyntheticsProjectMonitorRouteLegacy: SyntheticsStreamingRouteFactory = ( + libs: UMServerLibs +) => ({ + method: 'PUT', + path: API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY, + validate: { + body: schema.object({ + project: schema.string(), + keep_stale: schema.boolean(), + monitors: schema.arrayOf(schema.any()), + }), + }, + options: { + body: { + maxBytes: MAX_PAYLOAD_SIZE, + }, + }, + handler: async ({ + request, + savedObjectsClient, + server, + syntheticsMonitorClient, + subject, + }): Promise => { + try { + const monitors = (request.body?.monitors as ProjectMonitor[]) || []; + const spaceId = server.spaces.spacesService.getSpaceId(request); + const { keep_stale: keepStale, project: projectId } = request.body || {}; + const { publicLocations, privateLocations } = await getAllLocations( + server, + syntheticsMonitorClient, + savedObjectsClient + ); + const encryptedSavedObjectsClient = server.encryptedSavedObjects.getClient(); + + const pushMonitorFormatter = new ProjectMonitorFormatterLegacy({ + projectId, + spaceId, + keepStale, + locations: publicLocations, + privateLocations, + encryptedSavedObjectsClient, + savedObjectsClient, + monitors, + server, + syntheticsMonitorClient, + request, + subject, + }); + + await pushMonitorFormatter.configureAllProjectMonitors(); + + subject?.next({ + createdMonitors: pushMonitorFormatter.createdMonitors, + updatedMonitors: pushMonitorFormatter.updatedMonitors, + staleMonitors: pushMonitorFormatter.staleMonitors, + deletedMonitors: pushMonitorFormatter.deletedMonitors, + failedMonitors: pushMonitorFormatter.failedMonitors, + failedStaleMonitors: pushMonitorFormatter.failedStaleMonitors, + }); + } catch (error) { + subject?.error(error); + } finally { + subject?.complete(); + } + }, +}); diff --git a/x-pack/plugins/synthetics/server/routes/monitor_cruds/delete_monitor_project.ts b/x-pack/plugins/synthetics/server/routes/monitor_cruds/delete_monitor_project.ts index 3deb7a1be2170..67c937fb78a7b 100644 --- a/x-pack/plugins/synthetics/server/routes/monitor_cruds/delete_monitor_project.ts +++ b/x-pack/plugins/synthetics/server/routes/monitor_cruds/delete_monitor_project.ts @@ -16,7 +16,7 @@ import { deleteMonitorBulk } from './bulk_cruds/delete_monitor_bulk'; export const deleteSyntheticsMonitorProjectRoute: SyntheticsRestApiRouteFactory = () => ({ method: 'DELETE', - path: API_URLS.SYNTHETICS_MONITORS_PROJECT, + path: API_URLS.SYNTHETICS_MONITORS_PROJECT_DELETE, validate: { body: schema.object({ monitors: schema.arrayOf(schema.string()), diff --git a/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/project_monitor_formatter.test.ts b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/project_monitor_formatter.test.ts index 2566c6a358fba..28de75ed511d3 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/project_monitor_formatter.test.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/project_monitor_formatter.test.ts @@ -18,7 +18,6 @@ import { UptimeServerSetup } from '../../legacy_uptime/lib/adapters'; import { encryptedSavedObjectsMock } from '@kbn/encrypted-saved-objects-plugin/server/mocks'; import { SyntheticsMonitorClient } from '../synthetics_monitor/synthetics_monitor_client'; import { httpServerMock } from '@kbn/core-http-server-mocks'; -import { Subject } from 'rxjs'; import { formatSecrets } from '../utils'; import * as telemetryHooks from '../../routes/telemetry/monitor_upgrade_sender'; @@ -141,14 +140,9 @@ describe('ProjectMonitorFormatter', () => { const monitorClient = new SyntheticsMonitorClient(syntheticsService, serverMock); it('should return errors', async () => { - const testSubject = new Subject(); - - testSubject.next = jest.fn(); - const pushMonitorFormatter = new ProjectMonitorFormatter({ projectId: 'test-project', spaceId: 'default-space', - keepStale: false, locations, privateLocations, encryptedSavedObjectsClient, @@ -157,32 +151,18 @@ describe('ProjectMonitorFormatter', () => { server: serverMock, syntheticsMonitorClient: monitorClient, request: kibanaRequest, - subject: testSubject, }); pushMonitorFormatter.getProjectMonitorsForProject = jest.fn().mockResolvedValue([]); await pushMonitorFormatter.configureAllProjectMonitors(); - expect(testSubject.next).toHaveBeenNthCalledWith( - 1, - 'check if title is present 10 0: failed to create or update monitor' - ); - expect(testSubject.next).toHaveBeenNthCalledWith( - 2, - 'check if title is present 10 1: failed to create or update monitor' - ); - expect({ createdMonitors: pushMonitorFormatter.createdMonitors, updatedMonitors: pushMonitorFormatter.updatedMonitors, - staleMonitors: pushMonitorFormatter.staleMonitors, - deletedMonitors: pushMonitorFormatter.deletedMonitors, failedMonitors: pushMonitorFormatter.failedMonitors, - failedStaleMonitors: pushMonitorFormatter.failedStaleMonitors, }).toStrictEqual({ createdMonitors: [], - deletedMonitors: [], failedMonitors: [ { details: "Cannot read properties of undefined (reading 'authz')", @@ -197,15 +177,11 @@ describe('ProjectMonitorFormatter', () => { reason: 'Failed to create or update monitor', }, ], - failedStaleMonitors: [], - staleMonitors: [], updatedMonitors: [], }); }); it('throws fleet permission error', async () => { - const testSubject = new Subject(); - serverMock.fleet = { authz: { fromRequest: jest @@ -217,7 +193,6 @@ describe('ProjectMonitorFormatter', () => { const pushMonitorFormatter = new ProjectMonitorFormatter({ projectId: 'test-project', spaceId: 'default-space', - keepStale: false, locations, privateLocations, encryptedSavedObjectsClient, @@ -226,7 +201,6 @@ describe('ProjectMonitorFormatter', () => { server: serverMock, syntheticsMonitorClient: monitorClient, request: kibanaRequest, - subject: testSubject, }); pushMonitorFormatter.getProjectMonitorsForProject = jest.fn().mockResolvedValue([]); @@ -236,13 +210,9 @@ describe('ProjectMonitorFormatter', () => { expect({ createdMonitors: pushMonitorFormatter.createdMonitors, updatedMonitors: pushMonitorFormatter.updatedMonitors, - staleMonitors: pushMonitorFormatter.staleMonitors, - deletedMonitors: pushMonitorFormatter.deletedMonitors, failedMonitors: pushMonitorFormatter.failedMonitors, - failedStaleMonitors: pushMonitorFormatter.failedStaleMonitors, }).toStrictEqual({ createdMonitors: [], - deletedMonitors: [], failedMonitors: [ { details: INSUFFICIENT_FLEET_PERMISSIONS, @@ -257,15 +227,11 @@ describe('ProjectMonitorFormatter', () => { reason: 'Failed to create or update monitor', }, ], - failedStaleMonitors: [], - staleMonitors: [], updatedMonitors: [], }); }); it('catches errors from bulk edit method', async () => { - const testSubject = new Subject(); - serverMock.fleet = { authz: { fromRequest: jest @@ -277,7 +243,6 @@ describe('ProjectMonitorFormatter', () => { const pushMonitorFormatter = new ProjectMonitorFormatter({ projectId: 'test-project', spaceId: 'default-space', - keepStale: false, locations, privateLocations, encryptedSavedObjectsClient, @@ -286,7 +251,6 @@ describe('ProjectMonitorFormatter', () => { server: serverMock, syntheticsMonitorClient: monitorClient, request: kibanaRequest, - subject: testSubject, }); pushMonitorFormatter.getProjectMonitorsForProject = jest.fn().mockResolvedValue([]); @@ -296,15 +260,10 @@ describe('ProjectMonitorFormatter', () => { expect({ createdMonitors: pushMonitorFormatter.createdMonitors, updatedMonitors: pushMonitorFormatter.updatedMonitors, - staleMonitors: pushMonitorFormatter.staleMonitors, - deletedMonitors: pushMonitorFormatter.deletedMonitors, failedMonitors: pushMonitorFormatter.failedMonitors, - failedStaleMonitors: pushMonitorFormatter.failedStaleMonitors, }).toEqual({ createdMonitors: [], updatedMonitors: [], - staleMonitors: [], - deletedMonitors: [], failedMonitors: [ { details: "Cannot read properties of undefined (reading 'buildPackagePolicyFromPackage')", @@ -312,13 +271,10 @@ describe('ProjectMonitorFormatter', () => { reason: 'Failed to create 2 monitors', }, ], - failedStaleMonitors: [], }); }); it('configures project monitors when there are errors', async () => { - const testSubject = new Subject(); - serverMock.fleet = { authz: { fromRequest: jest @@ -332,7 +288,6 @@ describe('ProjectMonitorFormatter', () => { const pushMonitorFormatter = new ProjectMonitorFormatter({ projectId: 'test-project', spaceId: 'default-space', - keepStale: false, locations, privateLocations, encryptedSavedObjectsClient, @@ -341,7 +296,6 @@ describe('ProjectMonitorFormatter', () => { server: serverMock, syntheticsMonitorClient: monitorClient, request: kibanaRequest, - subject: testSubject, }); pushMonitorFormatter.getProjectMonitorsForProject = jest.fn().mockResolvedValue([]); @@ -351,15 +305,10 @@ describe('ProjectMonitorFormatter', () => { expect({ createdMonitors: pushMonitorFormatter.createdMonitors, updatedMonitors: pushMonitorFormatter.updatedMonitors, - staleMonitors: pushMonitorFormatter.staleMonitors, - deletedMonitors: pushMonitorFormatter.deletedMonitors, failedMonitors: pushMonitorFormatter.failedMonitors, - failedStaleMonitors: pushMonitorFormatter.failedStaleMonitors, }).toEqual({ createdMonitors: [], updatedMonitors: [], - staleMonitors: [], - deletedMonitors: [], failedMonitors: [ { details: "Cannot read properties of undefined (reading 'buildPackagePolicyFromPackage')", @@ -367,13 +316,10 @@ describe('ProjectMonitorFormatter', () => { reason: 'Failed to create 2 monitors', }, ], - failedStaleMonitors: [], }); }); it('shows errors thrown by fleet api', async () => { - const testSubject = new Subject(); - serverMock.fleet = { authz: { fromRequest: jest @@ -388,7 +334,6 @@ describe('ProjectMonitorFormatter', () => { const pushMonitorFormatter = new ProjectMonitorFormatter({ projectId: 'test-project', spaceId: 'default-space', - keepStale: false, locations, privateLocations, encryptedSavedObjectsClient, @@ -397,7 +342,6 @@ describe('ProjectMonitorFormatter', () => { server: serverMock, syntheticsMonitorClient: monitorClient, request: kibanaRequest, - subject: testSubject, }); pushMonitorFormatter.getProjectMonitorsForProject = jest.fn().mockResolvedValue([]); @@ -407,15 +351,10 @@ describe('ProjectMonitorFormatter', () => { expect({ createdMonitors: pushMonitorFormatter.createdMonitors, updatedMonitors: pushMonitorFormatter.updatedMonitors, - staleMonitors: pushMonitorFormatter.staleMonitors, - deletedMonitors: pushMonitorFormatter.deletedMonitors, failedMonitors: pushMonitorFormatter.failedMonitors, - failedStaleMonitors: pushMonitorFormatter.failedStaleMonitors, }).toEqual({ createdMonitors: [], updatedMonitors: [], - staleMonitors: [], - deletedMonitors: [], failedMonitors: [ { details: @@ -424,13 +363,10 @@ describe('ProjectMonitorFormatter', () => { payload: payloadData, }, ], - failedStaleMonitors: [], }); }); it('creates project monitors when no errors', async () => { - const testSubject = new Subject(); - serverMock.fleet = { authz: { fromRequest: jest @@ -450,7 +386,6 @@ describe('ProjectMonitorFormatter', () => { const pushMonitorFormatter = new ProjectMonitorFormatter({ projectId: 'test-project', spaceId: 'default-space', - keepStale: false, locations, privateLocations, encryptedSavedObjectsClient, @@ -459,7 +394,6 @@ describe('ProjectMonitorFormatter', () => { server: serverMock, syntheticsMonitorClient: monitorClient, request: kibanaRequest, - subject: testSubject, }); pushMonitorFormatter.getProjectMonitorsForProject = jest.fn().mockResolvedValue([]); @@ -492,17 +426,11 @@ describe('ProjectMonitorFormatter', () => { expect({ createdMonitors: pushMonitorFormatter.createdMonitors, updatedMonitors: pushMonitorFormatter.updatedMonitors, - staleMonitors: pushMonitorFormatter.staleMonitors, - deletedMonitors: pushMonitorFormatter.deletedMonitors, failedMonitors: pushMonitorFormatter.failedMonitors, - failedStaleMonitors: pushMonitorFormatter.failedStaleMonitors, }).toEqual({ createdMonitors: ['check if title is present 10 0', 'check if title is present 10 1'], updatedMonitors: [], - staleMonitors: [], - deletedMonitors: [], failedMonitors: [], - failedStaleMonitors: [], }); }); }); diff --git a/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/project_monitor_formatter.ts b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/project_monitor_formatter.ts index a430d25bcb407..35e85fe5cd03d 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/project_monitor_formatter.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/project_monitor_formatter.ts @@ -4,10 +4,8 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import type { Subject } from 'rxjs'; -import { isEqual, omit } from 'lodash'; -import pMap from 'p-map'; import { KibanaRequest } from '@kbn/core/server'; +import pMap from 'p-map'; import { SavedObjectsUpdateResponse, SavedObjectsClientContract, @@ -16,7 +14,6 @@ import { import { i18n } from '@kbn/i18n'; import { EncryptedSavedObjectsClient } from '@kbn/encrypted-saved-objects-plugin/server'; import { syncNewMonitorBulk } from '../../routes/monitor_cruds/bulk_cruds/add_monitor_bulk'; -import { deleteMonitorBulk } from '../../routes/monitor_cruds/bulk_cruds/delete_monitor_bulk'; import { SyntheticsMonitorClient } from '../synthetics_monitor/synthetics_monitor_client'; import { syncEditedMonitorBulk } from '../../routes/monitor_cruds/bulk_cruds/edit_monitor_bulk'; import { @@ -40,12 +37,6 @@ import { } from '../../routes/monitor_cruds/monitor_validation'; import { normalizeProjectMonitor } from './normalizers'; -interface StaleMonitor { - stale: boolean; - journeyId: string; - savedObjectId: string; -} -type StaleMonitorMap = Record; type FailedError = Array<{ id?: string; reason: string; details: string; payload?: object }>; export const INSUFFICIENT_FLEET_PERMISSIONS = i18n.translate( @@ -56,34 +47,48 @@ export const INSUFFICIENT_FLEET_PERMISSIONS = i18n.translate( } ); +export const CANNOT_UPDATE_MONITOR_TO_DIFFERENT_TYPE = i18n.translate( + 'xpack.synthetics.service.projectMonitors.cannotUpdateMonitorToDifferentType', + { + defaultMessage: 'Cannot update monitor to different type.', + } +); + +export const FAILED_TO_UPDATE_MONITOR = i18n.translate( + 'xpack.synthetics.service.projectMonitors.failedToUpdateMonitor', + { + defaultMessage: 'Failed to create or update monitor', + } +); + +export const FAILED_TO_UPDATE_MONITORS = i18n.translate( + 'xpack.synthetics.service.projectMonitors.failedToUpdateMonitors', + { + defaultMessage: 'Failed to create or update monitors', + } +); + export class ProjectMonitorFormatter { private projectId: string; private spaceId: string; - private keepStale: boolean; private locations: Locations; private privateLocations: PrivateLocation[]; private savedObjectsClient: SavedObjectsClientContract; private encryptedSavedObjectsClient: EncryptedSavedObjectsClient; - private staleMonitorsMap: StaleMonitorMap = {}; private monitors: ProjectMonitor[] = []; public createdMonitors: string[] = []; - public deletedMonitors: string[] = []; public updatedMonitors: string[] = []; - public staleMonitors: string[] = []; public failedMonitors: FailedError = []; - public failedStaleMonitors: FailedError = []; private server: UptimeServerSetup; private projectFilter: string; private syntheticsMonitorClient: SyntheticsMonitorClient; private request: KibanaRequest; - private subject?: Subject; private writeIntegrationPoliciesPermissions?: boolean; constructor({ locations, privateLocations, - keepStale, savedObjectsClient, encryptedSavedObjectsClient, projectId, @@ -92,11 +97,9 @@ export class ProjectMonitorFormatter { server, syntheticsMonitorClient, request, - subject, }: { locations: Locations; privateLocations: PrivateLocation[]; - keepStale: boolean; savedObjectsClient: SavedObjectsClientContract; encryptedSavedObjectsClient: EncryptedSavedObjectsClient; projectId: string; @@ -105,13 +108,11 @@ export class ProjectMonitorFormatter { server: UptimeServerSetup; syntheticsMonitorClient: SyntheticsMonitorClient; request: KibanaRequest; - subject?: Subject; }) { this.projectId = projectId; this.spaceId = spaceId; this.locations = locations; this.privateLocations = privateLocations; - this.keepStale = keepStale; this.savedObjectsClient = savedObjectsClient; this.encryptedSavedObjectsClient = encryptedSavedObjectsClient; this.syntheticsMonitorClient = syntheticsMonitorClient; @@ -119,12 +120,10 @@ export class ProjectMonitorFormatter { this.server = server; this.projectFilter = `${syntheticsMonitorType}.attributes.${ConfigKey.PROJECT_ID}: "${this.projectId}"`; this.request = request; - this.subject = subject; } public configureAllProjectMonitors = async () => { const existingMonitors = await this.getProjectMonitorsForProject(); - this.staleMonitorsMap = await this.getStaleMonitorsMap(existingMonitors); const normalizedNewMonitors: SyntheticsMonitor[] = []; const normalizedUpdateMonitors: Array<{ @@ -142,11 +141,29 @@ export class ProjectMonitorFormatter { monitor, }); if (normM) { - if (previousMonitor) { + if ( + previousMonitor && + previousMonitor.attributes[ConfigKey.MONITOR_TYPE] !== normM[ConfigKey.MONITOR_TYPE] + ) { + this.failedMonitors.push({ + reason: CANNOT_UPDATE_MONITOR_TO_DIFFERENT_TYPE, + details: i18n.translate( + 'xpack.synthetics.service.projectMonitors.cannotUpdateMonitorToDifferentTypeDetails', + { + defaultMessage: + 'Monitor {monitorId} of type {previousType} cannot be updated to type {currentType}. Please delete the monitor first and try again.', + values: { + currentType: monitor.type, + previousType: previousMonitor.attributes[ConfigKey.MONITOR_TYPE], + monitorId: monitor.id, + }, + } + ), + payload: monitor, + }); + continue; + } else if (previousMonitor) { this.updatedMonitors.push(monitor.id); - if (this.staleMonitorsMap[monitor.id]) { - this.staleMonitorsMap[monitor.id].stale = false; - } normalizedUpdateMonitors.push({ monitor: normM as MonitorFields, previousMonitor }); } else { normalizedNewMonitors.push(normM as MonitorFields); @@ -156,28 +173,7 @@ export class ProjectMonitorFormatter { await this.createMonitorsBulk(normalizedNewMonitors); - const { updatedCount } = await this.updateMonitorsBulk(normalizedUpdateMonitors); - - if (normalizedUpdateMonitors.length > 0) { - let updateMessage = ''; - if (updatedCount > 0) { - updateMessage = `${updatedCount} monitor${ - updatedCount > 1 ? 's' : '' - } updated successfully.`; - } - - const noChanges = normalizedUpdateMonitors.length - updatedCount; - let noChangeMessage = ''; - if (noChanges > 0) { - noChangeMessage = `${noChanges} monitor${noChanges > 1 ? 's' : ''} found with no changes.`; - } - - this.handleStreamingMessage({ - message: `${updateMessage} ${noChangeMessage}`, - }); - } - - await this.handleStaleMonitors(); + await this.updateMonitorsBulk(normalizedUpdateMonitors); }; validatePermissions = async ({ monitor }: { monitor: ProjectMonitor }) => { @@ -210,9 +206,6 @@ export class ProjectMonitorFormatter { if (errors.length) { this.failedMonitors.push(...errors); - this.handleStreamingMessage({ - message: `${monitor.id}: failed to create or update monitor`, - }); return null; } @@ -244,36 +237,13 @@ export class ProjectMonitorFormatter { this.server.logger.error(e); this.failedMonitors.push({ id: monitor.id, - reason: 'Failed to create or update monitor', + reason: FAILED_TO_UPDATE_MONITOR, details: e.message, payload: monitor, }); - this.handleStreamingMessage({ message: `${monitor.id}: failed to create or update monitor` }); - if (this.staleMonitorsMap[monitor.id]) { - this.staleMonitorsMap[monitor.id].stale = false; - } } }; - private getStaleMonitorsMap = async ( - existingMonitors: Array> - ): Promise => { - const staleMonitors: StaleMonitorMap = {}; - - existingMonitors.forEach((savedObject) => { - const journeyId = (savedObject.attributes as SyntheticsMonitor)[ConfigKey.JOURNEY_ID]; - if (journeyId) { - staleMonitors[journeyId] = { - stale: true, - savedObjectId: savedObject.id, - journeyId, - }; - } - }); - - return staleMonitors; - }; - public getProjectMonitorsForProject = async () => { const finder = this.savedObjectsClient.createPointInTimeFinder({ type: syntheticsMonitorType, @@ -308,32 +278,34 @@ export class ProjectMonitorFormatter { if (newMonitors && newMonitors.length === monitors.length) { this.createdMonitors.push(...monitors.map((monitor) => monitor[ConfigKey.JOURNEY_ID]!)); - this.handleStreamingMessage({ - message: `${monitors.length} monitor${ - monitors.length > 1 ? 's' : '' - } created successfully.`, - }); } else { this.failedMonitors.push({ - reason: `Failed to create ${monitors.length} monitors`, - details: 'Failed to create monitors', + reason: i18n.translate( + 'xpack.synthetics.service.projectMonitors.failedToCreateXMonitors', + { + defaultMessage: 'Failed to create {length} monitors', + values: { + length: monitors.length, + }, + } + ), + details: FAILED_TO_UPDATE_MONITORS, payload: monitors, }); - this.handleStreamingMessage({ - message: `Failed to create ${monitors.length} monitors`, - }); } } } catch (e) { this.server.logger.error(e); this.failedMonitors.push({ - reason: `Failed to create ${monitors.length} monitors`, + reason: i18n.translate('xpack.synthetics.service.projectMonitors.failedToCreateXMonitors', { + defaultMessage: 'Failed to create {length} monitors', + values: { + length: monitors.length, + }, + }), details: e.message, payload: monitors, }); - this.handleStreamingMessage({ - message: `Failed to create ${monitors.length} monitors`, - }); } }; @@ -375,27 +347,21 @@ export class ProjectMonitorFormatter { const previousMonitor = monitors[i].previousMonitor; const normalizedMonitor = monitors[i].monitor; - const keysToOmit = [ConfigKey.REVISION, ConfigKey.MONITOR_QUERY_ID, ConfigKey.CONFIG_ID]; - const { attributes: normalizedPreviousMonitorAttributes } = - normalizeSecrets(decryptedPreviousMonitor); - const hasMonitorBeenEdited = !isEqual( - omit(normalizedMonitor, keysToOmit), - omit(normalizedPreviousMonitorAttributes, keysToOmit) - ); + const { + attributes: { [ConfigKey.REVISION]: _, ...normalizedPreviousMonitorAttributes }, + } = normalizeSecrets(decryptedPreviousMonitor); - if (hasMonitorBeenEdited) { - const monitorWithRevision = formatSecrets({ - ...normalizedPreviousMonitorAttributes, - ...normalizedMonitor, - revision: (previousMonitor.attributes[ConfigKey.REVISION] || 0) + 1, - }); - monitorsToUpdate.push({ - normalizedMonitor, - previousMonitor, - monitorWithRevision, - decryptedPreviousMonitor, - }); - } + const monitorWithRevision = formatSecrets({ + ...normalizedPreviousMonitorAttributes, + ...normalizedMonitor, + revision: (previousMonitor.attributes[ConfigKey.REVISION] || 0) + 1, + }); + monitorsToUpdate.push({ + normalizedMonitor, + previousMonitor, + monitorWithRevision, + decryptedPreviousMonitor, + }); } const { editedMonitors } = await syncEditedMonitorBulk({ @@ -414,108 +380,6 @@ export class ProjectMonitorFormatter { }; }; - private handleStaleMonitors = async () => { - try { - const staleMonitorsList = Object.values(this.staleMonitorsMap).filter( - (monitor) => monitor.stale === true - ); - - const encryptedMonitors = await this.savedObjectsClient.bulkGet( - staleMonitorsList.map((staleMonitor) => ({ - id: staleMonitor.savedObjectId, - type: syntheticsMonitorType, - })) - ); - - let monitors = encryptedMonitors.saved_objects; - - const hasPrivateMonitor = monitors.some((monitor) => - monitor.attributes.locations.some((location) => !location.isServiceManaged) - ); - - if (hasPrivateMonitor) { - const { - integrations: { writeIntegrationPolicies }, - } = await this.server.fleet.authz.fromRequest(this.request); - if (!writeIntegrationPolicies) { - monitors = monitors.filter((monitor) => { - const hasPrivateLocation = monitor.attributes.locations.some( - (location) => !location.isServiceManaged - ); - if (hasPrivateLocation) { - const journeyId = (monitor.attributes as MonitorFields)[ConfigKey.JOURNEY_ID]!; - const monitorName = (monitor.attributes as MonitorFields)[ConfigKey.NAME]!; - this.handleStreamingMessage({ - message: `Monitor ${journeyId} could not be deleted`, - }); - this.failedStaleMonitors.push({ - id: journeyId, - reason: 'Failed to delete stale monitor', - details: `Unable to delete Synthetics package policy for monitor ${monitorName}. Fleet write permissions are needed to use Synthetics private locations.`, - }); - } - return !hasPrivateLocation; - }); - } - } - - const chunkSize = 100; - for (let i = 0; i < monitors.length; i += chunkSize) { - const chunkMonitors = monitors.slice(i, i + chunkSize); - try { - if (!this.keepStale) { - await deleteMonitorBulk({ - monitors: chunkMonitors, - savedObjectsClient: this.savedObjectsClient, - server: this.server, - syntheticsMonitorClient: this.syntheticsMonitorClient, - request: this.request, - }); - - for (const sm of chunkMonitors) { - const journeyId = (sm.attributes as MonitorFields)[ConfigKey.JOURNEY_ID]!; - - this.deletedMonitors.push(journeyId); - this.handleStreamingMessage({ - message: `Monitor ${journeyId} deleted successfully`, - }); - } - } else { - chunkMonitors.forEach((sm) => { - const journeyId = (sm.attributes as MonitorFields)[ConfigKey.JOURNEY_ID]!; - this.staleMonitors.push(journeyId); - }); - } - } catch (e) { - chunkMonitors.forEach((sm) => { - const journeyId = (sm.attributes as MonitorFields)[ConfigKey.JOURNEY_ID]!; - - this.handleStreamingMessage({ - message: `Monitor ${journeyId} could not be deleted`, - }); - this.failedStaleMonitors.push({ - id: journeyId, - reason: 'Failed to delete stale monitor', - details: e.message, - payload: staleMonitorsList.find( - (staleMonitor) => staleMonitor.savedObjectId === sm.id - ), - }); - }); - this.server.logger.error(e); - } - } - } catch (e) { - this.server.logger.error(e); - } - }; - - private handleStreamingMessage = ({ message }: { message: string }) => { - if (this.subject) { - this.subject?.next(message); - } - }; - private validateMonitor = ({ validationResult, monitorId, @@ -531,9 +395,6 @@ export class ProjectMonitorFormatter { details, payload: validationPayload, }); - if (this.staleMonitorsMap[monitorId]) { - this.staleMonitorsMap[monitorId].stale = false; - } } return validationResult; }; diff --git a/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/project_monitor_formatter_legacy.test.ts b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/project_monitor_formatter_legacy.test.ts new file mode 100644 index 0000000000000..14df60edfc4e2 --- /dev/null +++ b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/project_monitor_formatter_legacy.test.ts @@ -0,0 +1,653 @@ +/* + * 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 { loggerMock } from '@kbn/logging-mocks'; +import { savedObjectsClientMock } from '@kbn/core/server/mocks'; +import { + INSUFFICIENT_FLEET_PERMISSIONS, + ProjectMonitorFormatterLegacy, +} from './project_monitor_formatter_legacy'; +import { ConfigKey, DataStream, LocationStatus } from '../../../common/runtime_types'; +import { DEFAULT_FIELDS } from '../../../common/constants/monitor_defaults'; +import { times } from 'lodash'; +import { SyntheticsService } from '../synthetics_service'; +import { UptimeServerSetup } from '../../legacy_uptime/lib/adapters'; +import { encryptedSavedObjectsMock } from '@kbn/encrypted-saved-objects-plugin/server/mocks'; +import { SyntheticsMonitorClient } from '../synthetics_monitor/synthetics_monitor_client'; +import { httpServerMock } from '@kbn/core-http-server-mocks'; +import { Subject } from 'rxjs'; +import { formatSecrets } from '../utils'; + +import * as telemetryHooks from '../../routes/telemetry/monitor_upgrade_sender'; + +const testMonitors = [ + { + type: 'browser', + throttling: { download: 5, upload: 3, latency: 20 }, + schedule: 3, + locations: [], + privateLocations: ['Test private location'], + params: { url: 'http://localhost:8080' }, + playwrightOptions: { + userAgent: + 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1', + viewport: { width: 375, height: 667 }, + deviceScaleFactor: 2, + isMobile: true, + hasTouch: true, + headless: true, + }, + name: 'check if title is present 10 0', + id: 'check if title is present 10 0', + tags: [], + content: + 'UEsDBBQACAAIAAAAIQAAAAAAAAAAAAAAAAAQAAAAYmFzaWMuam91cm5leS50c2WQQU7DQAxF9znFV8QiUUOmXcCCUMQl2NdMnWbKJDMaO6Ilyt0JASQkNv9Z1teTZWNAIqwP5kU4iZGOug863u7uDXsSddbIddCOl0kMX6iPnsVoOAYxryTO1ucwpoGvtUrm+hiSYsLProIoxwp8iWwVM9oUeuTP/9V5k7UhofCscNhj2yx4xN2CzabElOHXWRxsx/YNroU69QwniImFB8Vui5vJzYcKxYRIJ66WTNQL5hL7p1WD9aYi9zQOtgPFGPNqecJ1sCj+tAB6J6erpj4FDcW3qh6TL5u1Mq/8yjn7BFBLBwhGDIWc4QAAAEkBAABQSwECLQMUAAgACAAAACEARgyFnOEAAABJAQAAEAAAAAAAAAAAACAApIEAAAAAYmFzaWMuam91cm5leS50c1BLBQYAAAAAAQABAD4AAAAfAQAAAAA=', + filter: { match: 'check if title is present 10 0' }, + hash: 'lleklrkelkj', + }, + { + type: 'browser', + throttling: { download: 5, upload: 3, latency: 20 }, + schedule: 3, + locations: [], + privateLocations: ['Test private location'], + params: { url: 'http://localhost:8080' }, + playwrightOptions: { + userAgent: + 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1', + viewport: { width: 375, height: 667 }, + deviceScaleFactor: 2, + isMobile: true, + hasTouch: true, + headless: true, + }, + name: 'check if title is present 10 1', + id: 'check if title is present 10 1', + tags: [], + content: + 'UEsDBBQACAAIAAAAIQAAAAAAAAAAAAAAAAAQAAAAYmFzaWMuam91cm5leS50c2WQQU7DQAxF9znFV8QiUUOmXcCCUMQl2NdMnWbKJDMaO6Ilyt0JASQkNv9Z1teTZWNAIqwP5kU4iZGOug863u7uDXsSddbIddCOl0kMX6iPnsVoOAYxryTO1ucwpoGvtUrm+hiSYsLProIoxwp8iWwVM9oUeuTP/9V5k7UhofCscNhj2yx4xN2CzabElOHXWRxsx/YNroU69QwniImFB8Vui5vJzYcKxYRIJ66WTNQL5hL7p1WD9aYi9zQOtgPFGPNqecJ1sCj+tAB6J6erpj4FDcW3qh6TL5u1Mq/8yjn7BFBLBwhGDIWc4QAAAEkBAABQSwECLQMUAAgACAAAACEARgyFnOEAAABJAQAAEAAAAAAAAAAAACAApIEAAAAAYmFzaWMuam91cm5leS50c1BLBQYAAAAAAQABAD4AAAAfAQAAAAA=', + filter: { match: 'check if title is present 10 1' }, + hash: 'lleklrkelkj', + }, +]; + +const privateLocations = times(1).map((n) => { + return { + id: `loc-${n}`, + label: 'Test private location', + geo: { + lat: 0, + lon: 0, + }, + isServiceManaged: false, + agentPolicyId: `loc-${n}`, + concurrentMonitors: 1, + }; +}); + +describe('ProjectMonitorFormatterLegacy', () => { + const mockEsClient = { + search: jest.fn(), + }; + const logger = loggerMock.create(); + + const kibanaRequest = httpServerMock.createKibanaRequest(); + + const soClient = savedObjectsClientMock.create(); + + const serverMock: UptimeServerSetup = { + logger, + uptimeEsClient: mockEsClient, + authSavedObjectsClient: soClient, + config: { + service: { + username: 'dev', + password: '12345', + manifestUrl: 'http://localhost:8080/api/manifest', + }, + }, + spaces: { + spacesService: { + getSpaceId: jest.fn().mockReturnValue('test-space'), + }, + }, + } as unknown as UptimeServerSetup; + + const syntheticsService = new SyntheticsService(serverMock); + + syntheticsService.addConfig = jest.fn(); + syntheticsService.editConfig = jest.fn(); + syntheticsService.deleteConfigs = jest.fn(); + + const encryptedSavedObjectsClient = encryptedSavedObjectsMock.createStart().getClient(); + + const locations = times(3).map((n) => { + return { + id: `loc-${n}`, + label: `Location ${n}`, + url: `https://example.com/${n}`, + geo: { + lat: 0, + lon: 0, + }, + isServiceManaged: true, + status: LocationStatus.GA, + }; + }); + + const monitorClient = new SyntheticsMonitorClient(syntheticsService, serverMock); + + it('should return errors', async () => { + const testSubject = new Subject(); + + testSubject.next = jest.fn(); + + const pushMonitorFormatter = new ProjectMonitorFormatterLegacy({ + projectId: 'test-project', + spaceId: 'default-space', + keepStale: false, + locations, + privateLocations, + encryptedSavedObjectsClient, + savedObjectsClient: soClient, + monitors: testMonitors, + server: serverMock, + syntheticsMonitorClient: monitorClient, + request: kibanaRequest, + subject: testSubject, + }); + + pushMonitorFormatter.getProjectMonitorsForProject = jest.fn().mockResolvedValue([]); + + await pushMonitorFormatter.configureAllProjectMonitors(); + + expect(testSubject.next).toHaveBeenNthCalledWith( + 1, + 'check if title is present 10 0: failed to create or update monitor' + ); + expect(testSubject.next).toHaveBeenNthCalledWith( + 2, + 'check if title is present 10 1: failed to create or update monitor' + ); + + expect({ + createdMonitors: pushMonitorFormatter.createdMonitors, + updatedMonitors: pushMonitorFormatter.updatedMonitors, + staleMonitors: pushMonitorFormatter.staleMonitors, + deletedMonitors: pushMonitorFormatter.deletedMonitors, + failedMonitors: pushMonitorFormatter.failedMonitors, + failedStaleMonitors: pushMonitorFormatter.failedStaleMonitors, + }).toStrictEqual({ + createdMonitors: [], + deletedMonitors: [], + failedMonitors: [ + { + details: "Cannot read properties of undefined (reading 'authz')", + id: 'check if title is present 10 0', + payload: testMonitors[0], + reason: 'Failed to create or update monitor', + }, + { + details: "Cannot read properties of undefined (reading 'authz')", + id: 'check if title is present 10 1', + payload: testMonitors[1], + reason: 'Failed to create or update monitor', + }, + ], + failedStaleMonitors: [], + staleMonitors: [], + updatedMonitors: [], + }); + }); + + it('throws fleet permission error', async () => { + const testSubject = new Subject(); + + serverMock.fleet = { + authz: { + fromRequest: jest + .fn() + .mockResolvedValue({ integrations: { writeIntegrationPolicies: false } }), + }, + } as any; + + const pushMonitorFormatter = new ProjectMonitorFormatterLegacy({ + projectId: 'test-project', + spaceId: 'default-space', + keepStale: false, + locations, + privateLocations, + encryptedSavedObjectsClient, + savedObjectsClient: soClient, + monitors: testMonitors, + server: serverMock, + syntheticsMonitorClient: monitorClient, + request: kibanaRequest, + subject: testSubject, + }); + + pushMonitorFormatter.getProjectMonitorsForProject = jest.fn().mockResolvedValue([]); + + await pushMonitorFormatter.configureAllProjectMonitors(); + + expect({ + createdMonitors: pushMonitorFormatter.createdMonitors, + updatedMonitors: pushMonitorFormatter.updatedMonitors, + staleMonitors: pushMonitorFormatter.staleMonitors, + deletedMonitors: pushMonitorFormatter.deletedMonitors, + failedMonitors: pushMonitorFormatter.failedMonitors, + failedStaleMonitors: pushMonitorFormatter.failedStaleMonitors, + }).toStrictEqual({ + createdMonitors: [], + deletedMonitors: [], + failedMonitors: [ + { + details: INSUFFICIENT_FLEET_PERMISSIONS, + id: 'check if title is present 10 0', + payload: testMonitors[0], + reason: 'Failed to create or update monitor', + }, + { + details: INSUFFICIENT_FLEET_PERMISSIONS, + id: 'check if title is present 10 1', + payload: testMonitors[1], + reason: 'Failed to create or update monitor', + }, + ], + failedStaleMonitors: [], + staleMonitors: [], + updatedMonitors: [], + }); + }); + + it('catches errors from bulk edit method', async () => { + const testSubject = new Subject(); + + serverMock.fleet = { + authz: { + fromRequest: jest + .fn() + .mockResolvedValue({ integrations: { writeIntegrationPolicies: true } }), + }, + } as any; + + const pushMonitorFormatter = new ProjectMonitorFormatterLegacy({ + projectId: 'test-project', + spaceId: 'default-space', + keepStale: false, + locations, + privateLocations, + encryptedSavedObjectsClient, + savedObjectsClient: soClient, + monitors: testMonitors, + server: serverMock, + syntheticsMonitorClient: monitorClient, + request: kibanaRequest, + subject: testSubject, + }); + + pushMonitorFormatter.getProjectMonitorsForProject = jest.fn().mockResolvedValue([]); + + await pushMonitorFormatter.configureAllProjectMonitors(); + + expect({ + createdMonitors: pushMonitorFormatter.createdMonitors, + updatedMonitors: pushMonitorFormatter.updatedMonitors, + staleMonitors: pushMonitorFormatter.staleMonitors, + deletedMonitors: pushMonitorFormatter.deletedMonitors, + failedMonitors: pushMonitorFormatter.failedMonitors, + failedStaleMonitors: pushMonitorFormatter.failedStaleMonitors, + }).toEqual({ + createdMonitors: [], + updatedMonitors: [], + staleMonitors: [], + deletedMonitors: [], + failedMonitors: [ + { + details: "Cannot read properties of undefined (reading 'buildPackagePolicyFromPackage')", + payload: payloadData, + reason: 'Failed to create 2 monitors', + }, + ], + failedStaleMonitors: [], + }); + }); + + it('configures project monitors when there are errors', async () => { + const testSubject = new Subject(); + + serverMock.fleet = { + authz: { + fromRequest: jest + .fn() + .mockResolvedValue({ integrations: { writeIntegrationPolicies: true } }), + }, + } as any; + + soClient.bulkCreate = jest.fn().mockResolvedValue({ saved_objects: [] }); + + const pushMonitorFormatter = new ProjectMonitorFormatterLegacy({ + projectId: 'test-project', + spaceId: 'default-space', + keepStale: false, + locations, + privateLocations, + encryptedSavedObjectsClient, + savedObjectsClient: soClient, + monitors: testMonitors, + server: serverMock, + syntheticsMonitorClient: monitorClient, + request: kibanaRequest, + subject: testSubject, + }); + + pushMonitorFormatter.getProjectMonitorsForProject = jest.fn().mockResolvedValue([]); + + await pushMonitorFormatter.configureAllProjectMonitors(); + + expect({ + createdMonitors: pushMonitorFormatter.createdMonitors, + updatedMonitors: pushMonitorFormatter.updatedMonitors, + staleMonitors: pushMonitorFormatter.staleMonitors, + deletedMonitors: pushMonitorFormatter.deletedMonitors, + failedMonitors: pushMonitorFormatter.failedMonitors, + failedStaleMonitors: pushMonitorFormatter.failedStaleMonitors, + }).toEqual({ + createdMonitors: [], + updatedMonitors: [], + staleMonitors: [], + deletedMonitors: [], + failedMonitors: [ + { + details: "Cannot read properties of undefined (reading 'buildPackagePolicyFromPackage')", + payload: payloadData, + reason: 'Failed to create 2 monitors', + }, + ], + failedStaleMonitors: [], + }); + }); + + it('shows errors thrown by fleet api', async () => { + const testSubject = new Subject(); + + serverMock.fleet = { + authz: { + fromRequest: jest + .fn() + .mockResolvedValue({ integrations: { writeIntegrationPolicies: true } }), + }, + packagePolicyService: {}, + } as any; + + soClient.bulkCreate = jest.fn().mockResolvedValue({ saved_objects: soResult }); + + const pushMonitorFormatter = new ProjectMonitorFormatterLegacy({ + projectId: 'test-project', + spaceId: 'default-space', + keepStale: false, + locations, + privateLocations, + encryptedSavedObjectsClient, + savedObjectsClient: soClient, + monitors: testMonitors, + server: serverMock, + syntheticsMonitorClient: monitorClient, + request: kibanaRequest, + subject: testSubject, + }); + + pushMonitorFormatter.getProjectMonitorsForProject = jest.fn().mockResolvedValue([]); + + await pushMonitorFormatter.configureAllProjectMonitors(); + + expect({ + createdMonitors: pushMonitorFormatter.createdMonitors, + updatedMonitors: pushMonitorFormatter.updatedMonitors, + staleMonitors: pushMonitorFormatter.staleMonitors, + deletedMonitors: pushMonitorFormatter.deletedMonitors, + failedMonitors: pushMonitorFormatter.failedMonitors, + failedStaleMonitors: pushMonitorFormatter.failedStaleMonitors, + }).toEqual({ + createdMonitors: [], + updatedMonitors: [], + staleMonitors: [], + deletedMonitors: [], + failedMonitors: [ + { + details: + 'this.server.fleet.packagePolicyService.buildPackagePolicyFromPackage is not a function', + reason: 'Failed to create 2 monitors', + payload: payloadData, + }, + ], + failedStaleMonitors: [], + }); + }); + + it('creates project monitors when no errors', async () => { + const testSubject = new Subject(); + + serverMock.fleet = { + authz: { + fromRequest: jest + .fn() + .mockResolvedValue({ integrations: { writeIntegrationPolicies: true } }), + }, + } as any; + + soClient.bulkCreate = jest.fn().mockResolvedValue({ saved_objects: soResult }); + + monitorClient.addMonitors = jest.fn().mockReturnValue({}); + + const telemetrySpy = jest + .spyOn(telemetryHooks, 'sendTelemetryEvents') + .mockImplementation(jest.fn()); + + const pushMonitorFormatter = new ProjectMonitorFormatterLegacy({ + projectId: 'test-project', + spaceId: 'default-space', + keepStale: false, + locations, + privateLocations, + encryptedSavedObjectsClient, + savedObjectsClient: soClient, + monitors: testMonitors, + server: serverMock, + syntheticsMonitorClient: monitorClient, + request: kibanaRequest, + subject: testSubject, + }); + + pushMonitorFormatter.getProjectMonitorsForProject = jest.fn().mockResolvedValue([]); + + await pushMonitorFormatter.configureAllProjectMonitors(); + + expect(soClient.bulkCreate).toHaveBeenCalledWith( + expect.arrayContaining([ + expect.objectContaining({ + ...soData[0], + attributes: { + ...soData[0].attributes, + [ConfigKey.MONITOR_QUERY_ID]: expect.any(String), + [ConfigKey.CONFIG_ID]: expect.any(String), + }, + }), + expect.objectContaining({ + ...soData[1], + attributes: { + ...soData[1].attributes, + [ConfigKey.MONITOR_QUERY_ID]: expect.any(String), + [ConfigKey.CONFIG_ID]: expect.any(String), + }, + }), + ]) + ); + + expect(telemetrySpy).toHaveBeenCalledTimes(2); + + expect({ + createdMonitors: pushMonitorFormatter.createdMonitors, + updatedMonitors: pushMonitorFormatter.updatedMonitors, + staleMonitors: pushMonitorFormatter.staleMonitors, + deletedMonitors: pushMonitorFormatter.deletedMonitors, + failedMonitors: pushMonitorFormatter.failedMonitors, + failedStaleMonitors: pushMonitorFormatter.failedStaleMonitors, + }).toEqual({ + createdMonitors: ['check if title is present 10 0', 'check if title is present 10 1'], + updatedMonitors: [], + staleMonitors: [], + deletedMonitors: [], + failedMonitors: [], + failedStaleMonitors: [], + }); + }); +}); + +const payloadData = [ + { + ...DEFAULT_FIELDS[DataStream.BROWSER], + __ui: { + is_zip_url_tls_enabled: false, + script_source: { + file_name: '', + is_generated_script: false, + }, + }, + config_id: '', + custom_heartbeat_id: 'check if title is present 10 0-test-project-default-space', + enabled: true, + 'filter_journeys.match': 'check if title is present 10 0', + 'filter_journeys.tags': [], + form_monitor_type: 'multistep', + ignore_https_errors: false, + journey_id: 'check if title is present 10 0', + locations: privateLocations, + name: 'check if title is present 10 0', + namespace: 'default_space', + origin: 'project', + original_space: 'default-space', + params: '{"url":"http://localhost:8080"}', + playwright_options: + '{"userAgent":"Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1","viewport":{"width":375,"height":667},"deviceScaleFactor":2,"isMobile":true,"hasTouch":true,"headless":true}', + playwright_text_assertion: '', + project_id: 'test-project', + schedule: { + number: '3', + unit: 'm', + }, + screenshots: 'on', + 'service.name': '', + 'source.inline.script': '', + 'source.project.content': + 'UEsDBBQACAAIAAAAIQAAAAAAAAAAAAAAAAAQAAAAYmFzaWMuam91cm5leS50c2WQQU7DQAxF9znFV8QiUUOmXcCCUMQl2NdMnWbKJDMaO6Ilyt0JASQkNv9Z1teTZWNAIqwP5kU4iZGOug863u7uDXsSddbIddCOl0kMX6iPnsVoOAYxryTO1ucwpoGvtUrm+hiSYsLProIoxwp8iWwVM9oUeuTP/9V5k7UhofCscNhj2yx4xN2CzabElOHXWRxsx/YNroU69QwniImFB8Vui5vJzYcKxYRIJ66WTNQL5hL7p1WD9aYi9zQOtgPFGPNqecJ1sCj+tAB6J6erpj4FDcW3qh6TL5u1Mq/8yjn7BFBLBwhGDIWc4QAAAEkBAABQSwECLQMUAAgACAAAACEARgyFnOEAAABJAQAAEAAAAAAAAAAAACAApIEAAAAAYmFzaWMuam91cm5leS50c1BLBQYAAAAAAQABAD4AAAAfAQAAAAA=', + 'source.zip_url.folder': '', + 'source.zip_url.password': '', + 'source.zip_url.proxy_url': '', + 'source.zip_url.url': '', + 'source.zip_url.ssl.certificate': undefined, + 'source.zip_url.username': '', + 'ssl.certificate': '', + 'ssl.certificate_authorities': '', + 'ssl.key': '', + 'ssl.key_passphrase': '', + 'ssl.supported_protocols': ['TLSv1.1', 'TLSv1.2', 'TLSv1.3'], + 'ssl.verification_mode': 'full', + synthetics_args: [], + tags: [], + 'throttling.config': '5d/3u/20l', + 'throttling.download_speed': '5', + 'throttling.is_enabled': true, + 'throttling.latency': '20', + 'throttling.upload_speed': '3', + timeout: null, + type: 'browser', + 'url.port': null, + urls: '', + id: '', + hash: 'lleklrkelkj', + }, + { + ...DEFAULT_FIELDS[DataStream.BROWSER], + __ui: { + is_zip_url_tls_enabled: false, + script_source: { + file_name: '', + is_generated_script: false, + }, + }, + config_id: '', + custom_heartbeat_id: 'check if title is present 10 1-test-project-default-space', + enabled: true, + 'filter_journeys.match': 'check if title is present 10 1', + 'filter_journeys.tags': [], + form_monitor_type: 'multistep', + ignore_https_errors: false, + journey_id: 'check if title is present 10 1', + locations: privateLocations, + name: 'check if title is present 10 1', + namespace: 'default_space', + origin: 'project', + original_space: 'default-space', + params: '{"url":"http://localhost:8080"}', + playwright_options: + '{"userAgent":"Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1","viewport":{"width":375,"height":667},"deviceScaleFactor":2,"isMobile":true,"hasTouch":true,"headless":true}', + playwright_text_assertion: '', + project_id: 'test-project', + schedule: { + number: '3', + unit: 'm', + }, + screenshots: 'on', + 'service.name': '', + 'source.inline.script': '', + 'source.project.content': + 'UEsDBBQACAAIAAAAIQAAAAAAAAAAAAAAAAAQAAAAYmFzaWMuam91cm5leS50c2WQQU7DQAxF9znFV8QiUUOmXcCCUMQl2NdMnWbKJDMaO6Ilyt0JASQkNv9Z1teTZWNAIqwP5kU4iZGOug863u7uDXsSddbIddCOl0kMX6iPnsVoOAYxryTO1ucwpoGvtUrm+hiSYsLProIoxwp8iWwVM9oUeuTP/9V5k7UhofCscNhj2yx4xN2CzabElOHXWRxsx/YNroU69QwniImFB8Vui5vJzYcKxYRIJ66WTNQL5hL7p1WD9aYi9zQOtgPFGPNqecJ1sCj+tAB6J6erpj4FDcW3qh6TL5u1Mq/8yjn7BFBLBwhGDIWc4QAAAEkBAABQSwECLQMUAAgACAAAACEARgyFnOEAAABJAQAAEAAAAAAAAAAAACAApIEAAAAAYmFzaWMuam91cm5leS50c1BLBQYAAAAAAQABAD4AAAAfAQAAAAA=', + 'source.zip_url.folder': '', + 'source.zip_url.password': '', + 'source.zip_url.proxy_url': '', + 'source.zip_url.url': '', + 'source.zip_url.username': '', + 'ssl.certificate': '', + 'ssl.certificate_authorities': '', + 'ssl.key': '', + 'ssl.key_passphrase': '', + 'ssl.supported_protocols': ['TLSv1.1', 'TLSv1.2', 'TLSv1.3'], + 'ssl.verification_mode': 'full', + synthetics_args: [], + tags: [], + 'throttling.config': '5d/3u/20l', + 'throttling.download_speed': '5', + 'throttling.is_enabled': true, + 'throttling.latency': '20', + 'throttling.upload_speed': '3', + timeout: null, + type: 'browser', + 'url.port': null, + urls: '', + id: '', + hash: 'lleklrkelkj', + }, +]; + +const soData = [ + { + attributes: formatSecrets({ + ...payloadData[0], + revision: 1, + } as any), + type: 'synthetics-monitor', + }, + { + attributes: formatSecrets({ + ...payloadData[1], + revision: 1, + } as any), + type: 'synthetics-monitor', + }, +]; + +const soResult = soData.map((so) => ({ id: 'test-id', ...so })); diff --git a/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/project_monitor_formatter_legacy.ts b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/project_monitor_formatter_legacy.ts new file mode 100644 index 0000000000000..82b29fe069c06 --- /dev/null +++ b/x-pack/plugins/synthetics/server/synthetics_service/project_monitor/project_monitor_formatter_legacy.ts @@ -0,0 +1,534 @@ +/* + * 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 { Subject } from 'rxjs'; +import { omit, isEqual } from 'lodash'; +import { KibanaRequest } from '@kbn/core/server'; +import { + SavedObjectsUpdateResponse, + SavedObjectsClientContract, + SavedObjectsFindResult, +} from '@kbn/core/server'; +import pMap from 'p-map'; +import { EncryptedSavedObjectsClient } from '@kbn/encrypted-saved-objects-plugin/server'; +import { syncNewMonitorBulk } from '../../routes/monitor_cruds/bulk_cruds/add_monitor_bulk'; +import { deleteMonitorBulk } from '../../routes/monitor_cruds/bulk_cruds/delete_monitor_bulk'; +import { SyntheticsMonitorClient } from '../synthetics_monitor/synthetics_monitor_client'; +import { syncEditedMonitorBulk } from '../../routes/monitor_cruds/bulk_cruds/edit_monitor_bulk'; +import { + ConfigKey, + SyntheticsMonitorWithSecrets, + EncryptedSyntheticsMonitor, + ServiceLocationErrors, + ProjectMonitor, + Locations, + SyntheticsMonitor, + MonitorFields, + PrivateLocation, +} from '../../../common/runtime_types'; +import { syntheticsMonitorType } from '../../legacy_uptime/lib/saved_objects/synthetics_monitor'; +import type { UptimeServerSetup } from '../../legacy_uptime/lib/adapters'; +import { formatSecrets, normalizeSecrets } from '../utils/secrets'; +import { + validateProjectMonitor, + validateMonitor, + ValidationResult, +} from '../../routes/monitor_cruds/monitor_validation'; +import { normalizeProjectMonitor } from './normalizers'; + +interface StaleMonitor { + stale: boolean; + journeyId: string; + savedObjectId: string; +} +type StaleMonitorMap = Record; +type FailedError = Array<{ id?: string; reason: string; details: string; payload?: object }>; + +export const INSUFFICIENT_FLEET_PERMISSIONS = + 'Insufficient permissions. In order to configure private locations, you must have Fleet and Integrations write permissions. To resolve, please generate a new API key with a user who has Fleet and Integrations write permissions.'; + +export class ProjectMonitorFormatterLegacy { + private projectId: string; + private spaceId: string; + private keepStale: boolean; + private locations: Locations; + private privateLocations: PrivateLocation[]; + private savedObjectsClient: SavedObjectsClientContract; + private encryptedSavedObjectsClient: EncryptedSavedObjectsClient; + private staleMonitorsMap: StaleMonitorMap = {}; + private monitors: ProjectMonitor[] = []; + public createdMonitors: string[] = []; + public deletedMonitors: string[] = []; + public updatedMonitors: string[] = []; + public staleMonitors: string[] = []; + public failedMonitors: FailedError = []; + public failedStaleMonitors: FailedError = []; + private server: UptimeServerSetup; + private projectFilter: string; + private syntheticsMonitorClient: SyntheticsMonitorClient; + private request: KibanaRequest; + private subject?: Subject; + + private writeIntegrationPoliciesPermissions?: boolean; + + constructor({ + locations, + privateLocations, + keepStale, + savedObjectsClient, + encryptedSavedObjectsClient, + projectId, + spaceId, + monitors, + server, + syntheticsMonitorClient, + request, + subject, + }: { + locations: Locations; + privateLocations: PrivateLocation[]; + keepStale: boolean; + savedObjectsClient: SavedObjectsClientContract; + encryptedSavedObjectsClient: EncryptedSavedObjectsClient; + projectId: string; + spaceId: string; + monitors: ProjectMonitor[]; + server: UptimeServerSetup; + syntheticsMonitorClient: SyntheticsMonitorClient; + request: KibanaRequest; + subject?: Subject; + }) { + this.projectId = projectId; + this.spaceId = spaceId; + this.locations = locations; + this.privateLocations = privateLocations; + this.keepStale = keepStale; + this.savedObjectsClient = savedObjectsClient; + this.encryptedSavedObjectsClient = encryptedSavedObjectsClient; + this.syntheticsMonitorClient = syntheticsMonitorClient; + this.monitors = monitors; + this.server = server; + this.projectFilter = `${syntheticsMonitorType}.attributes.${ConfigKey.PROJECT_ID}: "${this.projectId}"`; + this.request = request; + this.subject = subject; + } + + public configureAllProjectMonitors = async () => { + const existingMonitors = await this.getProjectMonitorsForProject(); + this.staleMonitorsMap = await this.getStaleMonitorsMap(existingMonitors); + + const normalizedNewMonitors: SyntheticsMonitor[] = []; + const normalizedUpdateMonitors: Array<{ + previousMonitor: SavedObjectsFindResult; + monitor: SyntheticsMonitor; + }> = []; + + for (const monitor of this.monitors) { + const previousMonitor = existingMonitors.find( + (monitorObj) => + (monitorObj.attributes as SyntheticsMonitor)[ConfigKey.JOURNEY_ID] === monitor.id + ); + + const normM = await this.validateProjectMonitor({ + monitor, + }); + if (normM) { + if (previousMonitor) { + this.updatedMonitors.push(monitor.id); + if (this.staleMonitorsMap[monitor.id]) { + this.staleMonitorsMap[monitor.id].stale = false; + } + normalizedUpdateMonitors.push({ monitor: normM as MonitorFields, previousMonitor }); + } else { + normalizedNewMonitors.push(normM as MonitorFields); + } + } + } + + await this.createMonitorsBulk(normalizedNewMonitors); + + const { updatedCount } = await this.updateMonitorsBulk(normalizedUpdateMonitors); + + if (normalizedUpdateMonitors.length > 0) { + let updateMessage = ''; + if (updatedCount > 0) { + updateMessage = `${updatedCount} monitor${ + updatedCount > 1 ? 's' : '' + } updated successfully.`; + } + + const noChanges = normalizedUpdateMonitors.length - updatedCount; + let noChangeMessage = ''; + if (noChanges > 0) { + noChangeMessage = `${noChanges} monitor${noChanges > 1 ? 's' : ''} found with no changes.`; + } + + this.handleStreamingMessage({ + message: `${updateMessage} ${noChangeMessage}`, + }); + } + + await this.handleStaleMonitors(); + }; + + validatePermissions = async ({ monitor }: { monitor: ProjectMonitor }) => { + if (this.writeIntegrationPoliciesPermissions || (monitor.privateLocations ?? []).length === 0) { + return; + } + const { + integrations: { writeIntegrationPolicies }, + } = await this.server.fleet.authz.fromRequest(this.request); + + this.writeIntegrationPoliciesPermissions = writeIntegrationPolicies; + + if (!writeIntegrationPolicies) { + throw new Error(INSUFFICIENT_FLEET_PERMISSIONS); + } + }; + + validateProjectMonitor = async ({ monitor }: { monitor: ProjectMonitor }) => { + try { + await this.validatePermissions({ monitor }); + + const { normalizedFields: normalizedMonitor, errors } = normalizeProjectMonitor({ + monitor, + locations: this.locations, + privateLocations: this.privateLocations, + projectId: this.projectId, + namespace: this.spaceId, + version: this.server.stackVersion, + }); + + if (errors.length) { + this.failedMonitors.push(...errors); + this.handleStreamingMessage({ + message: `${monitor.id}: failed to create or update monitor`, + }); + return null; + } + + /* Validates that the payload sent from the synthetics agent is valid */ + const { valid: isMonitorPayloadValid } = this.validateMonitor({ + validationResult: validateProjectMonitor({ + ...monitor, + type: normalizedMonitor[ConfigKey.MONITOR_TYPE], + }), + monitorId: monitor.id, + }); + + if (!isMonitorPayloadValid) { + return null; + } + + /* Validates that the normalized monitor is a valid monitor saved object type */ + const { valid: isNormalizedMonitorValid, decodedMonitor } = this.validateMonitor({ + validationResult: validateMonitor(normalizedMonitor as MonitorFields), + monitorId: monitor.id, + }); + + if (!isNormalizedMonitorValid || !decodedMonitor) { + return null; + } + + return decodedMonitor; + } catch (e) { + this.server.logger.error(e); + this.failedMonitors.push({ + id: monitor.id, + reason: 'Failed to create or update monitor', + details: e.message, + payload: monitor, + }); + this.handleStreamingMessage({ message: `${monitor.id}: failed to create or update monitor` }); + if (this.staleMonitorsMap[monitor.id]) { + this.staleMonitorsMap[monitor.id].stale = false; + } + } + }; + + private getStaleMonitorsMap = async ( + existingMonitors: Array> + ): Promise => { + const staleMonitors: StaleMonitorMap = {}; + + existingMonitors.forEach((savedObject) => { + const journeyId = (savedObject.attributes as SyntheticsMonitor)[ConfigKey.JOURNEY_ID]; + if (journeyId) { + staleMonitors[journeyId] = { + stale: true, + savedObjectId: savedObject.id, + journeyId, + }; + } + }); + + return staleMonitors; + }; + + public getProjectMonitorsForProject = async () => { + const finder = this.savedObjectsClient.createPointInTimeFinder({ + type: syntheticsMonitorType, + perPage: 1000, + filter: this.projectFilter, + }); + + const hits: Array> = []; + for await (const result of finder.find()) { + hits.push( + ...(result.saved_objects as Array>) + ); + } + + await finder.close(); + + return hits; + }; + + private createMonitorsBulk = async (monitors: SyntheticsMonitor[]) => { + try { + if (monitors.length > 0) { + const { newMonitors } = await syncNewMonitorBulk({ + normalizedMonitors: monitors, + server: this.server, + syntheticsMonitorClient: this.syntheticsMonitorClient, + soClient: this.savedObjectsClient, + request: this.request, + privateLocations: this.privateLocations, + spaceId: this.spaceId, + }); + + if (newMonitors && newMonitors.length === monitors.length) { + this.createdMonitors.push(...monitors.map((monitor) => monitor[ConfigKey.JOURNEY_ID]!)); + this.handleStreamingMessage({ + message: `${monitors.length} monitor${ + monitors.length > 1 ? 's' : '' + } created successfully.`, + }); + } else { + this.failedMonitors.push({ + reason: `Failed to create ${monitors.length} monitors`, + details: 'Failed to create monitors', + payload: monitors, + }); + this.handleStreamingMessage({ + message: `Failed to create ${monitors.length} monitors`, + }); + } + } + } catch (e) { + this.server.logger.error(e); + this.failedMonitors.push({ + reason: `Failed to create ${monitors.length} monitors`, + details: e.message, + payload: monitors, + }); + this.handleStreamingMessage({ + message: `Failed to create ${monitors.length} monitors`, + }); + } + }; + + private getDecryptedMonitors = async ( + monitors: Array> + ) => { + return await pMap( + monitors, + async (monitor) => + this.encryptedSavedObjectsClient.getDecryptedAsInternalUser( + syntheticsMonitorType, + monitor.id, + { + namespace: monitor.namespaces?.[0], + } + ), + { concurrency: 500 } + ); + }; + + private updateMonitorsBulk = async ( + monitors: Array<{ + monitor: SyntheticsMonitor; + previousMonitor: SavedObjectsFindResult; + }> + ): Promise<{ + editedMonitors: Array>; + errors: ServiceLocationErrors; + updatedCount: number; + }> => { + const decryptedPreviousMonitors = await this.getDecryptedMonitors( + monitors.map((m) => m.previousMonitor) + ); + + const monitorsToUpdate = []; + + for (let i = 0; i < decryptedPreviousMonitors.length; i++) { + const decryptedPreviousMonitor = decryptedPreviousMonitors[i]; + const previousMonitor = monitors[i].previousMonitor; + const normalizedMonitor = monitors[i].monitor; + + const keysToOmit = [ConfigKey.REVISION, ConfigKey.MONITOR_QUERY_ID, ConfigKey.CONFIG_ID]; + const { attributes: normalizedPreviousMonitorAttributes } = + normalizeSecrets(decryptedPreviousMonitor); + const hasMonitorBeenEdited = !isEqual( + omit(normalizedMonitor, keysToOmit), + omit(normalizedPreviousMonitorAttributes, keysToOmit) + ); + + if (hasMonitorBeenEdited) { + const monitorWithRevision = formatSecrets({ + ...normalizedPreviousMonitorAttributes, + ...normalizedMonitor, + revision: (previousMonitor.attributes[ConfigKey.REVISION] || 0) + 1, + }); + monitorsToUpdate.push({ + normalizedMonitor, + previousMonitor, + monitorWithRevision, + decryptedPreviousMonitor, + }); + } + } + + const { editedMonitors } = await syncEditedMonitorBulk({ + monitorsToUpdate, + server: this.server, + syntheticsMonitorClient: this.syntheticsMonitorClient, + savedObjectsClient: this.savedObjectsClient, + request: this.request, + privateLocations: this.privateLocations, + spaceId: this.spaceId, + }); + return { + editedMonitors: editedMonitors ?? [], + errors: [], + updatedCount: monitorsToUpdate.length, + }; + }; + + private handleStaleMonitors = async () => { + try { + const staleMonitorsList = Object.values(this.staleMonitorsMap).filter( + (monitor) => monitor.stale === true + ); + + const encryptedMonitors = await this.savedObjectsClient.bulkGet( + staleMonitorsList.map((staleMonitor) => ({ + id: staleMonitor.savedObjectId, + type: syntheticsMonitorType, + })) + ); + + let monitors = encryptedMonitors.saved_objects; + + const hasPrivateMonitor = monitors.some((monitor) => + monitor.attributes.locations.some((location) => !location.isServiceManaged) + ); + + if (hasPrivateMonitor) { + const { + integrations: { writeIntegrationPolicies }, + } = await this.server.fleet.authz.fromRequest(this.request); + if (!writeIntegrationPolicies) { + monitors = monitors.filter((monitor) => { + const hasPrivateLocation = monitor.attributes.locations.some( + (location) => !location.isServiceManaged + ); + if (hasPrivateLocation) { + const journeyId = (monitor.attributes as MonitorFields)[ConfigKey.JOURNEY_ID]!; + const monitorName = (monitor.attributes as MonitorFields)[ConfigKey.NAME]!; + this.handleStreamingMessage({ + message: `Monitor ${journeyId} could not be deleted`, + }); + this.failedStaleMonitors.push({ + id: journeyId, + reason: 'Failed to delete stale monitor', + details: `Unable to delete Synthetics package policy for monitor ${monitorName}. Fleet write permissions are needed to use Synthetics private locations.`, + }); + } + return !hasPrivateLocation; + }); + } + } + + const chunkSize = 100; + for (let i = 0; i < monitors.length; i += chunkSize) { + const chunkMonitors = monitors.slice(i, i + chunkSize); + try { + if (!this.keepStale) { + await deleteMonitorBulk({ + monitors: chunkMonitors, + savedObjectsClient: this.savedObjectsClient, + server: this.server, + syntheticsMonitorClient: this.syntheticsMonitorClient, + request: this.request, + }); + + for (const sm of chunkMonitors) { + const journeyId = (sm.attributes as MonitorFields)[ConfigKey.JOURNEY_ID]!; + + this.deletedMonitors.push(journeyId); + this.handleStreamingMessage({ + message: `Monitor ${journeyId} deleted successfully`, + }); + } + } else { + chunkMonitors.forEach((sm) => { + const journeyId = (sm.attributes as MonitorFields)[ConfigKey.JOURNEY_ID]!; + this.staleMonitors.push(journeyId); + }); + } + } catch (e) { + chunkMonitors.forEach((sm) => { + const journeyId = (sm.attributes as MonitorFields)[ConfigKey.JOURNEY_ID]!; + + this.handleStreamingMessage({ + message: `Monitor ${journeyId} could not be deleted`, + }); + this.failedStaleMonitors.push({ + id: journeyId, + reason: 'Failed to delete stale monitor', + details: e.message, + payload: staleMonitorsList.find( + (staleMonitor) => staleMonitor.savedObjectId === sm.id + ), + }); + }); + this.server.logger.error(e); + } + } + } catch (e) { + this.server.logger.error(e); + } + }; + + private handleStreamingMessage = ({ message }: { message: string }) => { + if (this.subject) { + this.subject?.next(message); + } + }; + + private validateMonitor = ({ + validationResult, + monitorId, + }: { + validationResult: ValidationResult; + monitorId: string; + }) => { + const { reason: message, details, payload: validationPayload, valid } = validationResult; + if (!valid) { + this.failedMonitors.push({ + id: monitorId, + reason: message, + details, + payload: validationPayload, + }); + if (this.staleMonitorsMap[monitorId]) { + this.staleMonitorsMap[monitorId].stale = false; + } + } + return validationResult; + }; +} diff --git a/x-pack/test/api_integration/apis/synthetics/add_monitor_project.ts b/x-pack/test/api_integration/apis/synthetics/add_monitor_project.ts index 65e9aa759f09c..7911beea80a6e 100644 --- a/x-pack/test/api_integration/apis/synthetics/add_monitor_project.ts +++ b/x-pack/test/api_integration/apis/synthetics/add_monitor_project.ts @@ -4,15 +4,14 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import fetch, { BodyInit, HeadersInit, Response } from 'node-fetch'; import uuid from 'uuid'; -import { format as formatUrl } from 'url'; +import expect from '@kbn/expect'; import { ConfigKey, ProjectMonitorsRequest } from '@kbn/synthetics-plugin/common/runtime_types'; import { API_URLS } from '@kbn/synthetics-plugin/common/constants'; import { formatKibanaNamespace } from '@kbn/synthetics-plugin/common/formatters'; import { syntheticsMonitorType } from '@kbn/synthetics-plugin/server/legacy_uptime/lib/saved_objects/synthetics_monitor'; +import { REQUEST_TOO_LARGE } from '@kbn/synthetics-plugin/server/routes/monitor_cruds/add_monitor_project'; import { PackagePolicy } from '@kbn/fleet-plugin/common'; -import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; import { getFixtureJson } from '../uptime/rest/helper/get_fixture_json'; import { PrivateLocationTestService } from './services/private_location_test_service'; @@ -26,12 +25,9 @@ export default function ({ getService }: FtrProviderContext) { this.tags('skipCloud'); const supertest = getService('supertest'); - const config = getService('config'); - const kibanaServerUrl = formatUrl(config.get('servers.kibana')); const supertestWithoutAuth = getService('supertestWithoutAuth'); const security = getService('security'); const kibanaServer = getService('kibanaServer'); - const projectMonitorEndpoint = kibanaServerUrl + API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY; let projectMonitors: ProjectMonitorsRequest; let httpProjectMonitors: ProjectMonitorsRequest; @@ -51,14 +47,11 @@ export default function ({ getService }: FtrProviderContext) { const deleteMonitor = async ( journeyId: string, projectId: string, - space: string = 'default', - username: string = '', - password: string = '' + space: string = 'default' ) => { try { const response = await supertest .get(`/s/${space}${API_URLS.SYNTHETICS_MONITORS}`) - .auth(username, password) .query({ filter: `${syntheticsMonitorType}.attributes.journey_id: "${journeyId}" AND ${syntheticsMonitorType}.attributes.project_id: "${projectId}"`, }) @@ -93,25 +86,35 @@ export default function ({ getService }: FtrProviderContext) { }); beforeEach(() => { - projectMonitors = setUniqueIds(getFixtureJson('project_browser_monitor')); - httpProjectMonitors = setUniqueIds(getFixtureJson('project_http_monitor')); - tcpProjectMonitors = setUniqueIds(getFixtureJson('project_tcp_monitor')); - icmpProjectMonitors = setUniqueIds(getFixtureJson('project_icmp_monitor')); + projectMonitors = setUniqueIds({ + monitors: getFixtureJson('project_browser_monitor').monitors, + }); + httpProjectMonitors = setUniqueIds({ + monitors: getFixtureJson('project_http_monitor').monitors, + }); + tcpProjectMonitors = setUniqueIds({ + monitors: getFixtureJson('project_tcp_monitor').monitors, + }); + icmpProjectMonitors = setUniqueIds({ + monitors: getFixtureJson('project_icmp_monitor').monitors, + }); }); it('project monitors - handles browser monitors', async () => { const successfulMonitors = [projectMonitors.monitors[0]]; + const project = `test-project-${uuid.v4()}`; try { - const messages = await parseStreamApiResponse( - projectMonitorEndpoint, - JSON.stringify(projectMonitors) - ); - - expect(messages).to.have.length(2); - expect(messages[1].updatedMonitors).eql([]); - expect(messages[1].createdMonitors).eql(successfulMonitors.map((monitor) => monitor.id)); - expect(messages[1].failedMonitors).eql([]); + const { body } = await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_UPDATE.replace('{projectName}', project)) + .set('kbn-xsrf', 'true') + .send(projectMonitors) + .expect(200); + expect(body).eql({ + updatedMonitors: [], + createdMonitors: successfulMonitors.map((monitor) => monitor.id), + failedMonitors: [], + }); for (const monitor of successfulMonitors) { const journeyId = monitor.id; @@ -135,7 +138,7 @@ export default function ({ getService }: FtrProviderContext) { }, }, config_id: decryptedCreatedMonitor.body.id, - custom_heartbeat_id: `${journeyId}-test-suite-default`, + custom_heartbeat_id: `${journeyId}-${project}-default`, enabled: true, 'filter_journeys.match': 'check if title is present', 'filter_journeys.tags': [], @@ -162,7 +165,7 @@ export default function ({ getService }: FtrProviderContext) { original_space: 'default', playwright_options: '{"headless":true,"chromiumSandbox":false}', playwright_text_assertion: '', - project_id: 'test-suite', + project_id: project, params: '', revision: 1, schedule: { @@ -196,14 +199,14 @@ export default function ({ getService }: FtrProviderContext) { type: 'browser', 'url.port': null, urls: '', - id: `${journeyId}-test-suite-default`, + id: `${journeyId}-${project}-default`, hash: 'ekrjelkjrelkjre', }); } } finally { await Promise.all([ successfulMonitors.map((monitor) => { - return deleteMonitor(monitor.id, httpProjectMonitors.project); + return deleteMonitor(monitor.id, project); }), ]); } @@ -212,28 +215,31 @@ export default function ({ getService }: FtrProviderContext) { it('project monitors - handles http monitors', async () => { const kibanaVersion = await kibanaServer.version.get(); const successfulMonitors = [httpProjectMonitors.monitors[1]]; + const project = `test-project-${uuid.v4()}`; try { - const messages = await parseStreamApiResponse( - projectMonitorEndpoint, - JSON.stringify(httpProjectMonitors) - ); + const { body } = await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_UPDATE.replace('{projectName}', project)) + .set('kbn-xsrf', 'true') + .send(httpProjectMonitors) + .expect(200); - expect(messages).to.have.length(3); - expect(messages[2].updatedMonitors).eql([]); - expect(messages[2].createdMonitors).eql(successfulMonitors.map((monitor) => monitor.id)); - expect(messages[2].failedMonitors).eql([ - { - id: httpProjectMonitors.monitors[0].id, - details: `Multiple urls are not supported for http project monitors in ${kibanaVersion}. Please set only 1 url per monitor. You monitor was not created or updated.`, - reason: 'Unsupported Heartbeat option', - }, - { - id: httpProjectMonitors.monitors[0].id, - details: `The following Heartbeat options are not supported for ${httpProjectMonitors.monitors[0].type} project monitors in ${kibanaVersion}: check.response.body|unsupportedKey.nestedUnsupportedKey. You monitor was not created or updated.`, - reason: 'Unsupported Heartbeat option', - }, - ]); + expect(body).eql({ + updatedMonitors: [], + createdMonitors: successfulMonitors.map((monitor) => monitor.id), + failedMonitors: [ + { + id: httpProjectMonitors.monitors[0].id, + details: `Multiple urls are not supported for http project monitors in ${kibanaVersion}. Please set only 1 url per monitor. You monitor was not created or updated.`, + reason: 'Unsupported Heartbeat option', + }, + { + id: httpProjectMonitors.monitors[0].id, + details: `The following Heartbeat options are not supported for ${httpProjectMonitors.monitors[0].type} project monitors in ${kibanaVersion}: check.response.body|unsupportedKey.nestedUnsupportedKey. You monitor was not created or updated.`, + reason: 'Unsupported Heartbeat option', + }, + ], + }); for (const monitor of successfulMonitors) { const journeyId = monitor.id; @@ -255,7 +261,7 @@ export default function ({ getService }: FtrProviderContext) { 'check.request.method': 'POST', 'check.response.status': ['200'], config_id: decryptedCreatedMonitor.body.id, - custom_heartbeat_id: `${journeyId}-test-suite-default`, + custom_heartbeat_id: `${journeyId}-${project}-default`, 'check.response.body.negative': [], 'check.response.body.positive': ['Saved', 'saved'], 'check.response.headers': {}, @@ -288,7 +294,7 @@ export default function ({ getService }: FtrProviderContext) { namespace: 'default', origin: 'project', original_space: 'default', - project_id: 'test-suite', + project_id: project, username: '', password: '', proxy_url: '', @@ -311,14 +317,14 @@ export default function ({ getService }: FtrProviderContext) { type: 'http', urls: Array.isArray(monitor.urls) ? monitor.urls?.[0] : monitor.urls, 'url.port': null, - id: `${journeyId}-test-suite-default`, + id: `${journeyId}-${project}-default`, hash: 'ekrjelkjrelkjre', }); } } finally { await Promise.all([ successfulMonitors.map((monitor) => { - return deleteMonitor(monitor.id, httpProjectMonitors.project); + return deleteMonitor(monitor.id, project); }), ]); } @@ -327,28 +333,31 @@ export default function ({ getService }: FtrProviderContext) { it('project monitors - handles tcp monitors', async () => { const successfulMonitors = [tcpProjectMonitors.monitors[0], tcpProjectMonitors.monitors[1]]; const kibanaVersion = await kibanaServer.version.get(); + const project = `test-project-${uuid.v4()}`; try { - const messages = await parseStreamApiResponse( - projectMonitorEndpoint, - JSON.stringify(tcpProjectMonitors) - ); + const { body } = await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_UPDATE.replace('{projectName}', project)) + .set('kbn-xsrf', 'true') + .send(tcpProjectMonitors) + .expect(200); - expect(messages).to.have.length(3); - expect(messages[2].updatedMonitors).eql([]); - expect(messages[2].createdMonitors).eql(successfulMonitors.map((monitor) => monitor.id)); - expect(messages[2].failedMonitors).eql([ - { - id: tcpProjectMonitors.monitors[2].id, - details: `Multiple hosts are not supported for tcp project monitors in ${kibanaVersion}. Please set only 1 host per monitor. You monitor was not created or updated.`, - reason: 'Unsupported Heartbeat option', - }, - { - id: tcpProjectMonitors.monitors[2].id, - details: `The following Heartbeat options are not supported for ${tcpProjectMonitors.monitors[0].type} project monitors in ${kibanaVersion}: ports|unsupportedKey.nestedUnsupportedKey. You monitor was not created or updated.`, - reason: 'Unsupported Heartbeat option', - }, - ]); + expect(body).eql({ + updatedMonitors: [], + createdMonitors: successfulMonitors.map((monitor) => monitor.id), + failedMonitors: [ + { + id: tcpProjectMonitors.monitors[2].id, + details: `Multiple hosts are not supported for tcp project monitors in ${kibanaVersion}. Please set only 1 host per monitor. You monitor was not created or updated.`, + reason: 'Unsupported Heartbeat option', + }, + { + id: tcpProjectMonitors.monitors[2].id, + details: `The following Heartbeat options are not supported for ${tcpProjectMonitors.monitors[0].type} project monitors in ${kibanaVersion}: ports|unsupportedKey.nestedUnsupportedKey. You monitor was not created or updated.`, + reason: 'Unsupported Heartbeat option', + }, + ], + }); for (const monitor of successfulMonitors) { const journeyId = monitor.id; @@ -368,7 +377,7 @@ export default function ({ getService }: FtrProviderContext) { is_tls_enabled: false, }, config_id: decryptedCreatedMonitor.body.id, - custom_heartbeat_id: `${journeyId}-test-suite-default`, + custom_heartbeat_id: `${journeyId}-${project}-default`, 'check.receive': '', 'check.send': '', enabled: true, @@ -392,7 +401,7 @@ export default function ({ getService }: FtrProviderContext) { namespace: 'default', origin: 'project', original_space: 'default', - project_id: 'test-suite', + project_id: project, revision: 1, schedule: { number: '1', @@ -413,14 +422,14 @@ export default function ({ getService }: FtrProviderContext) { hosts: Array.isArray(monitor.hosts) ? monitor.hosts?.[0] : monitor.hosts, 'url.port': null, urls: '', - id: `${journeyId}-test-suite-default`, + id: `${journeyId}-${project}-default`, hash: 'ekrjelkjrelkjre', }); } } finally { await Promise.all([ successfulMonitors.map((monitor) => { - return deleteMonitor(monitor.id, tcpProjectMonitors.project); + return deleteMonitor(monitor.id, project); }), ]); } @@ -429,28 +438,30 @@ export default function ({ getService }: FtrProviderContext) { it('project monitors - handles icmp monitors', async () => { const successfulMonitors = [icmpProjectMonitors.monitors[0], icmpProjectMonitors.monitors[1]]; const kibanaVersion = await kibanaServer.version.get(); + const project = `test-project-${uuid.v4()}`; try { - const messages = await parseStreamApiResponse( - projectMonitorEndpoint, - JSON.stringify(icmpProjectMonitors) - ); - - expect(messages).to.have.length(3); - expect(messages[2].updatedMonitors).eql([]); - expect(messages[2].createdMonitors).eql(successfulMonitors.map((monitor) => monitor.id)); - expect(messages[2].failedMonitors).eql([ - { - id: icmpProjectMonitors.monitors[2].id, - details: `Multiple hosts are not supported for icmp project monitors in ${kibanaVersion}. Please set only 1 host per monitor. You monitor was not created or updated.`, - reason: 'Unsupported Heartbeat option', - }, - { - id: icmpProjectMonitors.monitors[2].id, - details: `The following Heartbeat options are not supported for ${icmpProjectMonitors.monitors[0].type} project monitors in ${kibanaVersion}: unsupportedKey.nestedUnsupportedKey. You monitor was not created or updated.`, - reason: 'Unsupported Heartbeat option', - }, - ]); + const { body } = await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_UPDATE.replace('{projectName}', project)) + .set('kbn-xsrf', 'true') + .send(icmpProjectMonitors) + .expect(200); + expect(body).eql({ + updatedMonitors: [], + createdMonitors: successfulMonitors.map((monitor) => monitor.id), + failedMonitors: [ + { + id: icmpProjectMonitors.monitors[2].id, + details: `Multiple hosts are not supported for icmp project monitors in ${kibanaVersion}. Please set only 1 host per monitor. You monitor was not created or updated.`, + reason: 'Unsupported Heartbeat option', + }, + { + id: icmpProjectMonitors.monitors[2].id, + details: `The following Heartbeat options are not supported for ${icmpProjectMonitors.monitors[0].type} project monitors in ${kibanaVersion}: unsupportedKey.nestedUnsupportedKey. You monitor was not created or updated.`, + reason: 'Unsupported Heartbeat option', + }, + ], + }); for (const monitor of successfulMonitors) { const journeyId = monitor.id; @@ -467,7 +478,7 @@ export default function ({ getService }: FtrProviderContext) { expect(decryptedCreatedMonitor.body.attributes).to.eql({ config_id: decryptedCreatedMonitor.body.id, - custom_heartbeat_id: `${journeyId}-test-suite-default`, + custom_heartbeat_id: `${journeyId}-${project}-default`, enabled: true, form_monitor_type: 'icmp', journey_id: journeyId, @@ -501,7 +512,7 @@ export default function ({ getService }: FtrProviderContext) { namespace: 'default', origin: 'project', original_space: 'default', - project_id: 'test-suite', + project_id: project, revision: 1, schedule: { number: '1', @@ -516,496 +527,181 @@ export default function ({ getService }: FtrProviderContext) { monitor.wait?.slice(-1) === 's' ? monitor.wait?.slice(0, -1) : `${parseInt(monitor.wait?.slice(0, -1) || '1', 10) * 60}`, - id: `${journeyId}-test-suite-default`, + id: `${journeyId}-${project}-default`, hash: 'ekrjelkjrelkjre', }); } } finally { await Promise.all([ successfulMonitors.map((monitor) => { - return deleteMonitor(monitor.id, icmpProjectMonitors.project); + return deleteMonitor(monitor.id, project); }), ]); } }); it('project monitors - returns a list of successfully created monitors', async () => { + const project = `test-project-${uuid.v4()}`; try { - const messages = await parseStreamApiResponse( - projectMonitorEndpoint, - JSON.stringify(projectMonitors) - ); + const { body } = await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_UPDATE.replace('{projectName}', project)) + .set('kbn-xsrf', 'true') + .send(projectMonitors) + .expect(200); - expect(messages).to.have.length(2); - expect(messages[1].updatedMonitors).eql([]); - expect(messages[1].failedMonitors).eql([]); - expect(messages[1].createdMonitors).eql( - projectMonitors.monitors.map((monitor) => monitor.id) - ); + expect(body).eql({ + updatedMonitors: [], + failedMonitors: [], + createdMonitors: projectMonitors.monitors.map((monitor) => monitor.id), + }); } finally { await Promise.all([ projectMonitors.monitors.map((monitor) => { - return deleteMonitor(monitor.id, projectMonitors.project); + return deleteMonitor(monitor.id, project); }), ]); } }); it('project monitors - returns a list of successfully updated monitors', async () => { - try { - await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) - .set('kbn-xsrf', 'true') - .send(projectMonitors); - - const messages = await parseStreamApiResponse( - projectMonitorEndpoint, - JSON.stringify(projectMonitors) - ); - - expect(messages).to.have.length(2); - expect(messages[0]).eql(' 1 monitor found with no changes.'); - expect(messages[1].createdMonitors).eql([]); - expect(messages[1].failedMonitors).eql([]); - expect(messages[1].updatedMonitors).eql( - projectMonitors.monitors.map((monitor) => monitor.id) - ); - } finally { - await Promise.all([ - projectMonitors.monitors.map((monitor) => { - return deleteMonitor(monitor.id, projectMonitors.project); - }), - ]); - } - }); + const project = `test-project-${uuid.v4()}`; - it('project monitors - does not increment monitor revision unless a change has been made', async () => { try { await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) - .set('kbn-xsrf', 'true') - .send(projectMonitors); - - await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_UPDATE.replace('{projectName}', project)) .set('kbn-xsrf', 'true') - .send(projectMonitors); - - const updatedMonitorsResponse = await Promise.all( - projectMonitors.monitors.map((monitor) => { - return supertest - .get(API_URLS.SYNTHETICS_MONITORS) - .query({ filter: `${syntheticsMonitorType}.attributes.journey_id: ${monitor.id}` }) - .set('kbn-xsrf', 'true') - .expect(200); - }) - ); - - updatedMonitorsResponse.forEach((response) => { - expect(response.body.monitors[0].attributes.revision).eql(1); - }); - } finally { - await Promise.all([ - projectMonitors.monitors.map((monitor) => { - return deleteMonitor(monitor.id, projectMonitors.project); - }), - ]); - } - }); - - it('project monitors - increments monitor revision when a change has been made', async () => { - try { - await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .send(projectMonitors) + .expect(200); + const { body } = await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_UPDATE.replace('{projectName}', project)) .set('kbn-xsrf', 'true') - .send(projectMonitors); - - const editedMonitors = { - ...projectMonitors, - monitors: projectMonitors.monitors.map((monitor) => ({ - ...monitor, - content: 'changed content', - })), - }; - - const messages = await parseStreamApiResponse( - projectMonitorEndpoint, - JSON.stringify(editedMonitors) - ); - - const updatedMonitorsResponse = await Promise.all( - projectMonitors.monitors.map((monitor) => { - return supertest - .get(API_URLS.SYNTHETICS_MONITORS) - .query({ filter: `${syntheticsMonitorType}.attributes.journey_id: ${monitor.id}` }) - .set('kbn-xsrf', 'true') - .expect(200); - }) - ); + .send(projectMonitors) + .expect(200); - updatedMonitorsResponse.forEach((response) => { - expect(response.body.monitors[0].attributes.revision).eql(2); + expect(body).eql({ + createdMonitors: [], + failedMonitors: [], + updatedMonitors: projectMonitors.monitors.map((monitor) => monitor.id), }); - expect(messages[0]).eql('1 monitor updated successfully. '); } finally { await Promise.all([ projectMonitors.monitors.map((monitor) => { - return deleteMonitor(monitor.id, projectMonitors.project); + return deleteMonitor(monitor.id, project); }), ]); } }); - it('project monitors - does not delete monitors when keep stale is true', async () => { - const secondMonitor = { ...projectMonitors.monitors[0], id: 'test-id-2' }; - const testMonitors = [projectMonitors.monitors[0], secondMonitor]; + it('project monitors - validates monitor type', async () => { + const project = `test-project-${uuid.v4()}`; try { - await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) - .set('kbn-xsrf', 'true') - .send({ - ...projectMonitors, - monitors: testMonitors, - }); - - const messages = await parseStreamApiResponse( - projectMonitorEndpoint, - JSON.stringify(projectMonitors) - ); - - expect(messages).to.have.length(2); - expect(messages[0]).eql(' 1 monitor found with no changes.'); - expect(messages[1].createdMonitors).eql([]); - expect(messages[1].failedMonitors).eql([]); - expect(messages[1].deletedMonitors).eql([]); - expect(messages[1].updatedMonitors).eql([projectMonitors.monitors[0].id]); - expect(messages[1].staleMonitors).eql([secondMonitor.id]); - // does not delete the stale monitor - const getResponse = await supertest - .get(API_URLS.SYNTHETICS_MONITORS) - .query({ - filter: `${syntheticsMonitorType}.attributes.journey_id: ${secondMonitor.id}`, - }) + const { body } = await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_UPDATE.replace('{projectName}', project)) .set('kbn-xsrf', 'true') + .send({ monitors: [{ ...projectMonitors.monitors[0], schedule: '3m', tags: '' }] }) .expect(200); - const { monitors } = getResponse.body; - - expect(monitors.length).eql(1); + expect(body).eql({ + updatedMonitors: [], + failedMonitors: [ + { + details: 'Invalid value "3m" supplied to "schedule"', + id: projectMonitors.monitors[0].id, + payload: { + content: + 'UEsDBBQACAAIAON5qVQAAAAAAAAAAAAAAAAfAAAAZXhhbXBsZXMvdG9kb3MvYmFzaWMuam91cm5leS50c22Q0WrDMAxF3/sVF7MHB0LMXlc6RvcN+wDPVWNviW0sdUsp/fe5SSiD7UFCWFfHujIGlpnkybwxFTZfoY/E3hsaLEtwhs9RPNWKDU12zAOxkXRIbN4tB9d9pFOJdO6EN2HMqQguWN9asFBuQVMmJ7jiWNII9fIXrbabdUYr58l9IhwhQQZCYORCTFFUC31Btj21NRc7Mq4Nds+4bDD/pNVgT9F52Jyr2Fa+g75LAPttg8yErk+S9ELpTmVotlVwnfNCuh2lepl3+JflUmSBJ3uggt1v9INW/lHNLKze9dJe1J3QJK8pSvWkm6aTtCet5puq+x63+AFQSwcIAPQ3VfcAAACcAQAAUEsBAi0DFAAIAAgA43mpVAD0N1X3AAAAnAEAAB8AAAAAAAAAAAAgAKSBAAAAAGV4YW1wbGVzL3RvZG9zL2Jhc2ljLmpvdXJuZXkudHNQSwUGAAAAAAEAAQBNAAAARAEAAAAA', + filter: { + match: 'check if title is present', + }, + id: projectMonitors.monitors[0].id, + locations: ['localhost'], + name: 'check if title is present', + params: {}, + playwrightOptions: { + chromiumSandbox: false, + headless: true, + }, + schedule: '3m', + tags: '', + throttling: { + download: 5, + latency: 20, + upload: 3, + }, + type: 'browser', + hash: 'ekrjelkjrelkjre', + }, + reason: 'Failed to save or update monitor. Configuration is not valid', + }, + ], + createdMonitors: [], + }); } finally { await Promise.all([ - testMonitors.map((monitor) => { - return deleteMonitor(monitor.id, projectMonitors.project); + projectMonitors.monitors.map((monitor) => { + return deleteMonitor(monitor.id, project); }), ]); } }); - it('project monitors - deletes monitors when keep stale is false', async () => { - const secondMonitor = { ...projectMonitors.monitors[0], id: 'test-id-2' }; - const testMonitors = [projectMonitors.monitors[0], secondMonitor]; - + it('project monitors - saves space as data stream namespace', async () => { + const project = `test-project-${uuid.v4()}`; + const username = 'admin'; + const roleName = `synthetics_admin`; + const password = `${username}-password`; + const SPACE_ID = `test-space-${uuid.v4()}`; + const SPACE_NAME = `test-space-name ${uuid.v4()}`; + await kibanaServer.spaces.create({ id: SPACE_ID, name: SPACE_NAME }); try { - await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) - .set('kbn-xsrf', 'true') - .send({ - ...projectMonitors, - keep_stale: false, - monitors: testMonitors, - project: 'test-project-2', - }); - - const messages = await parseStreamApiResponse( - projectMonitorEndpoint, - JSON.stringify({ - ...projectMonitors, - keep_stale: false, - project: 'test-project-2', - }) - ); - - expect(messages).to.have.length(3); - - // expect monitor to have been deleted - const getResponse = await supertest - .get(API_URLS.SYNTHETICS_MONITORS) - .query({ - filter: `${syntheticsMonitorType}.attributes.journey_id: ${secondMonitor.id}`, - }) + await security.role.create(roleName, { + kibana: [ + { + feature: { + uptime: ['all'], + }, + spaces: ['*'], + }, + ], + }); + await security.user.create(username, { + password, + roles: [roleName], + full_name: 'a kibana user', + }); + await supertestWithoutAuth + .put( + `/s/${SPACE_ID}${API_URLS.SYNTHETICS_MONITORS_PROJECT_UPDATE.replace( + '{projectName}', + project + )}` + ) + .auth(username, password) .set('kbn-xsrf', 'true') + .send(projectMonitors) .expect(200); - - const { monitors } = getResponse.body; - expect(monitors[0]).eql(undefined); - expect(messages[0]).eql(` 1 monitor found with no changes.`); - expect(messages[1]).eql(`Monitor ${secondMonitor.id} deleted successfully`); - expect(messages[2].createdMonitors).eql([]); - expect(messages[2].failedMonitors).eql([]); - expect(messages[2].updatedMonitors).eql([projectMonitors.monitors[0].id]); - expect(messages[2].deletedMonitors).eql([secondMonitor.id]); - expect(messages[2].staleMonitors).eql([]); - } finally { - await Promise.all([ - testMonitors.map((monitor) => { - return deleteMonitor(monitor.id, projectMonitors.project); - }), - ]); - } - }); - - it('project monitors - does not delete monitors from different suites when keep stale is false', async () => { - const secondMonitor = { ...projectMonitors.monitors[0], id: 'test-id-2' }; - const testMonitors = [projectMonitors.monitors[0], secondMonitor]; - const testprojectId = 'test-suite-2'; - try { - await parseStreamApiResponse( - projectMonitorEndpoint, - JSON.stringify({ - ...projectMonitors, - keep_stale: false, - monitors: testMonitors, - }) - ); - - const messages = await parseStreamApiResponse( - projectMonitorEndpoint, - JSON.stringify({ - ...projectMonitors, - keep_stale: false, - project: testprojectId, - }) - ); - - expect(messages).to.have.length(2); - expect(messages[1].createdMonitors).eql([projectMonitors.monitors[0].id]); - expect(messages[1].failedMonitors).eql([]); - expect(messages[1].deletedMonitors).eql([]); - expect(messages[1].updatedMonitors).eql([]); - expect(messages[1].staleMonitors).eql([]); - // expect monitor not to have been deleted - const getResponse = await supertest - .get(API_URLS.SYNTHETICS_MONITORS) + const getResponse = await supertestWithoutAuth + .get(`/s/${SPACE_ID}${API_URLS.SYNTHETICS_MONITORS}`) + .auth(username, password) .query({ - filter: `${syntheticsMonitorType}.attributes.journey_id: ${secondMonitor.id}`, + filter: `${syntheticsMonitorType}.attributes.journey_id: ${projectMonitors.monitors[0].id}`, }) .set('kbn-xsrf', 'true') .expect(200); - const { monitors } = getResponse.body; - expect(monitors.length).eql(1); + expect(monitors[0].attributes[ConfigKey.NAMESPACE]).eql(formatKibanaNamespace(SPACE_ID)); } finally { - await Promise.all([ - testMonitors.map((monitor) => { - return deleteMonitor(monitor.id, projectMonitors.project); - }), - ]); - - await Promise.all([ - testMonitors.map((monitor) => { - return deleteMonitor(monitor.id, testprojectId); - }), - ]); + await deleteMonitor(projectMonitors.monitors[0].id, project, SPACE_ID); + await security.user.delete(username); + await security.role.delete(roleName); } }); - it('project monitors - does not delete a monitor from the same suite in a different space', async () => { - const secondMonitor = { ...projectMonitors.monitors[0], id: 'test-id-2' }; - const testMonitors = [projectMonitors.monitors[0], secondMonitor]; - const username = 'admin'; - const roleName = `synthetics_admin`; - const password = `${username}-password`; - const SPACE_ID = `test-space-${uuid.v4()}`; - const SPACE_NAME = `test-space-name ${uuid.v4()}`; - await kibanaServer.spaces.create({ id: SPACE_ID, name: SPACE_NAME }); - try { - await security.role.create(roleName, { - kibana: [ - { - feature: { - uptime: ['all'], - }, - spaces: ['*'], - }, - ], - }); - await security.user.create(username, { - password, - roles: [roleName], - full_name: 'a kibana user', - }); - await parseStreamApiResponse( - projectMonitorEndpoint, - JSON.stringify({ ...projectMonitors, keep_stale: false, monitors: testMonitors }), - { - Authorization: - 'Basic ' + Buffer.from(`${username}:${password}`, 'binary').toString('base64'), - } - ); - - const spaceUrl = - kibanaServerUrl + `/s/${SPACE_ID}${API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY}`; - - const messages = await parseStreamApiResponse( - spaceUrl, - JSON.stringify({ ...projectMonitors, keep_stale: false }), - { - Authorization: - 'Basic ' + Buffer.from(`${username}:${password}`, 'binary').toString('base64'), - } - ); - expect(messages).to.have.length(2); - expect(messages[1].createdMonitors).eql([projectMonitors.monitors[0].id]); - expect(messages[1].failedMonitors).eql([]); - expect(messages[1].deletedMonitors).eql([]); - expect(messages[1].updatedMonitors).eql([]); - expect(messages[1].staleMonitors).eql([]); - - const getResponse = await supertestWithoutAuth - .get(API_URLS.SYNTHETICS_MONITORS) - .auth(username, password) - .query({ - filter: `${syntheticsMonitorType}.attributes.journey_id: ${secondMonitor.id}`, - }) - .set('kbn-xsrf', 'true') - .expect(200); - const { monitors } = getResponse.body; - expect(monitors.length).eql(1); - } finally { - await Promise.all([ - testMonitors.map((monitor) => { - return deleteMonitor( - monitor.id, - projectMonitors.project, - 'default', - username, - password - ); - }), - ]); - await deleteMonitor( - projectMonitors.monitors[0].id, - projectMonitors.project, - SPACE_ID, - username, - password - ); - await security.user.delete(username); - await security.role.delete(roleName); - } - }); - - it('project monitors - validates monitor type', async () => { - try { - const messages = await parseStreamApiResponse( - projectMonitorEndpoint, - JSON.stringify({ - ...projectMonitors, - monitors: [{ ...projectMonitors.monitors[0], schedule: '3m', tags: '' }], - }) - ); - - expect(messages).to.have.length(1); - expect(messages[0].updatedMonitors).eql([]); - expect(messages[0].failedMonitors).eql([ - { - details: 'Invalid value "3m" supplied to "schedule"', - id: projectMonitors.monitors[0].id, - payload: { - content: - 'UEsDBBQACAAIAON5qVQAAAAAAAAAAAAAAAAfAAAAZXhhbXBsZXMvdG9kb3MvYmFzaWMuam91cm5leS50c22Q0WrDMAxF3/sVF7MHB0LMXlc6RvcN+wDPVWNviW0sdUsp/fe5SSiD7UFCWFfHujIGlpnkybwxFTZfoY/E3hsaLEtwhs9RPNWKDU12zAOxkXRIbN4tB9d9pFOJdO6EN2HMqQguWN9asFBuQVMmJ7jiWNII9fIXrbabdUYr58l9IhwhQQZCYORCTFFUC31Btj21NRc7Mq4Nds+4bDD/pNVgT9F52Jyr2Fa+g75LAPttg8yErk+S9ELpTmVotlVwnfNCuh2lepl3+JflUmSBJ3uggt1v9INW/lHNLKze9dJe1J3QJK8pSvWkm6aTtCet5puq+x63+AFQSwcIAPQ3VfcAAACcAQAAUEsBAi0DFAAIAAgA43mpVAD0N1X3AAAAnAEAAB8AAAAAAAAAAAAgAKSBAAAAAGV4YW1wbGVzL3RvZG9zL2Jhc2ljLmpvdXJuZXkudHNQSwUGAAAAAAEAAQBNAAAARAEAAAAA', - filter: { - match: 'check if title is present', - }, - id: projectMonitors.monitors[0].id, - locations: ['localhost'], - name: 'check if title is present', - params: {}, - playwrightOptions: { - chromiumSandbox: false, - headless: true, - }, - schedule: '3m', - tags: '', - throttling: { - download: 5, - latency: 20, - upload: 3, - }, - type: 'browser', - hash: 'ekrjelkjrelkjre', - }, - reason: 'Failed to save or update monitor. Configuration is not valid', - }, - ]); - expect(messages[0].createdMonitors).eql([]); - } finally { - await Promise.all([ - projectMonitors.monitors.map((monitor) => { - return deleteMonitor(monitor.id, projectMonitors.project); - }), - ]); - } - }); - - it('project monitors - saves space as data stream namespace', async () => { - const username = 'admin'; - const roleName = `synthetics_admin`; - const password = `${username}-password`; - const SPACE_ID = `test-space-${uuid.v4()}`; - const SPACE_NAME = `test-space-name ${uuid.v4()}`; - await kibanaServer.spaces.create({ id: SPACE_ID, name: SPACE_NAME }); - try { - await security.role.create(roleName, { - kibana: [ - { - feature: { - uptime: ['all'], - }, - spaces: ['*'], - }, - ], - }); - await security.user.create(username, { - password, - roles: [roleName], - full_name: 'a kibana user', - }); - await supertestWithoutAuth - .put(`/s/${SPACE_ID}${API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY}`) - .auth(username, password) - .set('kbn-xsrf', 'true') - .send(projectMonitors) - .expect(200); - // expect monitor not to have been deleted - const getResponse = await supertestWithoutAuth - .get(`/s/${SPACE_ID}${API_URLS.SYNTHETICS_MONITORS}`) - .auth(username, password) - .query({ - filter: `${syntheticsMonitorType}.attributes.journey_id: ${projectMonitors.monitors[0].id}`, - }) - .set('kbn-xsrf', 'true') - .expect(200); - const { monitors } = getResponse.body; - expect(monitors.length).eql(1); - expect(monitors[0].attributes[ConfigKey.NAMESPACE]).eql(formatKibanaNamespace(SPACE_ID)); - } finally { - await deleteMonitor( - projectMonitors.monitors[0].id, - projectMonitors.project, - SPACE_ID, - username, - password - ); - await security.user.delete(username); - await security.role.delete(roleName); - } - }); - - it('project monitors - formats custom id appropriately', async () => { + it('project monitors - formats custom id appropriately', async () => { + const project = `test project ${uuid.v4()}`; const username = 'admin'; const roleName = `synthetics_admin`; const password = `${username}-password`; @@ -1029,12 +725,16 @@ export default function ({ getService }: FtrProviderContext) { full_name: 'a kibana user', }); await supertestWithoutAuth - .put(`/s/${SPACE_ID}${API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY}`) + .put( + `/s/${SPACE_ID}${API_URLS.SYNTHETICS_MONITORS_PROJECT_UPDATE.replace( + '{projectName}', + project + )}` + ) .auth(username, password) .set('kbn-xsrf', 'true') .send(projectMonitors) .expect(200); - // expect monitor not to have been deleted const getResponse = await supertestWithoutAuth .get(`/s/${SPACE_ID}${API_URLS.SYNTHETICS_MONITORS}`) .auth(username, password) @@ -1046,27 +746,23 @@ export default function ({ getService }: FtrProviderContext) { const { monitors } = getResponse.body; expect(monitors.length).eql(1); expect(monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID]).eql( - `${projectMonitors.monitors[0].id}-${projectMonitors.project}-${SPACE_ID}` + `${projectMonitors.monitors[0].id}-${project}-${SPACE_ID}` ); } finally { - await deleteMonitor( - projectMonitors.monitors[0].id, - projectMonitors.project, - SPACE_ID, - username, - password - ); + await deleteMonitor(projectMonitors.monitors[0].id, project, SPACE_ID); await security.user.delete(username); await security.role.delete(roleName); } }); it('project monitors - is able to decrypt monitor when updated after hydration', async () => { + const project = `test-project-${uuid.v4()}`; try { await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_UPDATE.replace('{projectName}', project)) .set('kbn-xsrf', 'true') - .send(projectMonitors); + .send(projectMonitors) + .expect(200); const response = await supertest .get(API_URLS.SYNTHETICS_MONITORS) @@ -1093,13 +789,17 @@ export default function ({ getService }: FtrProviderContext) { .expect(200); // update project monitor via push api - const messages = await parseStreamApiResponse( - projectMonitorEndpoint, - JSON.stringify(projectMonitors) - ); - expect(messages).to.have.length(2); - expect(messages[0]).eql('1 monitor updated successfully. '); - expect(messages[1].updatedMonitors).eql([projectMonitors.monitors[0].id]); + const { body } = await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_UPDATE.replace('{projectName}', project)) + .set('kbn-xsrf', 'true') + .send(projectMonitors) + .expect(200); + + expect(body).eql({ + updatedMonitors: [projectMonitors.monitors[0].id], + createdMonitors: [], + failedMonitors: [], + }); // ensure that monitor can still be decrypted await supertest @@ -1109,21 +809,23 @@ export default function ({ getService }: FtrProviderContext) { } finally { await Promise.all([ projectMonitors.monitors.map((monitor) => { - return deleteMonitor(monitor.id, projectMonitors.project); + return deleteMonitor(monitor.id, project); }), ]); } }); it('project monitors - is able to enable and disable monitors', async () => { + const project = `test-project-${uuid.v4()}`; + try { await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_UPDATE.replace('{projectName}', project)) .set('kbn-xsrf', 'true') .send(projectMonitors); await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_UPDATE.replace('{projectName}', project)) .set('kbn-xsrf', 'true') .send({ ...projectMonitors, @@ -1147,13 +849,15 @@ export default function ({ getService }: FtrProviderContext) { } finally { await Promise.all([ projectMonitors.monitors.map((monitor) => { - return deleteMonitor(monitor.id, projectMonitors.project); + return deleteMonitor(monitor.id, project); }), ]); } }); it('project monitors - returns a failed monitor when user defines a private location without fleet permissions', async () => { + const project = `test-project-${uuid.v4()}`; + const secondMonitor = { ...projectMonitors.monitors[0], id: 'test-id-2', @@ -1180,27 +884,16 @@ export default function ({ getService }: FtrProviderContext) { full_name: 'a kibana user', }); - const messages = await parseStreamApiResponse( - kibanaServerUrl + API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY, - JSON.stringify({ - ...projectMonitors, - keep_stale: false, - monitors: testMonitors, - }), - { - Authorization: - 'Basic ' + Buffer.from(`${username}:${password}`, 'binary').toString('base64'), - } - ); + const { body } = await supertestWithoutAuth + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_UPDATE.replace('{projectName}', project)) + .auth(username, password) + .set('kbn-xsrf', 'true') + .send({ monitors: testMonitors }) + .expect(200); - expect(messages).to.have.length(3); - expect(messages[0]).to.eql('test-id-2: failed to create or update monitor'); - expect(messages[1]).to.eql(`1 monitor created successfully.`); - expect(messages[2]).to.eql({ + expect(body).eql({ createdMonitors: [testMonitors[0].id], updatedMonitors: [], - staleMonitors: [], - deletedMonitors: [], failedMonitors: [ { details: @@ -1233,126 +926,11 @@ export default function ({ getService }: FtrProviderContext) { reason: 'Failed to create or update monitor', }, ], - failedStaleMonitors: [], - }); - } finally { - await Promise.all([ - testMonitors.map((monitor) => { - return deleteMonitor( - monitor.id, - projectMonitors.project, - 'default', - username, - password - ); - }), - ]); - await security.user.delete(username); - await security.role.delete(roleName); - } - }); - - it('project monitors - returns a failed monitor when user tries to delete a monitor without fleet permissions', async () => { - const secondMonitor = { - ...projectMonitors.monitors[0], - id: 'test-id-2', - privateLocations: ['Test private location 0'], - }; - const testMonitors = [projectMonitors.monitors[0], secondMonitor]; - const username = 'test-username'; - const roleName = 'uptime read only'; - const password = `test-password`; - try { - await security.role.create(roleName, { - kibana: [ - { - feature: { - uptime: ['all'], - }, - spaces: ['*'], - }, - ], - }); - await security.user.create(username, { - password, - roles: [roleName], - full_name: 'a kibana user', - }); - - await parseStreamApiResponse( - kibanaServerUrl + API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY, - JSON.stringify({ - ...projectMonitors, - keep_stale: false, - monitors: testMonitors, - }) - ); - - const messages = await parseStreamApiResponse( - kibanaServerUrl + API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY, - JSON.stringify({ - ...projectMonitors, - keep_stale: false, - monitors: [], - }), - { - Authorization: - 'Basic ' + Buffer.from(`${username}:${password}`, 'binary').toString('base64'), - } - ); - - expect(messages).to.have.length(3); - expect( - messages.filter((msg) => msg === `Monitor ${testMonitors[1].id} could not be deleted`) - ).to.have.length(1); - expect( - messages.filter((msg) => msg === `Monitor ${testMonitors[0].id} deleted successfully`) - ).to.have.length(1); - expect(messages[2]).to.eql({ - createdMonitors: [], - updatedMonitors: [], - staleMonitors: [], - deletedMonitors: [testMonitors[0].id], - failedMonitors: [], - failedStaleMonitors: [ - { - details: - 'Unable to delete Synthetics package policy for monitor check if title is present. Fleet write permissions are needed to use Synthetics private locations.', - id: 'test-id-2', - reason: 'Failed to delete stale monitor', - }, - ], - }); - - const messages2 = await parseStreamApiResponse( - kibanaServerUrl + API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY, - JSON.stringify({ - ...projectMonitors, - keep_stale: false, - monitors: [], - }) - ); - - expect(messages2).to.have.length(2); - expect(messages2[0]).to.eql(`Monitor ${testMonitors[1].id} deleted successfully`); - expect(messages2[1]).to.eql({ - createdMonitors: [], - updatedMonitors: [], - staleMonitors: [], - deletedMonitors: [testMonitors[1].id], - failedMonitors: [], - failedStaleMonitors: [], }); } finally { await Promise.all([ testMonitors.map((monitor) => { - return deleteMonitor( - monitor.id, - projectMonitors.project, - 'default', - username, - password - ); + return deleteMonitor(monitor.id, project, 'default'); }), ]); await security.user.delete(username); @@ -1361,6 +939,7 @@ export default function ({ getService }: FtrProviderContext) { }); it('project monitors - returns a successful monitor when user defines a private location with fleet permissions', async () => { + const project = `test-project-${uuid.v4()}`; const secondMonitor = { ...projectMonitors.monitors[0], id: 'test-id-2', @@ -1388,36 +967,21 @@ export default function ({ getService }: FtrProviderContext) { roles: [roleName], full_name: 'a kibana user', }); - const messages = await parseStreamApiResponse( - projectMonitorEndpoint, - JSON.stringify({ - ...projectMonitors, - keep_stale: false, - monitors: testMonitors, - }) - ); - expect(messages).to.have.length(2); - expect(messages).to.eql([ - `2 monitors created successfully.`, - { - createdMonitors: [testMonitors[0].id, 'test-id-2'], - updatedMonitors: [], - staleMonitors: [], - deletedMonitors: [], - failedMonitors: [], - failedStaleMonitors: [], - }, - ]); + const { body } = await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_UPDATE.replace('{projectName}', project)) + .set('kbn-xsrf', 'true') + .send({ monitors: testMonitors }) + .expect(200); + + expect(body).to.eql({ + createdMonitors: [testMonitors[0].id, 'test-id-2'], + updatedMonitors: [], + failedMonitors: [], + }); } finally { await Promise.all([ testMonitors.map((monitor) => { - return deleteMonitor( - monitor.id, - projectMonitors.project, - 'default', - username, - password - ); + return deleteMonitor(monitor.id, project, 'default'); }), ]); await security.user.delete(username); @@ -1426,16 +990,19 @@ export default function ({ getService }: FtrProviderContext) { }); it('creates integration policies for project monitors with private locations', async () => { + const project = `test-project-${uuid.v4()}`; + try { await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_UPDATE.replace('{projectName}', project)) .set('kbn-xsrf', 'true') .send({ ...projectMonitors, monitors: [ { ...projectMonitors.monitors[0], privateLocations: ['Test private location 0'] }, ], - }); + }) + .expect(200); const monitorsResponse = await supertest .get(API_URLS.SYNTHETICS_MONITORS) @@ -1457,7 +1024,7 @@ export default function ({ getService }: FtrProviderContext) { }-${testPolicyId}` ); expect(packagePolicy.name).eql( - `${projectMonitors.monitors[0].id}-${projectMonitors.project}-default-Test private location 0` + `${projectMonitors.monitors[0].id}-${project}-default-Test private location 0` ); expect(packagePolicy.policy_id).eql(testPolicyId); @@ -1471,10 +1038,11 @@ export default function ({ getService }: FtrProviderContext) { name: 'check if title is present-Test private location 0', id, configId, + projectId: project, }) ); } finally { - await deleteMonitor(projectMonitors.monitors[0].id, projectMonitors.project); + await deleteMonitor(projectMonitors.monitors[0].id, project); const packagesResponse = await supertest.get( '/api/fleet/package_policies?page=1&perPage=2000&kuery=ingest-package-policies.package.name%3A%20synthetics' @@ -1484,17 +1052,19 @@ export default function ({ getService }: FtrProviderContext) { }); it('deletes integration policies for project monitors when private location is removed from the monitor - lightweight', async () => { + const project = `test-project-${uuid.v4()}`; + const monitorRequest = { - ...httpProjectMonitors, monitors: [ { ...httpProjectMonitors.monitors[1], privateLocations: ['Test private location 0'] }, ], }; try { await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_UPDATE.replace('{projectName}', project)) .set('kbn-xsrf', 'true') - .send(monitorRequest); + .send(monitorRequest) + .expect(200); const monitorsResponse = await supertest .get(API_URLS.SYNTHETICS_MONITORS) @@ -1519,12 +1089,12 @@ export default function ({ getService }: FtrProviderContext) { expect(packagePolicy.policy_id).eql(testPolicyId); await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_UPDATE.replace('{projectName}', project)) .set('kbn-xsrf', 'true') .send({ - ...monitorRequest, monitors: [{ ...monitorRequest.monitors[0], privateLocations: [] }], - }); + }) + .expect(200); const apiResponsePolicy2 = await supertest.get( '/api/fleet/package_policies?page=1&perPage=2000&kuery=ingest-package-policies.package.name%3A%20synthetics' @@ -1540,21 +1110,23 @@ export default function ({ getService }: FtrProviderContext) { expect(packagePolicy2).eql(undefined); } finally { - await deleteMonitor(projectMonitors.monitors[0].id, projectMonitors.project); + await deleteMonitor(projectMonitors.monitors[0].id, project); } }); it('deletes integration policies for project monitors when private location is removed from the monitor', async () => { + const project = `test-project-${uuid.v4()}`; + try { await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_UPDATE.replace('{projectName}', project)) .set('kbn-xsrf', 'true') .send({ - ...projectMonitors, monitors: [ { ...projectMonitors.monitors[0], privateLocations: ['Test private location 0'] }, ], - }); + }) + .expect(200); const monitorsResponse = await supertest .get(API_URLS.SYNTHETICS_MONITORS) @@ -1588,160 +1160,23 @@ export default function ({ getService }: FtrProviderContext) { name: 'check if title is present-Test private location 0', id, configId, + projectId: project, }) ); await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_UPDATE.replace('{projectName}', project)) .set('kbn-xsrf', 'true') .send({ - ...projectMonitors, monitors: [{ ...projectMonitors.monitors[0], privateLocations: [] }], - }); - - const apiResponsePolicy2 = await supertest.get( - '/api/fleet/package_policies?page=1&perPage=2000&kuery=ingest-package-policies.package.name%3A%20synthetics' - ); - - const packagePolicy2 = apiResponsePolicy2.body.items.find( - (pkgPolicy: PackagePolicy) => - pkgPolicy.id === - `${ - monitorsResponse.body.monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID] - }-${testPolicyId}` - ); - - expect(packagePolicy2).eql(undefined); - } finally { - await deleteMonitor(projectMonitors.monitors[0].id, projectMonitors.project); - - const apiResponsePolicy2 = await supertest.get( - '/api/fleet/package_policies?page=1&perPage=2000&kuery=ingest-package-policies.package.name%3A%20synthetics' - ); - expect(apiResponsePolicy2.body.items.length).eql(0); - } - }); - - it('deletes integration policies when project monitors are deleted', async () => { - try { - await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) - .set('kbn-xsrf', 'true') - .send({ - ...projectMonitors, - monitors: [ - { ...projectMonitors.monitors[0], privateLocations: ['Test private location 0'] }, - ], - }) - .expect(200); - - const monitorsResponse = await supertest - .get(API_URLS.SYNTHETICS_MONITORS) - .query({ - filter: `${syntheticsMonitorType}.attributes.journey_id: ${projectMonitors.monitors[0].id}`, - }) - .set('kbn-xsrf', 'true') - .expect(200); - - const apiResponsePolicy = await supertest.get( - '/api/fleet/package_policies?page=1&perPage=2000&kuery=ingest-package-policies.package.name%3A%20synthetics' - ); - - const packagePolicy = apiResponsePolicy.body.items.find( - (pkgPolicy: PackagePolicy) => - pkgPolicy.id === - monitorsResponse.body.monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID] + - '-' + - testPolicyId - ); - - expect(packagePolicy.policy_id).eql(testPolicyId); - - const configId = monitorsResponse.body.monitors[0].id; - const id = monitorsResponse.body.monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID]; - - comparePolicies( - packagePolicy, - getTestProjectSyntheticsPolicy({ - inputs: {}, - name: 'check if title is present-Test private location 0', - id, - configId, }) - ); - - await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) - .set('kbn-xsrf', 'true') - .send({ - ...projectMonitors, - monitors: [], - keep_stale: false, - }); - - const monitorsResponse2 = await supertest - .get(API_URLS.SYNTHETICS_MONITORS) - .query({ - filter: `${syntheticsMonitorType}.attributes.journey_id: ${projectMonitors.monitors[0].id}`, - }) - .set('kbn-xsrf', 'true') .expect(200); - expect(monitorsResponse2.body.monitors.length).eql(0); - - await new Promise((resolve) => { - setTimeout(() => resolve(null), 3000); - }); - const apiResponsePolicy2 = await supertest.get( '/api/fleet/package_policies?page=1&perPage=2000&kuery=ingest-package-policies.package.name%3A%20synthetics' ); const packagePolicy2 = apiResponsePolicy2.body.items.find( - (pkgPolicy: PackagePolicy) => - pkgPolicy.id === - monitorsResponse.body.monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID] + - '-' + - testPolicyId - ); - - expect(packagePolicy2).eql(undefined); - } finally { - await deleteMonitor(projectMonitors.monitors[0].id, projectMonitors.project); - - const apiResponsePolicy2 = await supertest.get( - '/api/fleet/package_policies?page=1&perPage=2000&kuery=ingest-package-policies.package.name%3A%20synthetics' - ); - expect(apiResponsePolicy2.body.items.length).eql(0); - } - }); - - it('deletes integration policies when project monitors are deleted - lightweight', async () => { - const monitorRequest = { - ...httpProjectMonitors, - monitors: [ - { ...httpProjectMonitors.monitors[1], privateLocations: ['Test private location 0'] }, - ], - }; - try { - await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) - .set('kbn-xsrf', 'true') - .send(monitorRequest); - - const monitorsResponse = await supertest - .get(API_URLS.SYNTHETICS_MONITORS) - .query({ - filter: `${syntheticsMonitorType}.attributes.journey_id: ${monitorRequest.monitors[0].id}`, - }) - .set('kbn-xsrf', 'true') - .expect(200); - - const apiResponsePolicy = await supertest.get( - '/api/fleet/package_policies?page=1&perPage=2000&kuery=ingest-package-policies.package.name%3A%20synthetics' - ); - - const packagePolicy = apiResponsePolicy.body.items.find( (pkgPolicy: PackagePolicy) => pkgPolicy.id === `${ @@ -1749,138 +1184,9 @@ export default function ({ getService }: FtrProviderContext) { }-${testPolicyId}` ); - expect(packagePolicy.policy_id).eql(testPolicyId); - - const configId = monitorsResponse.body.monitors[0].id; - const id = monitorsResponse.body.monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID]; - - const httpInput = packagePolicy.inputs.find( - (input: any) => input.type === 'synthetics/http' - ); - expect(httpInput).to.eql({ - type: 'synthetics/http', - policy_template: 'synthetics', - enabled: true, - streams: [ - { - enabled: true, - data_stream: { type: 'synthetics', dataset: 'http' }, - release: 'experimental', - vars: { - __ui: { value: '{"is_tls_enabled":false}', type: 'yaml' }, - enabled: { value: false, type: 'bool' }, - type: { value: 'http', type: 'text' }, - name: { value: 'My Monitor 3', type: 'text' }, - schedule: { value: '"@every 60m"', type: 'text' }, - urls: { value: 'http://localhost:9200', type: 'text' }, - 'service.name': { value: '', type: 'text' }, - timeout: { value: '80s', type: 'text' }, - max_redirects: { value: '0', type: 'integer' }, - proxy_url: { value: '', type: 'text' }, - tags: { value: '["tag2","tag2"]', type: 'yaml' }, - username: { value: '', type: 'text' }, - password: { value: '', type: 'password' }, - 'response.include_headers': { value: false, type: 'bool' }, - 'response.include_body': { value: 'always', type: 'text' }, - 'check.request.method': { value: 'POST', type: 'text' }, - 'check.request.headers': { - value: '{"Content-Type":"application/x-www-form-urlencoded"}', - type: 'yaml', - }, - 'check.request.body': { value: null, type: 'yaml' }, - 'check.response.status': { value: '["200"]', type: 'yaml' }, - 'check.response.headers': { value: null, type: 'yaml' }, - 'check.response.body.positive': { value: '["Saved","saved"]', type: 'yaml' }, - 'check.response.body.negative': { value: null, type: 'yaml' }, - 'ssl.certificate_authorities': { value: null, type: 'yaml' }, - 'ssl.certificate': { value: null, type: 'yaml' }, - 'ssl.key': { value: null, type: 'yaml' }, - 'ssl.key_passphrase': { value: null, type: 'text' }, - 'ssl.verification_mode': { value: 'full', type: 'text' }, - 'ssl.supported_protocols': { - value: '["TLSv1.1","TLSv1.2","TLSv1.3"]', - type: 'yaml', - }, - location_name: { value: 'Test private location 0', type: 'text' }, - id: { - value: id, - type: 'text', - }, - config_id: { value: configId, type: 'text' }, - run_once: { value: false, type: 'bool' }, - origin: { value: 'project', type: 'text' }, - 'monitor.project.id': { - type: 'text', - value: 'test-suite', - }, - 'monitor.project.name': { - type: 'text', - value: 'test-suite', - }, - }, - id: `synthetics/http-http-${id}-${testPolicyId}`, - compiled_stream: { - __ui: { is_tls_enabled: false }, - type: 'http', - name: 'My Monitor 3', - id, - origin: 'project', - enabled: false, - urls: 'http://localhost:9200', - schedule: '@every 60m', - timeout: '80s', - max_redirects: 0, - tags: ['tag2', 'tag2'], - 'response.include_headers': false, - 'response.include_body': 'always', - 'check.request.method': 'POST', - 'check.request.headers': { 'Content-Type': 'application/x-www-form-urlencoded' }, - 'check.response.status': ['200'], - 'check.response.body.positive': ['Saved', 'saved'], - 'ssl.verification_mode': 'full', - 'ssl.supported_protocols': ['TLSv1.1', 'TLSv1.2', 'TLSv1.3'], - processors: [ - { add_observer_metadata: { geo: { name: 'Test private location 0' } } }, - { - add_fields: { - target: '', - fields: { - 'monitor.fleet_managed': true, - config_id: configId, - 'monitor.project.id': 'test-suite', - 'monitor.project.name': 'test-suite', - }, - }, - }, - ], - }, - }, - ], - }); - - await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) - .set('kbn-xsrf', 'true') - .send({ - ...monitorRequest, - monitors: [], - }); - - const apiResponsePolicy2 = await supertest.get( - '/api/fleet/package_policies?page=1&perPage=2000&kuery=ingest-package-policies.package.name%3A%20synthetics' - ); - - const packagePolicy2 = apiResponsePolicy2.body.items.find( - (pkgPolicy: PackagePolicy) => - pkgPolicy.id === - `${ - monitorsResponse.body.monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID] - } - ${testPolicyId}` - ); - expect(packagePolicy2).eql(undefined); } finally { - await deleteMonitor(httpProjectMonitors.monitors[1].id, httpProjectMonitors.project); + await deleteMonitor(projectMonitors.monitors[0].id, project); const apiResponsePolicy2 = await supertest.get( '/api/fleet/package_policies?page=1&perPage=2000&kuery=ingest-package-policies.package.name%3A%20synthetics' @@ -1890,12 +1196,13 @@ export default function ({ getService }: FtrProviderContext) { }); it('handles updating package policies when project monitors are updated', async () => { + const project = `test-project-${uuid.v4()}`; + try { await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_UPDATE.replace('{projectName}', project)) .set('kbn-xsrf', 'true') .send({ - ...projectMonitors, monitors: [ { ...projectMonitors.monitors[0], @@ -1933,14 +1240,14 @@ export default function ({ getService }: FtrProviderContext) { name: 'check if title is present-Test private location 0', id, configId, + projectId: project, }) ); await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_UPDATE.replace('{projectName}', project)) .set('kbn-xsrf', 'true') .send({ - ...projectMonitors, monitors: [ { ...projectMonitors.monitors[0], @@ -1969,10 +1276,11 @@ export default function ({ getService }: FtrProviderContext) { name: 'check if title is present-Test private location 0', id: id2, configId: configId2, + projectId: project, }) ); } finally { - await deleteMonitor(projectMonitors.monitors[0].id, projectMonitors.project); + await deleteMonitor(projectMonitors.monitors[0].id, project); const apiResponsePolicy2 = await supertest.get( '/api/fleet/package_policies?page=1&perPage=2000&kuery=ingest-package-policies.package.name%3A%20synthetics' @@ -1982,12 +1290,12 @@ export default function ({ getService }: FtrProviderContext) { }); it('handles location formatting for both private and public locations', async () => { + const project = `test-project-${uuid.v4()}`; try { await supertest - .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_UPDATE.replace('{projectName}', project)) .set('kbn-xsrf', 'true') .send({ - ...projectMonitors, monitors: [ { ...projectMonitors.monitors[0], privateLocations: ['Test private location 0'] }, ], @@ -2031,94 +1339,104 @@ export default function ({ getService }: FtrProviderContext) { } finally { await Promise.all([ projectMonitors.monitors.map((monitor) => { - return deleteMonitor(monitor.id, projectMonitors.project); + return deleteMonitor(monitor.id, project); }), ]); } }); - }); -} - -/** - * Borrowed from AIOPS test code: https://github.com/elastic/kibana/blob/23a7ac2c2e2b1f64daa17b914e86989b1fde750c/x-pack/test/api_integration/apis/aiops/explain_log_rate_spikes.ts - * Receives a stream and parses the messages until the stream closes. - */ -async function* parseStream(stream: NodeJS.ReadableStream) { - let partial = ''; - - try { - for await (const value of stream) { - const full = `${partial}${value}`; - const parts = full.split('\n'); - const last = parts.pop(); - partial = last ?? ''; + it('only allows 250 requests at a time', async () => { + const project = `test-project-${uuid.v4()}`; + const monitors = []; + for (let i = 0; i < 251; i++) { + monitors.push({ + ...projectMonitors.monitors[0], + id: `test-id-${i}`, + name: `test-name-${i}`, + }); + } - const event = parts.map((p) => JSON.parse(p)); + try { + const { + body: { message }, + } = await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_UPDATE.replace('{projectName}', project)) + .set('kbn-xsrf', 'true') + .send({ + monitors, + }) + .expect(400); - for (const events of event) { - yield events; + expect(message).to.eql(REQUEST_TOO_LARGE); + } finally { + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .set('kbn-xsrf', 'true') + .send({ ...projectMonitors, keep_stale: false, project }); } - } - } catch (error) { - yield { type: 'error', payload: error.toString() }; - } -} + }); -/** - * Helper function to process the results of the module's stream parsing helper function. - */ -async function getMessages(stream: NodeJS.ReadableStream | null) { - if (stream === null) return []; - const data: any[] = []; - for await (const action of parseStream(stream)) { - data.push(action); - } - return data; -} + it('project monitors - cannot update a monitor of one type to another type', async () => { + const project = `test-project-${uuid.v4()}`; -/** - * This type is intended to highlight any break between shared parameter contracts defined in - * the module's streaming endpoint helper functions. - */ -type StreamApiFunction = ( - url: string, - body?: BodyInit, - extraHeaders?: HeadersInit, - method?: string -) => T; - -/** - * This helps the test file have DRY code when it comes to calling - * the same streaming endpoint over and over by defining some selective defaults. - */ -export const parseStreamApiResponse: StreamApiFunction> = async ( - url: string, - body?: BodyInit, - extraHeaders?: HeadersInit, - method = 'PUT' -) => { - const streamResponse = await callStreamApi(url, body, extraHeaders, method); - return getMessages(streamResponse.body); -}; - -/** - * This helps the test file have DRY code when it comes to calling - * the same streaming endpoint over and over by defining some selective defaults. - */ -const callStreamApi: StreamApiFunction> = async ( - url: string, - body?: BodyInit, - extraHeaders?: HeadersInit, - method = 'PUT' -) => { - return fetch(url, { - method, - headers: { - 'Content-Type': 'application/json', - 'kbn-xsrf': 'stream', - ...extraHeaders, - }, - body, + try { + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_UPDATE.replace('{projectName}', project)) + .set('kbn-xsrf', 'true') + .send(projectMonitors) + .expect(200); + const { body } = await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_UPDATE.replace('{projectName}', project)) + .set('kbn-xsrf', 'true') + .send({ + monitors: [{ ...httpProjectMonitors.monitors[1], id: projectMonitors.monitors[0].id }], + }) + .expect(200); + expect(body).eql({ + createdMonitors: [], + updatedMonitors: [], + failedMonitors: [ + { + details: `Monitor ${projectMonitors.monitors[0].id} of type browser cannot be updated to type http. Please delete the monitor first and try again.`, + payload: { + 'check.request': { + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + method: 'POST', + }, + 'check.response': { + body: { + positive: ['Saved', 'saved'], + }, + status: [200], + }, + enabled: false, + hash: 'ekrjelkjrelkjre', + id: projectMonitors.monitors[0].id, + locations: ['localhost'], + name: 'My Monitor 3', + response: { + include_body: 'always', + }, + 'response.include_headers': false, + schedule: 60, + timeout: '80s', + type: 'http', + tags: 'tag2,tag2', + urls: ['http://localhost:9200'], + }, + reason: 'Cannot update monitor to different type.', + }, + ], + }); + } finally { + await Promise.all([ + projectMonitors.monitors.map((monitor) => { + return deleteMonitor(monitor.id, project); + }), + ]); + } + }); }); -}; +} diff --git a/x-pack/test/api_integration/apis/synthetics/add_monitor_project_legacy.ts b/x-pack/test/api_integration/apis/synthetics/add_monitor_project_legacy.ts new file mode 100644 index 0000000000000..9d5e4b45f4e7f --- /dev/null +++ b/x-pack/test/api_integration/apis/synthetics/add_monitor_project_legacy.ts @@ -0,0 +1,2127 @@ +/* + * 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 fetch, { BodyInit, HeadersInit, Response } from 'node-fetch'; +import uuid from 'uuid'; +import expect from '@kbn/expect'; +import { format as formatUrl } from 'url'; +import { + ConfigKey, + LegacyProjectMonitorsRequest, +} from '@kbn/synthetics-plugin/common/runtime_types'; +import { API_URLS } from '@kbn/synthetics-plugin/common/constants'; +import { formatKibanaNamespace } from '@kbn/synthetics-plugin/common/formatters'; +import { syntheticsMonitorType } from '@kbn/synthetics-plugin/server/legacy_uptime/lib/saved_objects/synthetics_monitor'; +import { PackagePolicy } from '@kbn/fleet-plugin/common'; +import { FtrProviderContext } from '../../ftr_provider_context'; +import { getFixtureJson } from '../uptime/rest/helper/get_fixture_json'; +import { PrivateLocationTestService } from './services/private_location_test_service'; +import { + comparePolicies, + getTestProjectSyntheticsPolicy, +} from '../uptime/rest/sample_data/test_policy'; + +export default function ({ getService }: FtrProviderContext) { + describe('AddProjectLegacyMonitors', function () { + this.tags('skipCloud'); + + const supertest = getService('supertest'); + const config = getService('config'); + const kibanaServerUrl = formatUrl(config.get('servers.kibana')); + const supertestWithoutAuth = getService('supertestWithoutAuth'); + const security = getService('security'); + const kibanaServer = getService('kibanaServer'); + const projectMonitorEndpoint = kibanaServerUrl + API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY; + + let projectMonitors: LegacyProjectMonitorsRequest; + let httpProjectMonitors: LegacyProjectMonitorsRequest; + let tcpProjectMonitors: LegacyProjectMonitorsRequest; + let icmpProjectMonitors: LegacyProjectMonitorsRequest; + + let testPolicyId = ''; + const testPrivateLocations = new PrivateLocationTestService(getService); + + const setUniqueIds = (request: LegacyProjectMonitorsRequest) => { + return { + ...request, + monitors: request.monitors.map((monitor) => ({ ...monitor, id: uuid.v4() })), + }; + }; + + const deleteMonitor = async ( + journeyId: string, + projectId: string, + space: string = 'default', + username: string = '', + password: string = '' + ) => { + try { + const response = await supertest + .get(`/s/${space}${API_URLS.SYNTHETICS_MONITORS}`) + .auth(username, password) + .query({ + filter: `${syntheticsMonitorType}.attributes.journey_id: "${journeyId}" AND ${syntheticsMonitorType}.attributes.project_id: "${projectId}"`, + }) + .set('kbn-xsrf', 'true') + .expect(200); + const { monitors } = response.body; + if (monitors[0]?.id) { + await supertest + .delete(`/s/${space}${API_URLS.SYNTHETICS_MONITORS}/${monitors[0].id}`) + .set('kbn-xsrf', 'true') + .send(projectMonitors) + .expect(200); + } + } catch (e) { + // eslint-disable-next-line no-console + console.error(e); + } + }; + + before(async () => { + await supertest.post('/api/fleet/setup').set('kbn-xsrf', 'true').send().expect(200); + await supertest + .post('/api/fleet/epm/packages/synthetics/0.10.3') + .set('kbn-xsrf', 'true') + .send({ force: true }) + .expect(200); + + const testPolicyName = 'Fleet test server policy' + Date.now(); + const apiResponse = await testPrivateLocations.addFleetPolicy(testPolicyName); + testPolicyId = apiResponse.body.item.id; + await testPrivateLocations.setTestLocations([testPolicyId]); + }); + + beforeEach(() => { + projectMonitors = setUniqueIds(getFixtureJson('project_browser_monitor')); + httpProjectMonitors = setUniqueIds(getFixtureJson('project_http_monitor')); + tcpProjectMonitors = setUniqueIds(getFixtureJson('project_tcp_monitor')); + icmpProjectMonitors = setUniqueIds(getFixtureJson('project_icmp_monitor')); + }); + + it('project monitors - handles browser monitors', async () => { + const successfulMonitors = [projectMonitors.monitors[0]]; + + try { + const messages = await parseStreamApiResponse( + projectMonitorEndpoint, + JSON.stringify(projectMonitors) + ); + + expect(messages).to.have.length(2); + expect(messages[1].updatedMonitors).eql([]); + expect(messages[1].createdMonitors).eql(successfulMonitors.map((monitor) => monitor.id)); + expect(messages[1].failedMonitors).eql([]); + + for (const monitor of successfulMonitors) { + const journeyId = monitor.id; + const createdMonitorsResponse = await supertest + .get(API_URLS.SYNTHETICS_MONITORS) + .query({ filter: `${syntheticsMonitorType}.attributes.journey_id: ${journeyId}` }) + .set('kbn-xsrf', 'true') + .expect(200); + + const decryptedCreatedMonitor = await supertest + .get(`${API_URLS.SYNTHETICS_MONITORS}/${createdMonitorsResponse.body.monitors[0].id}`) + .set('kbn-xsrf', 'true') + .expect(200); + + expect(decryptedCreatedMonitor.body.attributes).to.eql({ + __ui: { + is_zip_url_tls_enabled: false, + script_source: { + file_name: '', + is_generated_script: false, + }, + }, + config_id: decryptedCreatedMonitor.body.id, + custom_heartbeat_id: `${journeyId}-test-suite-default`, + enabled: true, + 'filter_journeys.match': 'check if title is present', + 'filter_journeys.tags': [], + form_monitor_type: 'multistep', + ignore_https_errors: false, + journey_id: journeyId, + locations: [ + { + geo: { + lat: 0, + lon: 0, + }, + id: 'localhost', + isInvalid: false, + isServiceManaged: true, + label: 'Local Synthetics Service', + status: 'experimental', + url: 'mockDevUrl', + }, + ], + name: 'check if title is present', + namespace: 'default', + origin: 'project', + original_space: 'default', + playwright_options: '{"headless":true,"chromiumSandbox":false}', + playwright_text_assertion: '', + project_id: 'test-suite', + params: '', + revision: 1, + schedule: { + number: '10', + unit: 'm', + }, + screenshots: 'on', + 'service.name': '', + 'source.zip_url.folder': '', + 'source.zip_url.proxy_url': '', + 'source.zip_url.url': '', + 'source.zip_url.password': '', + 'source.zip_url.username': '', + synthetics_args: [], + tags: [], + 'throttling.config': '5d/3u/20l', + 'throttling.download_speed': '5', + 'throttling.is_enabled': true, + 'throttling.latency': '20', + 'throttling.upload_speed': '3', + 'ssl.certificate': '', + 'ssl.certificate_authorities': '', + 'ssl.supported_protocols': ['TLSv1.1', 'TLSv1.2', 'TLSv1.3'], + 'ssl.verification_mode': 'full', + 'ssl.key': '', + 'ssl.key_passphrase': '', + 'source.inline.script': '', + 'source.project.content': + 'UEsDBBQACAAIAON5qVQAAAAAAAAAAAAAAAAfAAAAZXhhbXBsZXMvdG9kb3MvYmFzaWMuam91cm5leS50c22Q0WrDMAxF3/sVF7MHB0LMXlc6RvcN+wDPVWNviW0sdUsp/fe5SSiD7UFCWFfHujIGlpnkybwxFTZfoY/E3hsaLEtwhs9RPNWKDU12zAOxkXRIbN4tB9d9pFOJdO6EN2HMqQguWN9asFBuQVMmJ7jiWNII9fIXrbabdUYr58l9IhwhQQZCYORCTFFUC31Btj21NRc7Mq4Nds+4bDD/pNVgT9F52Jyr2Fa+g75LAPttg8yErk+S9ELpTmVotlVwnfNCuh2lepl3+JflUmSBJ3uggt1v9INW/lHNLKze9dJe1J3QJK8pSvWkm6aTtCet5puq+x63+AFQSwcIAPQ3VfcAAACcAQAAUEsBAi0DFAAIAAgA43mpVAD0N1X3AAAAnAEAAB8AAAAAAAAAAAAgAKSBAAAAAGV4YW1wbGVzL3RvZG9zL2Jhc2ljLmpvdXJuZXkudHNQSwUGAAAAAAEAAQBNAAAARAEAAAAA', + timeout: null, + type: 'browser', + 'url.port': null, + urls: '', + id: `${journeyId}-test-suite-default`, + hash: 'ekrjelkjrelkjre', + }); + } + } finally { + await Promise.all([ + successfulMonitors.map((monitor) => { + return deleteMonitor(monitor.id, httpProjectMonitors.project); + }), + ]); + } + }); + + it('project monitors - handles http monitors', async () => { + const kibanaVersion = await kibanaServer.version.get(); + const successfulMonitors = [httpProjectMonitors.monitors[1]]; + + try { + const messages = await parseStreamApiResponse( + projectMonitorEndpoint, + JSON.stringify(httpProjectMonitors) + ); + + expect(messages).to.have.length(3); + expect(messages[2].updatedMonitors).eql([]); + expect(messages[2].createdMonitors).eql(successfulMonitors.map((monitor) => monitor.id)); + expect(messages[2].failedMonitors).eql([ + { + id: httpProjectMonitors.monitors[0].id, + details: `Multiple urls are not supported for http project monitors in ${kibanaVersion}. Please set only 1 url per monitor. You monitor was not created or updated.`, + reason: 'Unsupported Heartbeat option', + }, + { + id: httpProjectMonitors.monitors[0].id, + details: `The following Heartbeat options are not supported for ${httpProjectMonitors.monitors[0].type} project monitors in ${kibanaVersion}: check.response.body|unsupportedKey.nestedUnsupportedKey. You monitor was not created or updated.`, + reason: 'Unsupported Heartbeat option', + }, + ]); + + for (const monitor of successfulMonitors) { + const journeyId = monitor.id; + const createdMonitorsResponse = await supertest + .get(API_URLS.SYNTHETICS_MONITORS) + .query({ filter: `${syntheticsMonitorType}.attributes.journey_id: ${journeyId}` }) + .set('kbn-xsrf', 'true') + .expect(200); + + const decryptedCreatedMonitor = await supertest + .get(`${API_URLS.SYNTHETICS_MONITORS}/${createdMonitorsResponse.body.monitors[0].id}`) + .set('kbn-xsrf', 'true') + .expect(200); + + expect(decryptedCreatedMonitor.body.attributes).to.eql({ + __ui: { + is_tls_enabled: false, + }, + 'check.request.method': 'POST', + 'check.response.status': ['200'], + config_id: decryptedCreatedMonitor.body.id, + custom_heartbeat_id: `${journeyId}-test-suite-default`, + 'check.response.body.negative': [], + 'check.response.body.positive': ['Saved', 'saved'], + 'check.response.headers': {}, + 'check.request.body': { + type: 'text', + value: '', + }, + 'check.request.headers': { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + enabled: false, + form_monitor_type: 'http', + journey_id: journeyId, + locations: [ + { + geo: { + lat: 0, + lon: 0, + }, + id: 'localhost', + isInvalid: false, + isServiceManaged: true, + label: 'Local Synthetics Service', + status: 'experimental', + url: 'mockDevUrl', + }, + ], + max_redirects: '0', + name: monitor.name, + namespace: 'default', + origin: 'project', + original_space: 'default', + project_id: 'test-suite', + username: '', + password: '', + proxy_url: '', + 'response.include_body': 'always', + 'response.include_headers': false, + revision: 1, + schedule: { + number: '60', + unit: 'm', + }, + 'service.name': '', + 'ssl.certificate': '', + 'ssl.certificate_authorities': '', + 'ssl.supported_protocols': ['TLSv1.1', 'TLSv1.2', 'TLSv1.3'], + 'ssl.verification_mode': 'full', + 'ssl.key': '', + 'ssl.key_passphrase': '', + tags: Array.isArray(monitor.tags) ? monitor.tags : monitor.tags?.split(','), + timeout: '80', + type: 'http', + urls: Array.isArray(monitor.urls) ? monitor.urls?.[0] : monitor.urls, + 'url.port': null, + id: `${journeyId}-test-suite-default`, + hash: 'ekrjelkjrelkjre', + }); + } + } finally { + await Promise.all([ + successfulMonitors.map((monitor) => { + return deleteMonitor(monitor.id, httpProjectMonitors.project); + }), + ]); + } + }); + + it('project monitors - handles tcp monitors', async () => { + const successfulMonitors = [tcpProjectMonitors.monitors[0], tcpProjectMonitors.monitors[1]]; + const kibanaVersion = await kibanaServer.version.get(); + + try { + const messages = await parseStreamApiResponse( + projectMonitorEndpoint, + JSON.stringify(tcpProjectMonitors) + ); + + expect(messages).to.have.length(3); + expect(messages[2].updatedMonitors).eql([]); + expect(messages[2].createdMonitors).eql(successfulMonitors.map((monitor) => monitor.id)); + expect(messages[2].failedMonitors).eql([ + { + id: tcpProjectMonitors.monitors[2].id, + details: `Multiple hosts are not supported for tcp project monitors in ${kibanaVersion}. Please set only 1 host per monitor. You monitor was not created or updated.`, + reason: 'Unsupported Heartbeat option', + }, + { + id: tcpProjectMonitors.monitors[2].id, + details: `The following Heartbeat options are not supported for ${tcpProjectMonitors.monitors[0].type} project monitors in ${kibanaVersion}: ports|unsupportedKey.nestedUnsupportedKey. You monitor was not created or updated.`, + reason: 'Unsupported Heartbeat option', + }, + ]); + + for (const monitor of successfulMonitors) { + const journeyId = monitor.id; + const createdMonitorsResponse = await supertest + .get(API_URLS.SYNTHETICS_MONITORS) + .query({ filter: `${syntheticsMonitorType}.attributes.journey_id: ${journeyId}` }) + .set('kbn-xsrf', 'true') + .expect(200); + + const decryptedCreatedMonitor = await supertest + .get(`${API_URLS.SYNTHETICS_MONITORS}/${createdMonitorsResponse.body.monitors[0].id}`) + .set('kbn-xsrf', 'true') + .expect(200); + + expect(decryptedCreatedMonitor.body.attributes).to.eql({ + __ui: { + is_tls_enabled: false, + }, + config_id: decryptedCreatedMonitor.body.id, + custom_heartbeat_id: `${journeyId}-test-suite-default`, + 'check.receive': '', + 'check.send': '', + enabled: true, + form_monitor_type: 'tcp', + journey_id: journeyId, + locations: [ + { + geo: { + lat: 0, + lon: 0, + }, + id: 'localhost', + isInvalid: false, + isServiceManaged: true, + label: 'Local Synthetics Service', + status: 'experimental', + url: 'mockDevUrl', + }, + ], + name: monitor.name, + namespace: 'default', + origin: 'project', + original_space: 'default', + project_id: 'test-suite', + revision: 1, + schedule: { + number: '1', + unit: 'm', + }, + proxy_url: '', + proxy_use_local_resolver: false, + 'service.name': '', + 'ssl.certificate': '', + 'ssl.certificate_authorities': '', + 'ssl.supported_protocols': ['TLSv1.1', 'TLSv1.2', 'TLSv1.3'], + 'ssl.verification_mode': 'full', + 'ssl.key': '', + 'ssl.key_passphrase': '', + tags: Array.isArray(monitor.tags) ? monitor.tags : monitor.tags?.split(','), + timeout: '16', + type: 'tcp', + hosts: Array.isArray(monitor.hosts) ? monitor.hosts?.[0] : monitor.hosts, + 'url.port': null, + urls: '', + id: `${journeyId}-test-suite-default`, + hash: 'ekrjelkjrelkjre', + }); + } + } finally { + await Promise.all([ + successfulMonitors.map((monitor) => { + return deleteMonitor(monitor.id, tcpProjectMonitors.project); + }), + ]); + } + }); + + it('project monitors - handles icmp monitors', async () => { + const successfulMonitors = [icmpProjectMonitors.monitors[0], icmpProjectMonitors.monitors[1]]; + const kibanaVersion = await kibanaServer.version.get(); + + try { + const messages = await parseStreamApiResponse( + projectMonitorEndpoint, + JSON.stringify(icmpProjectMonitors) + ); + + expect(messages).to.have.length(3); + expect(messages[2].updatedMonitors).eql([]); + expect(messages[2].createdMonitors).eql(successfulMonitors.map((monitor) => monitor.id)); + expect(messages[2].failedMonitors).eql([ + { + id: icmpProjectMonitors.monitors[2].id, + details: `Multiple hosts are not supported for icmp project monitors in ${kibanaVersion}. Please set only 1 host per monitor. You monitor was not created or updated.`, + reason: 'Unsupported Heartbeat option', + }, + { + id: icmpProjectMonitors.monitors[2].id, + details: `The following Heartbeat options are not supported for ${icmpProjectMonitors.monitors[0].type} project monitors in ${kibanaVersion}: unsupportedKey.nestedUnsupportedKey. You monitor was not created or updated.`, + reason: 'Unsupported Heartbeat option', + }, + ]); + + for (const monitor of successfulMonitors) { + const journeyId = monitor.id; + const createdMonitorsResponse = await supertest + .get(API_URLS.SYNTHETICS_MONITORS) + .query({ filter: `${syntheticsMonitorType}.attributes.journey_id: ${journeyId}` }) + .set('kbn-xsrf', 'true') + .expect(200); + + const decryptedCreatedMonitor = await supertest + .get(`${API_URLS.SYNTHETICS_MONITORS}/${createdMonitorsResponse.body.monitors[0].id}`) + .set('kbn-xsrf', 'true') + .expect(200); + + expect(decryptedCreatedMonitor.body.attributes).to.eql({ + config_id: decryptedCreatedMonitor.body.id, + custom_heartbeat_id: `${journeyId}-test-suite-default`, + enabled: true, + form_monitor_type: 'icmp', + journey_id: journeyId, + locations: [ + { + geo: { + lat: 0, + lon: 0, + }, + id: 'localhost', + isInvalid: false, + isServiceManaged: true, + label: 'Local Synthetics Service', + status: 'experimental', + url: 'mockDevUrl', + }, + { + agentPolicyId: testPolicyId, + concurrentMonitors: 1, + geo: { + lat: '', + lon: '', + }, + id: testPolicyId, + isInvalid: false, + isServiceManaged: false, + label: 'Test private location 0', + }, + ], + name: monitor.name, + namespace: 'default', + origin: 'project', + original_space: 'default', + project_id: 'test-suite', + revision: 1, + schedule: { + number: '1', + unit: 'm', + }, + 'service.name': '', + tags: Array.isArray(monitor.tags) ? monitor.tags : monitor.tags?.split(','), + timeout: '16', + type: 'icmp', + hosts: Array.isArray(monitor.hosts) ? monitor.hosts?.[0] : monitor.hosts, + wait: + monitor.wait?.slice(-1) === 's' + ? monitor.wait?.slice(0, -1) + : `${parseInt(monitor.wait?.slice(0, -1) || '1', 10) * 60}`, + id: `${journeyId}-test-suite-default`, + hash: 'ekrjelkjrelkjre', + }); + } + } finally { + await Promise.all([ + successfulMonitors.map((monitor) => { + return deleteMonitor(monitor.id, icmpProjectMonitors.project); + }), + ]); + } + }); + + it('project monitors - returns a list of successfully created monitors', async () => { + try { + const messages = await parseStreamApiResponse( + projectMonitorEndpoint, + JSON.stringify(projectMonitors) + ); + + expect(messages).to.have.length(2); + expect(messages[1].updatedMonitors).eql([]); + expect(messages[1].failedMonitors).eql([]); + expect(messages[1].createdMonitors).eql( + projectMonitors.monitors.map((monitor) => monitor.id) + ); + } finally { + await Promise.all([ + projectMonitors.monitors.map((monitor) => { + return deleteMonitor(monitor.id, projectMonitors.project); + }), + ]); + } + }); + + it('project monitors - returns a list of successfully updated monitors', async () => { + try { + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .set('kbn-xsrf', 'true') + .send(projectMonitors); + + const messages = await parseStreamApiResponse( + projectMonitorEndpoint, + JSON.stringify(projectMonitors) + ); + + expect(messages).to.have.length(2); + expect(messages[0]).eql(' 1 monitor found with no changes.'); + expect(messages[1].createdMonitors).eql([]); + expect(messages[1].failedMonitors).eql([]); + expect(messages[1].updatedMonitors).eql( + projectMonitors.monitors.map((monitor) => monitor.id) + ); + } finally { + await Promise.all([ + projectMonitors.monitors.map((monitor) => { + return deleteMonitor(monitor.id, projectMonitors.project); + }), + ]); + } + }); + + it('project monitors - does not increment monitor revision unless a change has been made', async () => { + try { + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .set('kbn-xsrf', 'true') + .send(projectMonitors); + + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .set('kbn-xsrf', 'true') + .send(projectMonitors); + + const updatedMonitorsResponse = await Promise.all( + projectMonitors.monitors.map((monitor) => { + return supertest + .get(API_URLS.SYNTHETICS_MONITORS) + .query({ filter: `${syntheticsMonitorType}.attributes.journey_id: ${monitor.id}` }) + .set('kbn-xsrf', 'true') + .expect(200); + }) + ); + + updatedMonitorsResponse.forEach((response) => { + expect(response.body.monitors[0].attributes.revision).eql(1); + }); + } finally { + await Promise.all([ + projectMonitors.monitors.map((monitor) => { + return deleteMonitor(monitor.id, projectMonitors.project); + }), + ]); + } + }); + + it('project monitors - increments monitor revision when a change has been made', async () => { + try { + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .set('kbn-xsrf', 'true') + .send(projectMonitors); + + const editedMonitors = { + ...projectMonitors, + monitors: projectMonitors.monitors.map((monitor) => ({ + ...monitor, + content: 'changed content', + })), + }; + + const messages = await parseStreamApiResponse( + projectMonitorEndpoint, + JSON.stringify(editedMonitors) + ); + + const updatedMonitorsResponse = await Promise.all( + projectMonitors.monitors.map((monitor) => { + return supertest + .get(API_URLS.SYNTHETICS_MONITORS) + .query({ filter: `${syntheticsMonitorType}.attributes.journey_id: ${monitor.id}` }) + .set('kbn-xsrf', 'true') + .expect(200); + }) + ); + + updatedMonitorsResponse.forEach((response) => { + expect(response.body.monitors[0].attributes.revision).eql(2); + }); + expect(messages[0]).eql('1 monitor updated successfully. '); + } finally { + await Promise.all([ + projectMonitors.monitors.map((monitor) => { + return deleteMonitor(monitor.id, projectMonitors.project); + }), + ]); + } + }); + + it('project monitors - does not delete monitors when keep stale is true', async () => { + const secondMonitor = { ...projectMonitors.monitors[0], id: 'test-id-2' }; + const testMonitors = [projectMonitors.monitors[0], secondMonitor]; + + try { + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .set('kbn-xsrf', 'true') + .send({ + ...projectMonitors, + monitors: testMonitors, + }); + + const messages = await parseStreamApiResponse( + projectMonitorEndpoint, + JSON.stringify(projectMonitors) + ); + + expect(messages).to.have.length(2); + expect(messages[0]).eql(' 1 monitor found with no changes.'); + expect(messages[1].createdMonitors).eql([]); + expect(messages[1].failedMonitors).eql([]); + expect(messages[1].deletedMonitors).eql([]); + expect(messages[1].updatedMonitors).eql([projectMonitors.monitors[0].id]); + expect(messages[1].staleMonitors).eql([secondMonitor.id]); + // does not delete the stale monitor + const getResponse = await supertest + .get(API_URLS.SYNTHETICS_MONITORS) + .query({ + filter: `${syntheticsMonitorType}.attributes.journey_id: ${secondMonitor.id}`, + }) + .set('kbn-xsrf', 'true') + .expect(200); + + const { monitors } = getResponse.body; + + expect(monitors.length).eql(1); + } finally { + await Promise.all([ + testMonitors.map((monitor) => { + return deleteMonitor(monitor.id, projectMonitors.project); + }), + ]); + } + }); + + it('project monitors - deletes monitors when keep stale is false', async () => { + const secondMonitor = { ...projectMonitors.monitors[0], id: 'test-id-2' }; + const testMonitors = [projectMonitors.monitors[0], secondMonitor]; + + try { + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .set('kbn-xsrf', 'true') + .send({ + ...projectMonitors, + keep_stale: false, + monitors: testMonitors, + project: 'test-project-2', + }); + + const messages = await parseStreamApiResponse( + projectMonitorEndpoint, + JSON.stringify({ + ...projectMonitors, + keep_stale: false, + project: 'test-project-2', + }) + ); + + expect(messages).to.have.length(3); + + // expect monitor to have been deleted + const getResponse = await supertest + .get(API_URLS.SYNTHETICS_MONITORS) + .query({ + filter: `${syntheticsMonitorType}.attributes.journey_id: ${secondMonitor.id}`, + }) + .set('kbn-xsrf', 'true') + .expect(200); + + const { monitors } = getResponse.body; + expect(monitors[0]).eql(undefined); + expect(messages[0]).eql(` 1 monitor found with no changes.`); + expect(messages[1]).eql(`Monitor ${secondMonitor.id} deleted successfully`); + expect(messages[2].createdMonitors).eql([]); + expect(messages[2].failedMonitors).eql([]); + expect(messages[2].updatedMonitors).eql([projectMonitors.monitors[0].id]); + expect(messages[2].deletedMonitors).eql([secondMonitor.id]); + expect(messages[2].staleMonitors).eql([]); + } finally { + await Promise.all([ + testMonitors.map((monitor) => { + return deleteMonitor(monitor.id, projectMonitors.project); + }), + ]); + } + }); + + it('project monitors - does not delete monitors from different suites when keep stale is false', async () => { + const secondMonitor = { ...projectMonitors.monitors[0], id: 'test-id-2' }; + const testMonitors = [projectMonitors.monitors[0], secondMonitor]; + const testprojectId = 'test-suite-2'; + try { + await parseStreamApiResponse( + projectMonitorEndpoint, + JSON.stringify({ + ...projectMonitors, + keep_stale: false, + monitors: testMonitors, + }) + ); + + const messages = await parseStreamApiResponse( + projectMonitorEndpoint, + JSON.stringify({ + ...projectMonitors, + keep_stale: false, + project: testprojectId, + }) + ); + + expect(messages).to.have.length(2); + expect(messages[1].createdMonitors).eql([projectMonitors.monitors[0].id]); + expect(messages[1].failedMonitors).eql([]); + expect(messages[1].deletedMonitors).eql([]); + expect(messages[1].updatedMonitors).eql([]); + expect(messages[1].staleMonitors).eql([]); + + // expect monitor not to have been deleted + const getResponse = await supertest + .get(API_URLS.SYNTHETICS_MONITORS) + .query({ + filter: `${syntheticsMonitorType}.attributes.journey_id: ${secondMonitor.id}`, + }) + .set('kbn-xsrf', 'true') + .expect(200); + + const { monitors } = getResponse.body; + + expect(monitors.length).eql(1); + } finally { + await Promise.all([ + testMonitors.map((monitor) => { + return deleteMonitor(monitor.id, projectMonitors.project); + }), + ]); + + await Promise.all([ + testMonitors.map((monitor) => { + return deleteMonitor(monitor.id, testprojectId); + }), + ]); + } + }); + + it('project monitors - does not delete a monitor from the same suite in a different space', async () => { + const secondMonitor = { ...projectMonitors.monitors[0], id: 'test-id-2' }; + const testMonitors = [projectMonitors.monitors[0], secondMonitor]; + const username = 'admin'; + const roleName = `synthetics_admin`; + const password = `${username}-password`; + const SPACE_ID = `test-space-${uuid.v4()}`; + const SPACE_NAME = `test-space-name ${uuid.v4()}`; + await kibanaServer.spaces.create({ id: SPACE_ID, name: SPACE_NAME }); + try { + await security.role.create(roleName, { + kibana: [ + { + feature: { + uptime: ['all'], + }, + spaces: ['*'], + }, + ], + }); + await security.user.create(username, { + password, + roles: [roleName], + full_name: 'a kibana user', + }); + await parseStreamApiResponse( + projectMonitorEndpoint, + JSON.stringify({ ...projectMonitors, keep_stale: false, monitors: testMonitors }), + { + Authorization: + 'Basic ' + Buffer.from(`${username}:${password}`, 'binary').toString('base64'), + } + ); + + const spaceUrl = + kibanaServerUrl + `/s/${SPACE_ID}${API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY}`; + + const messages = await parseStreamApiResponse( + spaceUrl, + JSON.stringify({ ...projectMonitors, keep_stale: false }), + { + Authorization: + 'Basic ' + Buffer.from(`${username}:${password}`, 'binary').toString('base64'), + } + ); + expect(messages).to.have.length(2); + expect(messages[1].createdMonitors).eql([projectMonitors.monitors[0].id]); + expect(messages[1].failedMonitors).eql([]); + expect(messages[1].deletedMonitors).eql([]); + expect(messages[1].updatedMonitors).eql([]); + expect(messages[1].staleMonitors).eql([]); + + const getResponse = await supertestWithoutAuth + .get(API_URLS.SYNTHETICS_MONITORS) + .auth(username, password) + .query({ + filter: `${syntheticsMonitorType}.attributes.journey_id: ${secondMonitor.id}`, + }) + .set('kbn-xsrf', 'true') + .expect(200); + const { monitors } = getResponse.body; + expect(monitors.length).eql(1); + } finally { + await Promise.all([ + testMonitors.map((monitor) => { + return deleteMonitor( + monitor.id, + projectMonitors.project, + 'default', + username, + password + ); + }), + ]); + await deleteMonitor( + projectMonitors.monitors[0].id, + projectMonitors.project, + SPACE_ID, + username, + password + ); + await security.user.delete(username); + await security.role.delete(roleName); + } + }); + + it('project monitors - validates monitor type', async () => { + try { + const messages = await parseStreamApiResponse( + projectMonitorEndpoint, + JSON.stringify({ + ...projectMonitors, + monitors: [{ ...projectMonitors.monitors[0], schedule: '3m', tags: '' }], + }) + ); + + expect(messages).to.have.length(1); + expect(messages[0].updatedMonitors).eql([]); + expect(messages[0].failedMonitors).eql([ + { + details: 'Invalid value "3m" supplied to "schedule"', + id: projectMonitors.monitors[0].id, + payload: { + content: + 'UEsDBBQACAAIAON5qVQAAAAAAAAAAAAAAAAfAAAAZXhhbXBsZXMvdG9kb3MvYmFzaWMuam91cm5leS50c22Q0WrDMAxF3/sVF7MHB0LMXlc6RvcN+wDPVWNviW0sdUsp/fe5SSiD7UFCWFfHujIGlpnkybwxFTZfoY/E3hsaLEtwhs9RPNWKDU12zAOxkXRIbN4tB9d9pFOJdO6EN2HMqQguWN9asFBuQVMmJ7jiWNII9fIXrbabdUYr58l9IhwhQQZCYORCTFFUC31Btj21NRc7Mq4Nds+4bDD/pNVgT9F52Jyr2Fa+g75LAPttg8yErk+S9ELpTmVotlVwnfNCuh2lepl3+JflUmSBJ3uggt1v9INW/lHNLKze9dJe1J3QJK8pSvWkm6aTtCet5puq+x63+AFQSwcIAPQ3VfcAAACcAQAAUEsBAi0DFAAIAAgA43mpVAD0N1X3AAAAnAEAAB8AAAAAAAAAAAAgAKSBAAAAAGV4YW1wbGVzL3RvZG9zL2Jhc2ljLmpvdXJuZXkudHNQSwUGAAAAAAEAAQBNAAAARAEAAAAA', + filter: { + match: 'check if title is present', + }, + id: projectMonitors.monitors[0].id, + locations: ['localhost'], + name: 'check if title is present', + params: {}, + playwrightOptions: { + chromiumSandbox: false, + headless: true, + }, + schedule: '3m', + tags: '', + throttling: { + download: 5, + latency: 20, + upload: 3, + }, + type: 'browser', + hash: 'ekrjelkjrelkjre', + }, + reason: 'Failed to save or update monitor. Configuration is not valid', + }, + ]); + expect(messages[0].createdMonitors).eql([]); + } finally { + await Promise.all([ + projectMonitors.monitors.map((monitor) => { + return deleteMonitor(monitor.id, projectMonitors.project); + }), + ]); + } + }); + + it('project monitors - saves space as data stream namespace', async () => { + const username = 'admin'; + const roleName = `synthetics_admin`; + const password = `${username}-password`; + const SPACE_ID = `test-space-${uuid.v4()}`; + const SPACE_NAME = `test-space-name ${uuid.v4()}`; + await kibanaServer.spaces.create({ id: SPACE_ID, name: SPACE_NAME }); + try { + await security.role.create(roleName, { + kibana: [ + { + feature: { + uptime: ['all'], + }, + spaces: ['*'], + }, + ], + }); + await security.user.create(username, { + password, + roles: [roleName], + full_name: 'a kibana user', + }); + await supertestWithoutAuth + .put(`/s/${SPACE_ID}${API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY}`) + .auth(username, password) + .set('kbn-xsrf', 'true') + .send(projectMonitors) + .expect(200); + // expect monitor not to have been deleted + const getResponse = await supertestWithoutAuth + .get(`/s/${SPACE_ID}${API_URLS.SYNTHETICS_MONITORS}`) + .auth(username, password) + .query({ + filter: `${syntheticsMonitorType}.attributes.journey_id: ${projectMonitors.monitors[0].id}`, + }) + .set('kbn-xsrf', 'true') + .expect(200); + const { monitors } = getResponse.body; + expect(monitors.length).eql(1); + expect(monitors[0].attributes[ConfigKey.NAMESPACE]).eql(formatKibanaNamespace(SPACE_ID)); + } finally { + await deleteMonitor( + projectMonitors.monitors[0].id, + projectMonitors.project, + SPACE_ID, + username, + password + ); + await security.user.delete(username); + await security.role.delete(roleName); + } + }); + + it('project monitors - formats custom id appropriately', async () => { + const username = 'admin'; + const roleName = `synthetics_admin`; + const password = `${username}-password`; + const SPACE_ID = `test-space-${uuid.v4()}`; + const SPACE_NAME = `test-space-name ${uuid.v4()}`; + await kibanaServer.spaces.create({ id: SPACE_ID, name: SPACE_NAME }); + try { + await security.role.create(roleName, { + kibana: [ + { + feature: { + uptime: ['all'], + }, + spaces: ['*'], + }, + ], + }); + await security.user.create(username, { + password, + roles: [roleName], + full_name: 'a kibana user', + }); + await supertestWithoutAuth + .put(`/s/${SPACE_ID}${API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY}`) + .auth(username, password) + .set('kbn-xsrf', 'true') + .send(projectMonitors) + .expect(200); + // expect monitor not to have been deleted + const getResponse = await supertestWithoutAuth + .get(`/s/${SPACE_ID}${API_URLS.SYNTHETICS_MONITORS}`) + .auth(username, password) + .query({ + filter: `${syntheticsMonitorType}.attributes.journey_id: ${projectMonitors.monitors[0].id}`, + }) + .set('kbn-xsrf', 'true') + .expect(200); + const { monitors } = getResponse.body; + expect(monitors.length).eql(1); + expect(monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID]).eql( + `${projectMonitors.monitors[0].id}-${projectMonitors.project}-${SPACE_ID}` + ); + } finally { + await deleteMonitor( + projectMonitors.monitors[0].id, + projectMonitors.project, + SPACE_ID, + username, + password + ); + await security.user.delete(username); + await security.role.delete(roleName); + } + }); + + it('project monitors - is able to decrypt monitor when updated after hydration', async () => { + try { + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .set('kbn-xsrf', 'true') + .send(projectMonitors); + + const response = await supertest + .get(API_URLS.SYNTHETICS_MONITORS) + .query({ + filter: `${syntheticsMonitorType}.attributes.journey_id: ${projectMonitors.monitors[0].id}`, + }) + .set('kbn-xsrf', 'true') + .expect(200); + + const { monitors } = response.body; + + // add urls and ports to mimic hydration + const updates = { + [ConfigKey.URLS]: 'https://modified-host.com', + [ConfigKey.PORT]: 443, + }; + + const modifiedMonitor = { ...monitors[0]?.attributes, ...updates }; + + await supertest + .put(API_URLS.SYNTHETICS_MONITORS + '/' + monitors[0]?.id) + .set('kbn-xsrf', 'true') + .send(modifiedMonitor) + .expect(200); + + // update project monitor via push api + const messages = await parseStreamApiResponse( + projectMonitorEndpoint, + JSON.stringify(projectMonitors) + ); + expect(messages).to.have.length(2); + expect(messages[0]).eql('1 monitor updated successfully. '); + expect(messages[1].updatedMonitors).eql([projectMonitors.monitors[0].id]); + + // ensure that monitor can still be decrypted + await supertest + .get(API_URLS.SYNTHETICS_MONITORS + '/' + monitors[0]?.id) + .set('kbn-xsrf', 'true') + .expect(200); + } finally { + await Promise.all([ + projectMonitors.monitors.map((monitor) => { + return deleteMonitor(monitor.id, projectMonitors.project); + }), + ]); + } + }); + + it('project monitors - is able to enable and disable monitors', async () => { + try { + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .set('kbn-xsrf', 'true') + .send(projectMonitors); + + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .set('kbn-xsrf', 'true') + .send({ + ...projectMonitors, + monitors: [ + { + ...projectMonitors.monitors[0], + enabled: false, + }, + ], + }) + .expect(200); + const response = await supertest + .get(API_URLS.SYNTHETICS_MONITORS) + .query({ + filter: `${syntheticsMonitorType}.attributes.journey_id: ${projectMonitors.monitors[0].id}`, + }) + .set('kbn-xsrf', 'true') + .expect(200); + const { monitors } = response.body; + expect(monitors[0].attributes.enabled).eql(false); + } finally { + await Promise.all([ + projectMonitors.monitors.map((monitor) => { + return deleteMonitor(monitor.id, projectMonitors.project); + }), + ]); + } + }); + + it('project monitors - returns a failed monitor when user defines a private location without fleet permissions', async () => { + const secondMonitor = { + ...projectMonitors.monitors[0], + id: 'test-id-2', + privateLocations: ['Test private location 0'], + }; + const testMonitors = [projectMonitors.monitors[0], secondMonitor]; + const username = 'admin'; + const roleName = 'uptime read only'; + const password = `${username}-password`; + try { + await security.role.create(roleName, { + kibana: [ + { + feature: { + uptime: ['all'], + }, + spaces: ['*'], + }, + ], + }); + await security.user.create(username, { + password, + roles: [roleName], + full_name: 'a kibana user', + }); + + const messages = await parseStreamApiResponse( + kibanaServerUrl + API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY, + JSON.stringify({ + ...projectMonitors, + keep_stale: false, + monitors: testMonitors, + }), + { + Authorization: + 'Basic ' + Buffer.from(`${username}:${password}`, 'binary').toString('base64'), + } + ); + + expect(messages).to.have.length(3); + expect(messages[0]).to.eql('test-id-2: failed to create or update monitor'); + expect(messages[1]).to.eql(`1 monitor created successfully.`); + expect(messages[2]).to.eql({ + createdMonitors: [testMonitors[0].id], + updatedMonitors: [], + staleMonitors: [], + deletedMonitors: [], + failedMonitors: [ + { + details: + 'Insufficient permissions. In order to configure private locations, you must have Fleet and Integrations write permissions. To resolve, please generate a new API key with a user who has Fleet and Integrations write permissions.', + id: 'test-id-2', + payload: { + content: + 'UEsDBBQACAAIAON5qVQAAAAAAAAAAAAAAAAfAAAAZXhhbXBsZXMvdG9kb3MvYmFzaWMuam91cm5leS50c22Q0WrDMAxF3/sVF7MHB0LMXlc6RvcN+wDPVWNviW0sdUsp/fe5SSiD7UFCWFfHujIGlpnkybwxFTZfoY/E3hsaLEtwhs9RPNWKDU12zAOxkXRIbN4tB9d9pFOJdO6EN2HMqQguWN9asFBuQVMmJ7jiWNII9fIXrbabdUYr58l9IhwhQQZCYORCTFFUC31Btj21NRc7Mq4Nds+4bDD/pNVgT9F52Jyr2Fa+g75LAPttg8yErk+S9ELpTmVotlVwnfNCuh2lepl3+JflUmSBJ3uggt1v9INW/lHNLKze9dJe1J3QJK8pSvWkm6aTtCet5puq+x63+AFQSwcIAPQ3VfcAAACcAQAAUEsBAi0DFAAIAAgA43mpVAD0N1X3AAAAnAEAAB8AAAAAAAAAAAAgAKSBAAAAAGV4YW1wbGVzL3RvZG9zL2Jhc2ljLmpvdXJuZXkudHNQSwUGAAAAAAEAAQBNAAAARAEAAAAA', + filter: { + match: 'check if title is present', + }, + id: 'test-id-2', + locations: ['localhost'], + name: 'check if title is present', + params: {}, + playwrightOptions: { + chromiumSandbox: false, + headless: true, + }, + privateLocations: ['Test private location 0'], + schedule: 10, + tags: [], + throttling: { + download: 5, + latency: 20, + upload: 3, + }, + hash: 'ekrjelkjrelkjre', + }, + reason: 'Failed to create or update monitor', + }, + ], + failedStaleMonitors: [], + }); + } finally { + await Promise.all([ + testMonitors.map((monitor) => { + return deleteMonitor( + monitor.id, + projectMonitors.project, + 'default', + username, + password + ); + }), + ]); + await security.user.delete(username); + await security.role.delete(roleName); + } + }); + + it('project monitors - returns a failed monitor when user tries to delete a monitor without fleet permissions', async () => { + const secondMonitor = { + ...projectMonitors.monitors[0], + id: 'test-id-2', + privateLocations: ['Test private location 0'], + }; + const testMonitors = [projectMonitors.monitors[0], secondMonitor]; + const username = 'test-username'; + const roleName = 'uptime read only'; + const password = `test-password`; + try { + await security.role.create(roleName, { + kibana: [ + { + feature: { + uptime: ['all'], + }, + spaces: ['*'], + }, + ], + }); + await security.user.create(username, { + password, + roles: [roleName], + full_name: 'a kibana user', + }); + + await parseStreamApiResponse( + kibanaServerUrl + API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY, + JSON.stringify({ + ...projectMonitors, + keep_stale: false, + monitors: testMonitors, + }) + ); + + const messages = await parseStreamApiResponse( + kibanaServerUrl + API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY, + JSON.stringify({ + ...projectMonitors, + keep_stale: false, + monitors: [], + }), + { + Authorization: + 'Basic ' + Buffer.from(`${username}:${password}`, 'binary').toString('base64'), + } + ); + + expect(messages).to.have.length(3); + expect( + messages.filter((msg) => msg === `Monitor ${testMonitors[1].id} could not be deleted`) + ).to.have.length(1); + expect( + messages.filter((msg) => msg === `Monitor ${testMonitors[0].id} deleted successfully`) + ).to.have.length(1); + expect(messages[2]).to.eql({ + createdMonitors: [], + updatedMonitors: [], + staleMonitors: [], + deletedMonitors: [testMonitors[0].id], + failedMonitors: [], + failedStaleMonitors: [ + { + details: + 'Unable to delete Synthetics package policy for monitor check if title is present. Fleet write permissions are needed to use Synthetics private locations.', + id: 'test-id-2', + reason: 'Failed to delete stale monitor', + }, + ], + }); + + const messages2 = await parseStreamApiResponse( + kibanaServerUrl + API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY, + JSON.stringify({ + ...projectMonitors, + keep_stale: false, + monitors: [], + }) + ); + + expect(messages2).to.have.length(2); + expect(messages2[0]).to.eql(`Monitor ${testMonitors[1].id} deleted successfully`); + expect(messages2[1]).to.eql({ + createdMonitors: [], + updatedMonitors: [], + staleMonitors: [], + deletedMonitors: [testMonitors[1].id], + failedMonitors: [], + failedStaleMonitors: [], + }); + } finally { + await Promise.all([ + testMonitors.map((monitor) => { + return deleteMonitor( + monitor.id, + projectMonitors.project, + 'default', + username, + password + ); + }), + ]); + await security.user.delete(username); + await security.role.delete(roleName); + } + }); + + it('project monitors - returns a successful monitor when user defines a private location with fleet permissions', async () => { + const secondMonitor = { + ...projectMonitors.monitors[0], + id: 'test-id-2', + privateLocations: ['Test private location 0'], + }; + const testMonitors = [projectMonitors.monitors[0], secondMonitor]; + const username = 'admin'; + const roleName = 'uptime with fleet'; + const password = `${username}-password`; + try { + await security.role.create(roleName, { + kibana: [ + { + feature: { + uptime: ['all'], + fleetv2: ['all'], + fleet: ['all'], + }, + spaces: ['*'], + }, + ], + }); + await security.user.create(username, { + password, + roles: [roleName], + full_name: 'a kibana user', + }); + const messages = await parseStreamApiResponse( + projectMonitorEndpoint, + JSON.stringify({ + ...projectMonitors, + keep_stale: false, + monitors: testMonitors, + }) + ); + expect(messages).to.have.length(2); + expect(messages).to.eql([ + `2 monitors created successfully.`, + { + createdMonitors: [testMonitors[0].id, 'test-id-2'], + updatedMonitors: [], + staleMonitors: [], + deletedMonitors: [], + failedMonitors: [], + failedStaleMonitors: [], + }, + ]); + } finally { + await Promise.all([ + testMonitors.map((monitor) => { + return deleteMonitor( + monitor.id, + projectMonitors.project, + 'default', + username, + password + ); + }), + ]); + await security.user.delete(username); + await security.role.delete(roleName); + } + }); + + it('creates integration policies for project monitors with private locations', async () => { + try { + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .set('kbn-xsrf', 'true') + .send({ + ...projectMonitors, + monitors: [ + { ...projectMonitors.monitors[0], privateLocations: ['Test private location 0'] }, + ], + }); + + const monitorsResponse = await supertest + .get(API_URLS.SYNTHETICS_MONITORS) + .query({ + filter: `${syntheticsMonitorType}.attributes.journey_id: ${projectMonitors.monitors[0].id}`, + }) + .set('kbn-xsrf', 'true') + .expect(200); + + const apiResponsePolicy = await supertest.get( + '/api/fleet/package_policies?page=1&perPage=2000&kuery=ingest-package-policies.package.name%3A%20synthetics' + ); + + const packagePolicy = apiResponsePolicy.body.items.find( + (pkgPolicy: PackagePolicy) => + pkgPolicy.id === + `${ + monitorsResponse.body.monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID] + }-${testPolicyId}` + ); + expect(packagePolicy.name).eql( + `${projectMonitors.monitors[0].id}-${projectMonitors.project}-default-Test private location 0` + ); + expect(packagePolicy.policy_id).eql(testPolicyId); + + const configId = monitorsResponse.body.monitors[0].id; + const id = monitorsResponse.body.monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID]; + + comparePolicies( + packagePolicy, + getTestProjectSyntheticsPolicy({ + inputs: {}, + name: 'check if title is present-Test private location 0', + id, + configId, + }) + ); + } finally { + await deleteMonitor(projectMonitors.monitors[0].id, projectMonitors.project); + + const packagesResponse = await supertest.get( + '/api/fleet/package_policies?page=1&perPage=2000&kuery=ingest-package-policies.package.name%3A%20synthetics' + ); + expect(packagesResponse.body.items.length).eql(0); + } + }); + + it('deletes integration policies for project monitors when private location is removed from the monitor - lightweight', async () => { + const monitorRequest = { + ...httpProjectMonitors, + monitors: [ + { ...httpProjectMonitors.monitors[1], privateLocations: ['Test private location 0'] }, + ], + }; + try { + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .set('kbn-xsrf', 'true') + .send(monitorRequest); + + const monitorsResponse = await supertest + .get(API_URLS.SYNTHETICS_MONITORS) + .query({ + filter: `${syntheticsMonitorType}.attributes.journey_id: ${monitorRequest.monitors[0].id}`, + }) + .set('kbn-xsrf', 'true') + .expect(200); + + const apiResponsePolicy = await supertest.get( + '/api/fleet/package_policies?page=1&perPage=2000&kuery=ingest-package-policies.package.name%3A%20synthetics' + ); + + const packagePolicy = apiResponsePolicy.body.items.find( + (pkgPolicy: PackagePolicy) => + pkgPolicy.id === + `${ + monitorsResponse.body.monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID] + }-${testPolicyId}` + ); + + expect(packagePolicy.policy_id).eql(testPolicyId); + + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .set('kbn-xsrf', 'true') + .send({ + ...monitorRequest, + monitors: [{ ...monitorRequest.monitors[0], privateLocations: [] }], + }); + + const apiResponsePolicy2 = await supertest.get( + '/api/fleet/package_policies?page=1&perPage=2000&kuery=ingest-package-policies.package.name%3A%20synthetics' + ); + + const packagePolicy2 = apiResponsePolicy2.body.items.find( + (pkgPolicy: PackagePolicy) => + pkgPolicy.id === + `${ + monitorsResponse.body.monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID] + }-${testPolicyId}` + ); + + expect(packagePolicy2).eql(undefined); + } finally { + await deleteMonitor(projectMonitors.monitors[0].id, projectMonitors.project); + } + }); + + it('deletes integration policies for project monitors when private location is removed from the monitor', async () => { + try { + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .set('kbn-xsrf', 'true') + .send({ + ...projectMonitors, + monitors: [ + { ...projectMonitors.monitors[0], privateLocations: ['Test private location 0'] }, + ], + }); + + const monitorsResponse = await supertest + .get(API_URLS.SYNTHETICS_MONITORS) + .query({ + filter: `${syntheticsMonitorType}.attributes.journey_id: ${projectMonitors.monitors[0].id}`, + }) + .set('kbn-xsrf', 'true') + .expect(200); + + const apiResponsePolicy = await supertest.get( + '/api/fleet/package_policies?page=1&perPage=2000&kuery=ingest-package-policies.package.name%3A%20synthetics' + ); + + const packagePolicy = apiResponsePolicy.body.items.find( + (pkgPolicy: PackagePolicy) => + pkgPolicy.id === + `${ + monitorsResponse.body.monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID] + }-${testPolicyId}` + ); + + expect(packagePolicy.policy_id).eql(testPolicyId); + + const configId = monitorsResponse.body.monitors[0].id; + const id = monitorsResponse.body.monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID]; + + comparePolicies( + packagePolicy, + getTestProjectSyntheticsPolicy({ + inputs: {}, + name: 'check if title is present-Test private location 0', + id, + configId, + }) + ); + + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .set('kbn-xsrf', 'true') + .send({ + ...projectMonitors, + monitors: [{ ...projectMonitors.monitors[0], privateLocations: [] }], + }); + + const apiResponsePolicy2 = await supertest.get( + '/api/fleet/package_policies?page=1&perPage=2000&kuery=ingest-package-policies.package.name%3A%20synthetics' + ); + + const packagePolicy2 = apiResponsePolicy2.body.items.find( + (pkgPolicy: PackagePolicy) => + pkgPolicy.id === + `${ + monitorsResponse.body.monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID] + }-${testPolicyId}` + ); + + expect(packagePolicy2).eql(undefined); + } finally { + await deleteMonitor(projectMonitors.monitors[0].id, projectMonitors.project); + + const apiResponsePolicy2 = await supertest.get( + '/api/fleet/package_policies?page=1&perPage=2000&kuery=ingest-package-policies.package.name%3A%20synthetics' + ); + expect(apiResponsePolicy2.body.items.length).eql(0); + } + }); + + it('deletes integration policies when project monitors are deleted', async () => { + try { + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .set('kbn-xsrf', 'true') + .send({ + ...projectMonitors, + monitors: [ + { ...projectMonitors.monitors[0], privateLocations: ['Test private location 0'] }, + ], + }) + .expect(200); + + const monitorsResponse = await supertest + .get(API_URLS.SYNTHETICS_MONITORS) + .query({ + filter: `${syntheticsMonitorType}.attributes.journey_id: ${projectMonitors.monitors[0].id}`, + }) + .set('kbn-xsrf', 'true') + .expect(200); + + const apiResponsePolicy = await supertest.get( + '/api/fleet/package_policies?page=1&perPage=2000&kuery=ingest-package-policies.package.name%3A%20synthetics' + ); + + const packagePolicy = apiResponsePolicy.body.items.find( + (pkgPolicy: PackagePolicy) => + pkgPolicy.id === + monitorsResponse.body.monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID] + + '-' + + testPolicyId + ); + + expect(packagePolicy.policy_id).eql(testPolicyId); + + const configId = monitorsResponse.body.monitors[0].id; + const id = monitorsResponse.body.monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID]; + + comparePolicies( + packagePolicy, + getTestProjectSyntheticsPolicy({ + inputs: {}, + name: 'check if title is present-Test private location 0', + id, + configId, + }) + ); + + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .set('kbn-xsrf', 'true') + .send({ + ...projectMonitors, + monitors: [], + keep_stale: false, + }); + + const monitorsResponse2 = await supertest + .get(API_URLS.SYNTHETICS_MONITORS) + .query({ + filter: `${syntheticsMonitorType}.attributes.journey_id: ${projectMonitors.monitors[0].id}`, + }) + .set('kbn-xsrf', 'true') + .expect(200); + + expect(monitorsResponse2.body.monitors.length).eql(0); + + await new Promise((resolve) => { + setTimeout(() => resolve(null), 3000); + }); + + const apiResponsePolicy2 = await supertest.get( + '/api/fleet/package_policies?page=1&perPage=2000&kuery=ingest-package-policies.package.name%3A%20synthetics' + ); + + const packagePolicy2 = apiResponsePolicy2.body.items.find( + (pkgPolicy: PackagePolicy) => + pkgPolicy.id === + monitorsResponse.body.monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID] + + '-' + + testPolicyId + ); + + expect(packagePolicy2).eql(undefined); + } finally { + await deleteMonitor(projectMonitors.monitors[0].id, projectMonitors.project); + + const apiResponsePolicy2 = await supertest.get( + '/api/fleet/package_policies?page=1&perPage=2000&kuery=ingest-package-policies.package.name%3A%20synthetics' + ); + expect(apiResponsePolicy2.body.items.length).eql(0); + } + }); + + it('deletes integration policies when project monitors are deleted - lightweight', async () => { + const monitorRequest = { + ...httpProjectMonitors, + monitors: [ + { ...httpProjectMonitors.monitors[1], privateLocations: ['Test private location 0'] }, + ], + }; + try { + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .set('kbn-xsrf', 'true') + .send(monitorRequest); + + const monitorsResponse = await supertest + .get(API_URLS.SYNTHETICS_MONITORS) + .query({ + filter: `${syntheticsMonitorType}.attributes.journey_id: ${monitorRequest.monitors[0].id}`, + }) + .set('kbn-xsrf', 'true') + .expect(200); + + const apiResponsePolicy = await supertest.get( + '/api/fleet/package_policies?page=1&perPage=2000&kuery=ingest-package-policies.package.name%3A%20synthetics' + ); + + const packagePolicy = apiResponsePolicy.body.items.find( + (pkgPolicy: PackagePolicy) => + pkgPolicy.id === + `${ + monitorsResponse.body.monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID] + }-${testPolicyId}` + ); + + expect(packagePolicy.policy_id).eql(testPolicyId); + + const configId = monitorsResponse.body.monitors[0].id; + const id = monitorsResponse.body.monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID]; + + const httpInput = packagePolicy.inputs.find( + (input: any) => input.type === 'synthetics/http' + ); + expect(httpInput).to.eql({ + type: 'synthetics/http', + policy_template: 'synthetics', + enabled: true, + streams: [ + { + enabled: true, + data_stream: { type: 'synthetics', dataset: 'http' }, + release: 'experimental', + vars: { + __ui: { value: '{"is_tls_enabled":false}', type: 'yaml' }, + enabled: { value: false, type: 'bool' }, + type: { value: 'http', type: 'text' }, + name: { value: 'My Monitor 3', type: 'text' }, + schedule: { value: '"@every 60m"', type: 'text' }, + urls: { value: 'http://localhost:9200', type: 'text' }, + 'service.name': { value: '', type: 'text' }, + timeout: { value: '80s', type: 'text' }, + max_redirects: { value: '0', type: 'integer' }, + proxy_url: { value: '', type: 'text' }, + tags: { value: '["tag2","tag2"]', type: 'yaml' }, + username: { value: '', type: 'text' }, + password: { value: '', type: 'password' }, + 'response.include_headers': { value: false, type: 'bool' }, + 'response.include_body': { value: 'always', type: 'text' }, + 'check.request.method': { value: 'POST', type: 'text' }, + 'check.request.headers': { + value: '{"Content-Type":"application/x-www-form-urlencoded"}', + type: 'yaml', + }, + 'check.request.body': { value: null, type: 'yaml' }, + 'check.response.status': { value: '["200"]', type: 'yaml' }, + 'check.response.headers': { value: null, type: 'yaml' }, + 'check.response.body.positive': { value: '["Saved","saved"]', type: 'yaml' }, + 'check.response.body.negative': { value: null, type: 'yaml' }, + 'ssl.certificate_authorities': { value: null, type: 'yaml' }, + 'ssl.certificate': { value: null, type: 'yaml' }, + 'ssl.key': { value: null, type: 'yaml' }, + 'ssl.key_passphrase': { value: null, type: 'text' }, + 'ssl.verification_mode': { value: 'full', type: 'text' }, + 'ssl.supported_protocols': { + value: '["TLSv1.1","TLSv1.2","TLSv1.3"]', + type: 'yaml', + }, + location_name: { value: 'Test private location 0', type: 'text' }, + id: { + value: id, + type: 'text', + }, + config_id: { value: configId, type: 'text' }, + run_once: { value: false, type: 'bool' }, + origin: { value: 'project', type: 'text' }, + 'monitor.project.id': { + type: 'text', + value: 'test-suite', + }, + 'monitor.project.name': { + type: 'text', + value: 'test-suite', + }, + }, + id: `synthetics/http-http-${id}-${testPolicyId}`, + compiled_stream: { + __ui: { is_tls_enabled: false }, + type: 'http', + name: 'My Monitor 3', + id, + origin: 'project', + enabled: false, + urls: 'http://localhost:9200', + schedule: '@every 60m', + timeout: '80s', + max_redirects: 0, + tags: ['tag2', 'tag2'], + 'response.include_headers': false, + 'response.include_body': 'always', + 'check.request.method': 'POST', + 'check.request.headers': { 'Content-Type': 'application/x-www-form-urlencoded' }, + 'check.response.status': ['200'], + 'check.response.body.positive': ['Saved', 'saved'], + 'ssl.verification_mode': 'full', + 'ssl.supported_protocols': ['TLSv1.1', 'TLSv1.2', 'TLSv1.3'], + processors: [ + { add_observer_metadata: { geo: { name: 'Test private location 0' } } }, + { + add_fields: { + target: '', + fields: { + 'monitor.fleet_managed': true, + config_id: configId, + 'monitor.project.id': 'test-suite', + 'monitor.project.name': 'test-suite', + }, + }, + }, + ], + }, + }, + ], + }); + + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .set('kbn-xsrf', 'true') + .send({ + ...monitorRequest, + monitors: [], + }); + + const apiResponsePolicy2 = await supertest.get( + '/api/fleet/package_policies?page=1&perPage=2000&kuery=ingest-package-policies.package.name%3A%20synthetics' + ); + + const packagePolicy2 = apiResponsePolicy2.body.items.find( + (pkgPolicy: PackagePolicy) => + pkgPolicy.id === + `${ + monitorsResponse.body.monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID] + } - ${testPolicyId}` + ); + + expect(packagePolicy2).eql(undefined); + } finally { + await deleteMonitor(httpProjectMonitors.monitors[1].id, httpProjectMonitors.project); + + const apiResponsePolicy2 = await supertest.get( + '/api/fleet/package_policies?page=1&perPage=2000&kuery=ingest-package-policies.package.name%3A%20synthetics' + ); + expect(apiResponsePolicy2.body.items.length).eql(0); + } + }); + + it('handles updating package policies when project monitors are updated', async () => { + try { + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .set('kbn-xsrf', 'true') + .send({ + ...projectMonitors, + monitors: [ + { + ...projectMonitors.monitors[0], + privateLocations: ['Test private location 0'], + }, + ], + }); + + const monitorsResponse = await supertest + .get(API_URLS.SYNTHETICS_MONITORS) + .query({ + filter: `${syntheticsMonitorType}.attributes.journey_id: ${projectMonitors.monitors[0].id}`, + }) + .set('kbn-xsrf', 'true') + .expect(200); + + const apiResponsePolicy = await supertest.get( + '/api/fleet/package_policies?page=1&perPage=2000&kuery=ingest-package-policies.package.name%3A%20synthetics' + ); + + const configId = monitorsResponse.body.monitors[0].id; + const id = monitorsResponse.body.monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID]; + const policyId = `${id}-${testPolicyId}`; + + const packagePolicy = apiResponsePolicy.body.items.find( + (pkgPolicy: PackagePolicy) => pkgPolicy.id === policyId + ); + + expect(packagePolicy.policy_id).eql(testPolicyId); + + comparePolicies( + packagePolicy, + getTestProjectSyntheticsPolicy({ + inputs: {}, + name: 'check if title is present-Test private location 0', + id, + configId, + }) + ); + + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .set('kbn-xsrf', 'true') + .send({ + ...projectMonitors, + monitors: [ + { + ...projectMonitors.monitors[0], + privateLocations: ['Test private location 0'], + enabled: false, + }, + ], + }); + + const apiResponsePolicy2 = await supertest.get( + '/api/fleet/package_policies?page=1&perPage=2000&kuery=ingest-package-policies.package.name%3A%20synthetics' + ); + + const configId2 = monitorsResponse.body.monitors[0].id; + const id2 = monitorsResponse.body.monitors[0].attributes[ConfigKey.CUSTOM_HEARTBEAT_ID]; + const policyId2 = `${id}-${testPolicyId}`; + + const packagePolicy2 = apiResponsePolicy2.body.items.find( + (pkgPolicy: PackagePolicy) => pkgPolicy.id === policyId2 + ); + + comparePolicies( + packagePolicy2, + getTestProjectSyntheticsPolicy({ + inputs: { enabled: { value: false, type: 'bool' } }, + name: 'check if title is present-Test private location 0', + id: id2, + configId: configId2, + }) + ); + } finally { + await deleteMonitor(projectMonitors.monitors[0].id, projectMonitors.project); + + const apiResponsePolicy2 = await supertest.get( + '/api/fleet/package_policies?page=1&perPage=2000&kuery=ingest-package-policies.package.name%3A%20synthetics' + ); + expect(apiResponsePolicy2.body.items.length).eql(0); + } + }); + + it('handles location formatting for both private and public locations', async () => { + try { + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY) + .set('kbn-xsrf', 'true') + .send({ + ...projectMonitors, + monitors: [ + { ...projectMonitors.monitors[0], privateLocations: ['Test private location 0'] }, + ], + }); + + const updatedMonitorsResponse = await Promise.all( + projectMonitors.monitors.map((monitor) => { + return supertest + .get(API_URLS.SYNTHETICS_MONITORS) + .query({ filter: `${syntheticsMonitorType}.attributes.journey_id: ${monitor.id}` }) + .set('kbn-xsrf', 'true') + .expect(200); + }) + ); + + updatedMonitorsResponse.forEach((response) => { + expect(response.body.monitors[0].attributes.locations).eql([ + { + id: 'localhost', + label: 'Local Synthetics Service', + geo: { lat: 0, lon: 0 }, + url: 'mockDevUrl', + isServiceManaged: true, + status: 'experimental', + isInvalid: false, + }, + { + label: 'Test private location 0', + isServiceManaged: false, + isInvalid: false, + agentPolicyId: testPolicyId, + id: testPolicyId, + geo: { + lat: '', + lon: '', + }, + concurrentMonitors: 1, + }, + ]); + }); + } finally { + await Promise.all([ + projectMonitors.monitors.map((monitor) => { + return deleteMonitor(monitor.id, projectMonitors.project); + }), + ]); + } + }); + }); +} + +/** + * Borrowed from AIOPS test code: https://github.com/elastic/kibana/blob/23a7ac2c2e2b1f64daa17b914e86989b1fde750c/x-pack/test/api_integration/apis/aiops/explain_log_rate_spikes.ts + * Receives a stream and parses the messages until the stream closes. + */ +async function* parseStream(stream: NodeJS.ReadableStream) { + let partial = ''; + + try { + for await (const value of stream) { + const full = `${partial}${value}`; + const parts = full.split('\n'); + const last = parts.pop(); + + partial = last ?? ''; + + const event = parts.map((p) => JSON.parse(p)); + + for (const events of event) { + yield events; + } + } + } catch (error) { + yield { type: 'error', payload: error.toString() }; + } +} + +/** + * Helper function to process the results of the module's stream parsing helper function. + */ +async function getMessages(stream: NodeJS.ReadableStream | null) { + if (stream === null) return []; + const data: any[] = []; + for await (const action of parseStream(stream)) { + data.push(action); + } + return data; +} + +/** + * This type is intended to highlight any break between shared parameter contracts defined in + * the module's streaming endpoint helper functions. + */ +type StreamApiFunction = ( + url: string, + body?: BodyInit, + extraHeaders?: HeadersInit, + method?: string +) => T; + +/** + * This helps the test file have DRY code when it comes to calling + * the same streaming endpoint over and over by defining some selective defaults. + */ +export const parseStreamApiResponse: StreamApiFunction> = async ( + url: string, + body?: BodyInit, + extraHeaders?: HeadersInit, + method = 'PUT' +) => { + const streamResponse = await callStreamApi(url, body, extraHeaders, method); + return getMessages(streamResponse.body); +}; + +/** + * This helps the test file have DRY code when it comes to calling + * the same streaming endpoint over and over by defining some selective defaults. + */ +const callStreamApi: StreamApiFunction> = async ( + url: string, + body?: BodyInit, + extraHeaders?: HeadersInit, + method = 'PUT' +) => { + return fetch(url, { + method, + headers: { + 'Content-Type': 'application/json', + 'kbn-xsrf': 'stream', + ...extraHeaders, + }, + body, + }); +}; diff --git a/x-pack/test/api_integration/apis/synthetics/delete_monitor_project.ts b/x-pack/test/api_integration/apis/synthetics/delete_monitor_project.ts index ea8e295afacfe..8024cd74a34c2 100644 --- a/x-pack/test/api_integration/apis/synthetics/delete_monitor_project.ts +++ b/x-pack/test/api_integration/apis/synthetics/delete_monitor_project.ts @@ -16,7 +16,7 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; import { getFixtureJson } from '../uptime/rest/helper/get_fixture_json'; import { PrivateLocationTestService } from './services/private_location_test_service'; -import { parseStreamApiResponse } from './add_monitor_project'; +import { parseStreamApiResponse } from './add_monitor_project_legacy'; export default function ({ getService }: FtrProviderContext) { describe('DeleteProjectMonitors', function () { @@ -92,7 +92,7 @@ export default function ({ getService }: FtrProviderContext) { const monitorsToDelete = monitors.map((monitor) => monitor.id); const response = await supertest - .delete(API_URLS.SYNTHETICS_MONITORS_PROJECT.replace('{projectName}', project)) + .delete(API_URLS.SYNTHETICS_MONITORS_PROJECT_DELETE.replace('{projectName}', project)) .set('kbn-xsrf', 'true') .send({ monitors: monitorsToDelete }) .expect(400); @@ -144,7 +144,7 @@ export default function ({ getService }: FtrProviderContext) { const monitorsToDelete = [monitorToDelete]; const response = await supertest - .delete(API_URLS.SYNTHETICS_MONITORS_PROJECT.replace('{projectName}', project)) + .delete(API_URLS.SYNTHETICS_MONITORS_PROJECT_DELETE.replace('{projectName}', project)) .set('kbn-xsrf', 'true') .send({ monitors: monitorsToDelete }) .expect(200); @@ -218,7 +218,7 @@ export default function ({ getService }: FtrProviderContext) { const monitorsToDelete = monitors.map((monitor) => monitor.id); const response = await supertest - .delete(API_URLS.SYNTHETICS_MONITORS_PROJECT.replace('{projectName}', project)) + .delete(API_URLS.SYNTHETICS_MONITORS_PROJECT_DELETE.replace('{projectName}', project)) .set('kbn-xsrf', 'true') .send({ monitors: monitorsToDelete }) .expect(200); @@ -315,7 +315,7 @@ export default function ({ getService }: FtrProviderContext) { const response = await supertest .delete( - `/s/${SPACE_ID}${API_URLS.SYNTHETICS_MONITORS_PROJECT.replace( + `/s/${SPACE_ID}${API_URLS.SYNTHETICS_MONITORS_PROJECT_DELETE.replace( '{projectName}', project )}` @@ -407,7 +407,7 @@ export default function ({ getService }: FtrProviderContext) { const monitorsToDelete = monitors.map((monitor) => monitor.id); const response = await supertest - .delete(API_URLS.SYNTHETICS_MONITORS_PROJECT.replace('{projectName}', project)) + .delete(API_URLS.SYNTHETICS_MONITORS_PROJECT_DELETE.replace('{projectName}', project)) .set('kbn-xsrf', 'true') .send({ monitors: monitorsToDelete }) .expect(200); @@ -500,7 +500,7 @@ export default function ({ getService }: FtrProviderContext) { const { body: { message }, } = await supertestWithoutAuth - .delete(API_URLS.SYNTHETICS_MONITORS_PROJECT.replace('{projectName}', project)) + .delete(API_URLS.SYNTHETICS_MONITORS_PROJECT_DELETE.replace('{projectName}', project)) .set('kbn-xsrf', 'true') .auth(username, password) .send({ monitors: monitorsToDelete }) diff --git a/x-pack/test/api_integration/apis/synthetics/get_monitor_project.ts b/x-pack/test/api_integration/apis/synthetics/get_monitor_project.ts index 734d10f6355ee..dd2c71913c625 100644 --- a/x-pack/test/api_integration/apis/synthetics/get_monitor_project.ts +++ b/x-pack/test/api_integration/apis/synthetics/get_monitor_project.ts @@ -8,7 +8,7 @@ import uuid from 'uuid'; import type SuperTest from 'supertest'; import { format as formatUrl } from 'url'; import { - ProjectMonitorsRequest, + LegacyProjectMonitorsRequest, ProjectMonitor, ProjectMonitorMetaData, } from '@kbn/synthetics-plugin/common/runtime_types'; @@ -17,7 +17,7 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; import { getFixtureJson } from '../uptime/rest/helper/get_fixture_json'; import { PrivateLocationTestService } from './services/private_location_test_service'; -import { parseStreamApiResponse } from './add_monitor_project'; +import { parseStreamApiResponse } from './add_monitor_project_legacy'; export default function ({ getService }: FtrProviderContext) { describe('GetProjectMonitors', function () { @@ -28,15 +28,15 @@ export default function ({ getService }: FtrProviderContext) { const kibanaServerUrl = formatUrl(config.get('servers.kibana')); const projectMonitorEndpoint = kibanaServerUrl + API_URLS.SYNTHETICS_MONITORS_PROJECT_LEGACY; - let projectMonitors: ProjectMonitorsRequest; - let httpProjectMonitors: ProjectMonitorsRequest; - let tcpProjectMonitors: ProjectMonitorsRequest; - let icmpProjectMonitors: ProjectMonitorsRequest; + let projectMonitors: LegacyProjectMonitorsRequest; + let httpProjectMonitors: LegacyProjectMonitorsRequest; + let tcpProjectMonitors: LegacyProjectMonitorsRequest; + let icmpProjectMonitors: LegacyProjectMonitorsRequest; let testPolicyId = ''; const testPrivateLocations = new PrivateLocationTestService(getService); - const setUniqueIds = (request: ProjectMonitorsRequest) => { + const setUniqueIds = (request: LegacyProjectMonitorsRequest) => { return { ...request, monitors: request.monitors.map((monitor) => ({ ...monitor, id: uuid.v4() })), diff --git a/x-pack/test/api_integration/apis/synthetics/index.ts b/x-pack/test/api_integration/apis/synthetics/index.ts index 937d714a6a96f..763afc371b045 100644 --- a/x-pack/test/api_integration/apis/synthetics/index.ts +++ b/x-pack/test/api_integration/apis/synthetics/index.ts @@ -19,6 +19,7 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./get_monitor')); loadTestFile(require.resolve('./get_monitor_overview')); loadTestFile(require.resolve('./add_monitor')); + loadTestFile(require.resolve('./add_monitor_project_legacy')); loadTestFile(require.resolve('./add_monitor_project')); loadTestFile(require.resolve('./get_monitor_project')); loadTestFile(require.resolve('./add_monitor_private_location')); diff --git a/x-pack/test/api_integration/apis/uptime/rest/sample_data/test_policy.ts b/x-pack/test/api_integration/apis/uptime/rest/sample_data/test_policy.ts index 05bba2286e004..26418137fc23e 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/sample_data/test_policy.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/sample_data/test_policy.ts @@ -302,11 +302,13 @@ export const getTestProjectSyntheticsPolicy = ( inputs = {}, configId, id, + projectId = 'test-suite', }: { name?: string; inputs: Record; configId: string; id: string; + projectId?: string; } = { name: 'check if title is present-Test private location 0', inputs: {}, @@ -314,9 +316,9 @@ export const getTestProjectSyntheticsPolicy = ( id: '', } ): PackagePolicy => ({ - id: '4b6abc6c-118b-4d93-a489-1135500d09f1-test-suite-default-d70a46e0-22ea-11ed-8c6b-09a2d21dfbc3', + id: `4b6abc6c-118b-4d93-a489-1135500d09f1-${projectId}-default-d70a46e0-22ea-11ed-8c6b-09a2d21dfbc3`, version: 'WzEzMDksMV0=', - name: '4b6abc6c-118b-4d93-a489-1135500d09f1-test-suite-default-Test private location 0', + name: `4b6abc6c-118b-4d93-a489-1135500d09f1-${projectId}-default-Test private location 0`, namespace: 'default', package: { name: 'synthetics', title: 'Elastic Synthetics', version: '0.10.3' }, enabled: true, @@ -368,7 +370,7 @@ export const getTestProjectSyntheticsPolicy = ( 'monitor.project.id': { type: 'text' }, 'monitor.project.name': { type: 'text' }, }, - id: 'synthetics/http-http-4b6abc6c-118b-4d93-a489-1135500d09f1-test-suite-default-d70a46e0-22ea-11ed-8c6b-09a2d21dfbc3', + id: `synthetics/http-http-4b6abc6c-118b-4d93-a489-1135500d09f1-${projectId}-default-d70a46e0-22ea-11ed-8c6b-09a2d21dfbc3`, }, ], }, @@ -409,7 +411,7 @@ export const getTestProjectSyntheticsPolicy = ( 'monitor.project.id': { type: 'text' }, 'monitor.project.name': { type: 'text' }, }, - id: 'synthetics/tcp-tcp-4b6abc6c-118b-4d93-a489-1135500d09f1-test-suite-default-d70a46e0-22ea-11ed-8c6b-09a2d21dfbc3', + id: `synthetics/tcp-tcp-4b6abc6c-118b-4d93-a489-1135500d09f1-${projectId}-default-d70a46e0-22ea-11ed-8c6b-09a2d21dfbc3`, }, ], }, @@ -441,7 +443,7 @@ export const getTestProjectSyntheticsPolicy = ( 'monitor.project.id': { type: 'text' }, 'monitor.project.name': { type: 'text' }, }, - id: 'synthetics/icmp-icmp-4b6abc6c-118b-4d93-a489-1135500d09f1-test-suite-default-d70a46e0-22ea-11ed-8c6b-09a2d21dfbc3', + id: `synthetics/icmp-icmp-4b6abc6c-118b-4d93-a489-1135500d09f1-${projectId}-default-d70a46e0-22ea-11ed-8c6b-09a2d21dfbc3`, }, ], }, @@ -500,11 +502,11 @@ export const getTestProjectSyntheticsPolicy = ( config_id: { value: configId, type: 'text' }, run_once: { value: false, type: 'bool' }, origin: { value: 'project', type: 'text' }, - 'monitor.project.id': { value: 'test-suite', type: 'text' }, - 'monitor.project.name': { value: 'test-suite', type: 'text' }, + 'monitor.project.id': { value: projectId, type: 'text' }, + 'monitor.project.name': { value: projectId, type: 'text' }, ...inputs, }, - id: 'synthetics/browser-browser-4b6abc6c-118b-4d93-a489-1135500d09f1-test-suite-default-d70a46e0-22ea-11ed-8c6b-09a2d21dfbc3', + id: `synthetics/browser-browser-4b6abc6c-118b-4d93-a489-1135500d09f1-${projectId}-default-d70a46e0-22ea-11ed-8c6b-09a2d21dfbc3`, compiled_stream: { __ui: { script_source: { is_generated_script: false, file_name: '' }, @@ -531,8 +533,8 @@ export const getTestProjectSyntheticsPolicy = ( fields: { 'monitor.fleet_managed': true, config_id: configId, - 'monitor.project.name': 'test-suite', - 'monitor.project.id': 'test-suite', + 'monitor.project.name': projectId, + 'monitor.project.id': projectId, }, }, }, @@ -547,7 +549,7 @@ export const getTestProjectSyntheticsPolicy = ( enabled: true, release: 'beta', data_stream: { type: 'synthetics', dataset: 'browser.network' }, - id: 'synthetics/browser-browser.network-4b6abc6c-118b-4d93-a489-1135500d09f1-test-suite-default-d70a46e0-22ea-11ed-8c6b-09a2d21dfbc3', + id: `synthetics/browser-browser.network-4b6abc6c-118b-4d93-a489-1135500d09f1-${projectId}-default-d70a46e0-22ea-11ed-8c6b-09a2d21dfbc3`, compiled_stream: { processors: [ { add_observer_metadata: { geo: { name: 'Fleet managed' } } }, @@ -559,7 +561,7 @@ export const getTestProjectSyntheticsPolicy = ( enabled: true, release: 'beta', data_stream: { type: 'synthetics', dataset: 'browser.screenshot' }, - id: 'synthetics/browser-browser.screenshot-4b6abc6c-118b-4d93-a489-1135500d09f1-test-suite-default-d70a46e0-22ea-11ed-8c6b-09a2d21dfbc3', + id: `synthetics/browser-browser.screenshot-4b6abc6c-118b-4d93-a489-1135500d09f1-${projectId}-default-d70a46e0-22ea-11ed-8c6b-09a2d21dfbc3`, compiled_stream: { processors: [ { add_observer_metadata: { geo: { name: 'Fleet managed' } } }, From 3dd5c5388e3dfde8c7c33b4233054ef7555cafea Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Fri, 4 Nov 2022 02:27:23 +0000 Subject: [PATCH 03/31] chore(NA): update ci step name to Check Public API Docs (#144573) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .buildkite/pipelines/on_merge.yml | 4 ++-- .../{on_merge_ts_refs_api_docs.sh => on_merge_api_docs.sh} | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename .buildkite/scripts/steps/{on_merge_ts_refs_api_docs.sh => on_merge_api_docs.sh} (100%) diff --git a/.buildkite/pipelines/on_merge.yml b/.buildkite/pipelines/on_merge.yml index 7ea0317b56e70..ffca48499b159 100644 --- a/.buildkite/pipelines/on_merge.yml +++ b/.buildkite/pipelines/on_merge.yml @@ -39,8 +39,8 @@ steps: - exit_status: '*' limit: 1 - - command: .buildkite/scripts/steps/on_merge_ts_refs_api_docs.sh - label: Build TS Refs and Check Public API Docs + - command: .buildkite/scripts/steps/on_merge_api_docs.sh + label: Check Public API Docs key: public-api-docs agents: queue: n2-4-spot diff --git a/.buildkite/scripts/steps/on_merge_ts_refs_api_docs.sh b/.buildkite/scripts/steps/on_merge_api_docs.sh similarity index 100% rename from .buildkite/scripts/steps/on_merge_ts_refs_api_docs.sh rename to .buildkite/scripts/steps/on_merge_api_docs.sh From 6baf409079d8a85133a3d4cb32403500ddfff6e3 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Fri, 4 Nov 2022 00:45:21 -0400 Subject: [PATCH 04/31] [api-docs] Daily api_docs build (#144584) --- api_docs/actions.mdx | 2 +- api_docs/advanced_settings.mdx | 2 +- api_docs/aiops.mdx | 2 +- api_docs/alerting.devdocs.json | 16 +++++ api_docs/alerting.mdx | 4 +- api_docs/apm.mdx | 2 +- api_docs/banners.mdx | 2 +- api_docs/bfetch.mdx | 2 +- api_docs/canvas.mdx | 2 +- api_docs/cases.mdx | 2 +- api_docs/charts.mdx | 2 +- api_docs/cloud.mdx | 2 +- api_docs/cloud_chat.mdx | 2 +- api_docs/cloud_experiments.mdx | 2 +- api_docs/cloud_security_posture.mdx | 2 +- api_docs/console.mdx | 2 +- api_docs/controls.mdx | 2 +- api_docs/core.mdx | 2 +- api_docs/custom_integrations.mdx | 2 +- api_docs/dashboard.mdx | 2 +- api_docs/dashboard_enhanced.mdx | 2 +- api_docs/data.devdocs.json | 8 --- api_docs/data.mdx | 2 +- api_docs/data_query.mdx | 2 +- api_docs/data_search.mdx | 2 +- api_docs/data_view_editor.mdx | 2 +- api_docs/data_view_field_editor.mdx | 2 +- api_docs/data_view_management.mdx | 2 +- api_docs/data_views.devdocs.json | 12 ---- api_docs/data_views.mdx | 2 +- api_docs/data_visualizer.mdx | 2 +- api_docs/deprecations_by_api.mdx | 2 +- api_docs/deprecations_by_plugin.mdx | 8 +-- api_docs/deprecations_by_team.mdx | 2 +- api_docs/dev_tools.mdx | 2 +- api_docs/discover.mdx | 2 +- api_docs/discover_enhanced.mdx | 2 +- api_docs/embeddable.mdx | 2 +- api_docs/embeddable_enhanced.mdx | 2 +- api_docs/encrypted_saved_objects.mdx | 2 +- api_docs/enterprise_search.mdx | 2 +- api_docs/es_ui_shared.mdx | 2 +- api_docs/event_annotation.mdx | 2 +- api_docs/event_log.mdx | 2 +- api_docs/expression_error.mdx | 2 +- api_docs/expression_gauge.mdx | 2 +- api_docs/expression_heatmap.mdx | 2 +- api_docs/expression_image.mdx | 2 +- api_docs/expression_legacy_metric_vis.mdx | 2 +- api_docs/expression_metric.mdx | 2 +- api_docs/expression_metric_vis.devdocs.json | 58 +++++++++++++++ api_docs/expression_metric_vis.mdx | 4 +- .../expression_partition_vis.devdocs.json | 64 +++++++++++++++++ api_docs/expression_partition_vis.mdx | 4 +- api_docs/expression_repeat_image.mdx | 2 +- api_docs/expression_reveal_image.mdx | 2 +- api_docs/expression_shape.mdx | 2 +- api_docs/expression_tagcloud.mdx | 2 +- api_docs/expression_x_y.mdx | 2 +- api_docs/expressions.devdocs.json | 71 ++++++++++++++++++- api_docs/expressions.mdx | 4 +- api_docs/features.mdx | 2 +- api_docs/field_formats.mdx | 2 +- api_docs/file_upload.mdx | 2 +- api_docs/files.devdocs.json | 18 +++++ api_docs/files.mdx | 4 +- api_docs/fleet.devdocs.json | 14 ++++ api_docs/fleet.mdx | 4 +- api_docs/global_search.mdx | 2 +- api_docs/guided_onboarding.mdx | 2 +- api_docs/home.mdx | 2 +- api_docs/index_lifecycle_management.mdx | 2 +- api_docs/index_management.mdx | 2 +- api_docs/infra.mdx | 2 +- api_docs/inspector.mdx | 2 +- api_docs/interactive_setup.mdx | 2 +- api_docs/kbn_ace.mdx | 2 +- api_docs/kbn_aiops_components.mdx | 2 +- api_docs/kbn_aiops_utils.mdx | 2 +- api_docs/kbn_alerts.mdx | 2 +- api_docs/kbn_analytics.mdx | 2 +- api_docs/kbn_analytics_client.mdx | 2 +- ..._analytics_shippers_elastic_v3_browser.mdx | 2 +- ...n_analytics_shippers_elastic_v3_common.mdx | 2 +- ...n_analytics_shippers_elastic_v3_server.mdx | 2 +- api_docs/kbn_analytics_shippers_fullstory.mdx | 2 +- api_docs/kbn_analytics_shippers_gainsight.mdx | 2 +- api_docs/kbn_apm_config_loader.mdx | 2 +- api_docs/kbn_apm_synthtrace.mdx | 2 +- api_docs/kbn_apm_utils.mdx | 2 +- api_docs/kbn_axe_config.mdx | 2 +- api_docs/kbn_cases_components.mdx | 2 +- api_docs/kbn_chart_icons.mdx | 2 +- api_docs/kbn_ci_stats_core.mdx | 2 +- api_docs/kbn_ci_stats_performance_metrics.mdx | 2 +- api_docs/kbn_ci_stats_reporter.mdx | 2 +- api_docs/kbn_cli_dev_mode.mdx | 2 +- api_docs/kbn_coloring.mdx | 2 +- api_docs/kbn_config.mdx | 2 +- api_docs/kbn_config_mocks.mdx | 2 +- api_docs/kbn_config_schema.mdx | 2 +- .../kbn_content_management_table_list.mdx | 2 +- api_docs/kbn_core_analytics_browser.mdx | 2 +- .../kbn_core_analytics_browser_internal.mdx | 2 +- api_docs/kbn_core_analytics_browser_mocks.mdx | 2 +- api_docs/kbn_core_analytics_server.mdx | 2 +- .../kbn_core_analytics_server_internal.mdx | 2 +- api_docs/kbn_core_analytics_server_mocks.mdx | 2 +- api_docs/kbn_core_application_browser.mdx | 2 +- .../kbn_core_application_browser_internal.mdx | 2 +- .../kbn_core_application_browser_mocks.mdx | 2 +- api_docs/kbn_core_application_common.mdx | 2 +- api_docs/kbn_core_apps_browser_internal.mdx | 2 +- api_docs/kbn_core_apps_browser_mocks.mdx | 2 +- api_docs/kbn_core_apps_server_internal.mdx | 2 +- api_docs/kbn_core_base_browser_mocks.mdx | 2 +- api_docs/kbn_core_base_common.mdx | 2 +- api_docs/kbn_core_base_server_internal.mdx | 2 +- api_docs/kbn_core_base_server_mocks.mdx | 2 +- .../kbn_core_capabilities_browser_mocks.mdx | 2 +- api_docs/kbn_core_capabilities_common.mdx | 2 +- api_docs/kbn_core_capabilities_server.mdx | 2 +- .../kbn_core_capabilities_server_mocks.mdx | 2 +- api_docs/kbn_core_chrome_browser.mdx | 2 +- api_docs/kbn_core_chrome_browser_mocks.mdx | 2 +- api_docs/kbn_core_config_server_internal.mdx | 2 +- api_docs/kbn_core_deprecations_browser.mdx | 2 +- ...kbn_core_deprecations_browser_internal.mdx | 2 +- .../kbn_core_deprecations_browser_mocks.mdx | 2 +- api_docs/kbn_core_deprecations_common.mdx | 2 +- api_docs/kbn_core_deprecations_server.mdx | 2 +- .../kbn_core_deprecations_server_internal.mdx | 2 +- .../kbn_core_deprecations_server_mocks.mdx | 2 +- api_docs/kbn_core_doc_links_browser.mdx | 2 +- api_docs/kbn_core_doc_links_browser_mocks.mdx | 2 +- api_docs/kbn_core_doc_links_server.mdx | 2 +- api_docs/kbn_core_doc_links_server_mocks.mdx | 2 +- ...e_elasticsearch_client_server_internal.mdx | 2 +- ...core_elasticsearch_client_server_mocks.mdx | 2 +- api_docs/kbn_core_elasticsearch_server.mdx | 2 +- ...kbn_core_elasticsearch_server_internal.mdx | 2 +- .../kbn_core_elasticsearch_server_mocks.mdx | 2 +- .../kbn_core_environment_server_internal.mdx | 2 +- .../kbn_core_environment_server_mocks.mdx | 2 +- .../kbn_core_execution_context_browser.mdx | 2 +- ...ore_execution_context_browser_internal.mdx | 2 +- ...n_core_execution_context_browser_mocks.mdx | 2 +- .../kbn_core_execution_context_common.mdx | 2 +- .../kbn_core_execution_context_server.mdx | 2 +- ...core_execution_context_server_internal.mdx | 2 +- ...bn_core_execution_context_server_mocks.mdx | 2 +- api_docs/kbn_core_fatal_errors_browser.mdx | 2 +- .../kbn_core_fatal_errors_browser_mocks.mdx | 2 +- api_docs/kbn_core_http_browser.mdx | 2 +- api_docs/kbn_core_http_browser_internal.mdx | 2 +- api_docs/kbn_core_http_browser_mocks.mdx | 2 +- api_docs/kbn_core_http_common.mdx | 2 +- .../kbn_core_http_context_server_mocks.mdx | 2 +- ...re_http_request_handler_context_server.mdx | 2 +- api_docs/kbn_core_http_resources_server.mdx | 2 +- ...bn_core_http_resources_server_internal.mdx | 2 +- .../kbn_core_http_resources_server_mocks.mdx | 2 +- .../kbn_core_http_router_server_internal.mdx | 2 +- .../kbn_core_http_router_server_mocks.mdx | 2 +- api_docs/kbn_core_http_server.mdx | 2 +- api_docs/kbn_core_http_server_internal.mdx | 2 +- api_docs/kbn_core_http_server_mocks.mdx | 2 +- api_docs/kbn_core_i18n_browser.mdx | 2 +- api_docs/kbn_core_i18n_browser_mocks.mdx | 2 +- api_docs/kbn_core_i18n_server.mdx | 2 +- api_docs/kbn_core_i18n_server_internal.mdx | 2 +- api_docs/kbn_core_i18n_server_mocks.mdx | 2 +- .../kbn_core_injected_metadata_browser.mdx | 2 +- ...n_core_injected_metadata_browser_mocks.mdx | 2 +- ...kbn_core_integrations_browser_internal.mdx | 2 +- .../kbn_core_integrations_browser_mocks.mdx | 2 +- api_docs/kbn_core_lifecycle_browser.mdx | 2 +- api_docs/kbn_core_lifecycle_browser_mocks.mdx | 2 +- api_docs/kbn_core_lifecycle_server.mdx | 2 +- api_docs/kbn_core_lifecycle_server_mocks.mdx | 2 +- api_docs/kbn_core_logging_browser_mocks.mdx | 2 +- api_docs/kbn_core_logging_common_internal.mdx | 2 +- api_docs/kbn_core_logging_server.mdx | 2 +- api_docs/kbn_core_logging_server_internal.mdx | 2 +- api_docs/kbn_core_logging_server_mocks.mdx | 2 +- ...ore_metrics_collectors_server_internal.mdx | 2 +- ...n_core_metrics_collectors_server_mocks.mdx | 2 +- api_docs/kbn_core_metrics_server.mdx | 2 +- api_docs/kbn_core_metrics_server_internal.mdx | 2 +- api_docs/kbn_core_metrics_server_mocks.mdx | 2 +- api_docs/kbn_core_mount_utils_browser.mdx | 2 +- api_docs/kbn_core_node_server.mdx | 2 +- api_docs/kbn_core_node_server_internal.mdx | 2 +- api_docs/kbn_core_node_server_mocks.mdx | 2 +- api_docs/kbn_core_notifications_browser.mdx | 2 +- ...bn_core_notifications_browser_internal.mdx | 2 +- .../kbn_core_notifications_browser_mocks.mdx | 2 +- api_docs/kbn_core_overlays_browser.mdx | 2 +- .../kbn_core_overlays_browser_internal.mdx | 2 +- api_docs/kbn_core_overlays_browser_mocks.mdx | 2 +- api_docs/kbn_core_plugins_browser.mdx | 2 +- api_docs/kbn_core_plugins_browser_mocks.mdx | 2 +- api_docs/kbn_core_plugins_server.mdx | 2 +- api_docs/kbn_core_plugins_server_mocks.mdx | 2 +- api_docs/kbn_core_preboot_server.mdx | 2 +- api_docs/kbn_core_preboot_server_mocks.mdx | 2 +- api_docs/kbn_core_rendering_browser_mocks.mdx | 2 +- .../kbn_core_rendering_server_internal.mdx | 2 +- api_docs/kbn_core_rendering_server_mocks.mdx | 2 +- .../kbn_core_saved_objects_api_browser.mdx | 2 +- .../kbn_core_saved_objects_api_server.mdx | 2 +- ...core_saved_objects_api_server_internal.mdx | 2 +- ...bn_core_saved_objects_api_server_mocks.mdx | 2 +- ...ore_saved_objects_base_server_internal.mdx | 2 +- ...n_core_saved_objects_base_server_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_browser.mdx | 2 +- ...bn_core_saved_objects_browser_internal.mdx | 2 +- .../kbn_core_saved_objects_browser_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_common.mdx | 2 +- ..._objects_import_export_server_internal.mdx | 2 +- ...ved_objects_import_export_server_mocks.mdx | 2 +- ...aved_objects_migration_server_internal.mdx | 2 +- ...e_saved_objects_migration_server_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_server.mdx | 2 +- ...kbn_core_saved_objects_server_internal.mdx | 2 +- .../kbn_core_saved_objects_server_mocks.mdx | 2 +- .../kbn_core_saved_objects_utils_server.mdx | 2 +- api_docs/kbn_core_status_common.mdx | 2 +- api_docs/kbn_core_status_common_internal.mdx | 2 +- api_docs/kbn_core_status_server.mdx | 2 +- api_docs/kbn_core_status_server_internal.mdx | 2 +- api_docs/kbn_core_status_server_mocks.mdx | 2 +- ...core_test_helpers_deprecations_getters.mdx | 2 +- ...n_core_test_helpers_http_setup_browser.mdx | 2 +- ...n_core_test_helpers_so_type_serializer.mdx | 2 +- api_docs/kbn_core_test_helpers_test_utils.mdx | 2 +- api_docs/kbn_core_theme_browser.mdx | 2 +- api_docs/kbn_core_theme_browser_internal.mdx | 2 +- api_docs/kbn_core_theme_browser_mocks.mdx | 2 +- api_docs/kbn_core_ui_settings_browser.mdx | 2 +- .../kbn_core_ui_settings_browser_internal.mdx | 2 +- .../kbn_core_ui_settings_browser_mocks.mdx | 2 +- api_docs/kbn_core_ui_settings_common.mdx | 2 +- api_docs/kbn_core_ui_settings_server.mdx | 2 +- .../kbn_core_ui_settings_server_internal.mdx | 2 +- .../kbn_core_ui_settings_server_mocks.mdx | 2 +- api_docs/kbn_core_usage_data_server.mdx | 2 +- .../kbn_core_usage_data_server_internal.mdx | 2 +- api_docs/kbn_core_usage_data_server_mocks.mdx | 2 +- api_docs/kbn_crypto.mdx | 2 +- api_docs/kbn_crypto_browser.mdx | 2 +- api_docs/kbn_datemath.mdx | 2 +- api_docs/kbn_dev_cli_errors.mdx | 2 +- api_docs/kbn_dev_cli_runner.mdx | 2 +- api_docs/kbn_dev_proc_runner.mdx | 2 +- api_docs/kbn_dev_utils.mdx | 2 +- api_docs/kbn_doc_links.mdx | 2 +- api_docs/kbn_docs_utils.mdx | 2 +- api_docs/kbn_ebt_tools.mdx | 2 +- api_docs/kbn_es.mdx | 2 +- api_docs/kbn_es_archiver.mdx | 2 +- api_docs/kbn_es_errors.mdx | 2 +- api_docs/kbn_es_query.mdx | 2 +- api_docs/kbn_es_types.mdx | 2 +- api_docs/kbn_eslint_plugin_imports.mdx | 2 +- api_docs/kbn_field_types.mdx | 2 +- api_docs/kbn_find_used_node_modules.mdx | 2 +- .../kbn_ftr_common_functional_services.mdx | 2 +- api_docs/kbn_generate.mdx | 2 +- api_docs/kbn_get_repo_files.mdx | 2 +- api_docs/kbn_guided_onboarding.mdx | 2 +- api_docs/kbn_handlebars.mdx | 2 +- api_docs/kbn_hapi_mocks.mdx | 2 +- api_docs/kbn_home_sample_data_card.mdx | 2 +- api_docs/kbn_home_sample_data_tab.mdx | 2 +- api_docs/kbn_i18n.mdx | 2 +- api_docs/kbn_i18n_react.mdx | 2 +- api_docs/kbn_import_resolver.mdx | 2 +- api_docs/kbn_interpreter.mdx | 2 +- api_docs/kbn_io_ts_utils.mdx | 2 +- api_docs/kbn_jest_serializers.mdx | 2 +- api_docs/kbn_journeys.mdx | 2 +- api_docs/kbn_kibana_manifest_schema.mdx | 2 +- .../kbn_language_documentation_popover.mdx | 2 +- api_docs/kbn_logging.mdx | 2 +- api_docs/kbn_logging_mocks.mdx | 2 +- api_docs/kbn_managed_vscode_config.mdx | 2 +- api_docs/kbn_mapbox_gl.mdx | 2 +- api_docs/kbn_ml_agg_utils.mdx | 2 +- api_docs/kbn_ml_is_populated_object.mdx | 2 +- api_docs/kbn_ml_string_hash.mdx | 2 +- api_docs/kbn_monaco.mdx | 2 +- api_docs/kbn_optimizer.mdx | 2 +- api_docs/kbn_optimizer_webpack_helpers.mdx | 2 +- api_docs/kbn_osquery_io_ts_types.mdx | 2 +- ..._performance_testing_dataset_extractor.mdx | 2 +- api_docs/kbn_plugin_generator.mdx | 2 +- api_docs/kbn_plugin_helpers.mdx | 2 +- api_docs/kbn_react_field.mdx | 2 +- api_docs/kbn_repo_source_classifier.mdx | 2 +- api_docs/kbn_rule_data_utils.mdx | 2 +- .../kbn_securitysolution_autocomplete.mdx | 2 +- api_docs/kbn_securitysolution_es_utils.mdx | 2 +- ...ritysolution_exception_list_components.mdx | 2 +- api_docs/kbn_securitysolution_hook_utils.mdx | 2 +- ..._securitysolution_io_ts_alerting_types.mdx | 2 +- .../kbn_securitysolution_io_ts_list_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_utils.mdx | 2 +- api_docs/kbn_securitysolution_list_api.mdx | 2 +- .../kbn_securitysolution_list_constants.mdx | 2 +- api_docs/kbn_securitysolution_list_hooks.mdx | 2 +- api_docs/kbn_securitysolution_list_utils.mdx | 2 +- api_docs/kbn_securitysolution_rules.mdx | 2 +- api_docs/kbn_securitysolution_t_grid.mdx | 2 +- api_docs/kbn_securitysolution_utils.mdx | 2 +- api_docs/kbn_server_http_tools.mdx | 2 +- api_docs/kbn_server_route_repository.mdx | 2 +- api_docs/kbn_shared_svg.mdx | 2 +- api_docs/kbn_shared_ux_avatar_solution.mdx | 2 +- ...ared_ux_avatar_user_profile_components.mdx | 2 +- .../kbn_shared_ux_button_exit_full_screen.mdx | 2 +- ...hared_ux_button_exit_full_screen_mocks.mdx | 2 +- api_docs/kbn_shared_ux_button_toolbar.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data_mocks.mdx | 2 +- api_docs/kbn_shared_ux_link_redirect_app.mdx | 2 +- .../kbn_shared_ux_link_redirect_app_mocks.mdx | 2 +- api_docs/kbn_shared_ux_markdown.mdx | 2 +- api_docs/kbn_shared_ux_markdown_mocks.mdx | 2 +- .../kbn_shared_ux_page_analytics_no_data.mdx | 2 +- ...shared_ux_page_analytics_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_no_data.mdx | 2 +- ...bn_shared_ux_page_kibana_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_template.mdx | 2 +- ...n_shared_ux_page_kibana_template_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data.mdx | 2 +- .../kbn_shared_ux_page_no_data_config.mdx | 2 +- ...bn_shared_ux_page_no_data_config_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_solution_nav.mdx | 2 +- .../kbn_shared_ux_prompt_no_data_views.mdx | 2 +- ...n_shared_ux_prompt_no_data_views_mocks.mdx | 2 +- api_docs/kbn_shared_ux_router.mdx | 2 +- api_docs/kbn_shared_ux_router_mocks.mdx | 2 +- api_docs/kbn_shared_ux_storybook_config.mdx | 2 +- api_docs/kbn_shared_ux_storybook_mock.mdx | 2 +- api_docs/kbn_shared_ux_utility.mdx | 2 +- api_docs/kbn_some_dev_log.mdx | 2 +- api_docs/kbn_sort_package_json.mdx | 2 +- api_docs/kbn_std.mdx | 2 +- api_docs/kbn_stdio_dev_helpers.mdx | 2 +- api_docs/kbn_storybook.mdx | 2 +- api_docs/kbn_telemetry_tools.mdx | 2 +- api_docs/kbn_test.mdx | 2 +- api_docs/kbn_test_jest_helpers.mdx | 2 +- api_docs/kbn_test_subj_selector.mdx | 2 +- api_docs/kbn_tooling_log.mdx | 2 +- api_docs/kbn_type_summarizer.mdx | 2 +- api_docs/kbn_type_summarizer_core.mdx | 2 +- api_docs/kbn_typed_react_router_config.mdx | 2 +- api_docs/kbn_ui_shared_deps_src.mdx | 2 +- api_docs/kbn_ui_theme.mdx | 2 +- api_docs/kbn_user_profile_components.mdx | 2 +- api_docs/kbn_utility_types.mdx | 2 +- api_docs/kbn_utility_types_jest.mdx | 2 +- api_docs/kbn_utils.mdx | 2 +- api_docs/kbn_yarn_lock_validator.mdx | 2 +- api_docs/kibana_overview.mdx | 2 +- api_docs/kibana_react.mdx | 2 +- api_docs/kibana_utils.mdx | 2 +- api_docs/kubernetes_security.mdx | 2 +- api_docs/lens.mdx | 2 +- api_docs/license_api_guard.mdx | 2 +- api_docs/license_management.mdx | 2 +- api_docs/licensing.mdx | 2 +- api_docs/lists.mdx | 2 +- api_docs/management.mdx | 2 +- api_docs/maps.mdx | 2 +- api_docs/maps_ems.mdx | 2 +- api_docs/ml.mdx | 2 +- api_docs/monitoring.mdx | 2 +- api_docs/monitoring_collection.mdx | 2 +- api_docs/navigation.mdx | 2 +- api_docs/newsfeed.mdx | 2 +- api_docs/notifications.devdocs.json | 59 +++++++++++++++ api_docs/notifications.mdx | 35 +++++++++ api_docs/observability.mdx | 2 +- api_docs/osquery.devdocs.json | 4 +- api_docs/osquery.mdx | 4 +- api_docs/plugin_directory.mdx | 21 +++--- api_docs/presentation_util.mdx | 2 +- api_docs/profiling.mdx | 2 +- api_docs/remote_clusters.mdx | 2 +- api_docs/reporting.mdx | 2 +- api_docs/rollup.mdx | 2 +- api_docs/rule_registry.mdx | 2 +- api_docs/runtime_fields.mdx | 2 +- api_docs/saved_objects.mdx | 2 +- api_docs/saved_objects_finder.mdx | 2 +- api_docs/saved_objects_management.mdx | 2 +- api_docs/saved_objects_tagging.mdx | 2 +- api_docs/saved_objects_tagging_oss.mdx | 2 +- api_docs/saved_search.mdx | 2 +- api_docs/screenshot_mode.mdx | 2 +- api_docs/screenshotting.mdx | 2 +- api_docs/security.mdx | 2 +- api_docs/security_solution.mdx | 2 +- api_docs/session_view.mdx | 2 +- api_docs/share.mdx | 2 +- api_docs/snapshot_restore.mdx | 2 +- api_docs/spaces.mdx | 2 +- api_docs/stack_alerts.mdx | 2 +- api_docs/stack_connectors.mdx | 2 +- api_docs/task_manager.mdx | 2 +- api_docs/telemetry.mdx | 2 +- api_docs/telemetry_collection_manager.mdx | 2 +- api_docs/telemetry_collection_xpack.mdx | 2 +- api_docs/telemetry_management_section.mdx | 2 +- api_docs/threat_intelligence.mdx | 2 +- api_docs/timelines.mdx | 2 +- api_docs/transform.mdx | 2 +- api_docs/triggers_actions_ui.mdx | 2 +- api_docs/ui_actions.mdx | 2 +- api_docs/ui_actions_enhanced.mdx | 2 +- api_docs/unified_field_list.mdx | 2 +- api_docs/unified_histogram.mdx | 2 +- api_docs/unified_search.mdx | 2 +- api_docs/unified_search_autocomplete.mdx | 2 +- api_docs/url_forwarding.mdx | 2 +- api_docs/usage_collection.mdx | 2 +- api_docs/ux.mdx | 2 +- api_docs/vis_default_editor.mdx | 2 +- api_docs/vis_type_gauge.mdx | 2 +- api_docs/vis_type_heatmap.mdx | 2 +- api_docs/vis_type_pie.mdx | 2 +- api_docs/vis_type_table.mdx | 2 +- api_docs/vis_type_timelion.mdx | 2 +- api_docs/vis_type_timeseries.mdx | 2 +- api_docs/vis_type_vega.mdx | 2 +- api_docs/vis_type_vislib.mdx | 2 +- api_docs/vis_type_xy.mdx | 2 +- api_docs/visualizations.mdx | 2 +- 443 files changed, 789 insertions(+), 473 deletions(-) create mode 100644 api_docs/notifications.devdocs.json create mode 100644 api_docs/notifications.mdx diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index 45ae25e9b17c0..66093e7a6b5ab 100644 --- a/api_docs/actions.mdx +++ b/api_docs/actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/actions title: "actions" image: https://source.unsplash.com/400x175/?github description: API docs for the actions plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'actions'] --- import actionsObj from './actions.devdocs.json'; diff --git a/api_docs/advanced_settings.mdx b/api_docs/advanced_settings.mdx index bd29be2c00481..672f93fb0919e 100644 --- a/api_docs/advanced_settings.mdx +++ b/api_docs/advanced_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/advancedSettings title: "advancedSettings" image: https://source.unsplash.com/400x175/?github description: API docs for the advancedSettings plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings'] --- import advancedSettingsObj from './advanced_settings.devdocs.json'; diff --git a/api_docs/aiops.mdx b/api_docs/aiops.mdx index 936c9a2367ae2..187ae5f13dbb8 100644 --- a/api_docs/aiops.mdx +++ b/api_docs/aiops.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiops title: "aiops" image: https://source.unsplash.com/400x175/?github description: API docs for the aiops plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiops'] --- import aiopsObj from './aiops.devdocs.json'; diff --git a/api_docs/alerting.devdocs.json b/api_docs/alerting.devdocs.json index 5ace082c7a03e..841e8225d9d8d 100644 --- a/api_docs/alerting.devdocs.json +++ b/api_docs/alerting.devdocs.json @@ -1611,6 +1611,22 @@ "returnComment": [], "children": [] }, + { + "parentPluginId": "alerting", + "id": "def-server.PluginStartContract.getAllTypes", + "type": "Function", + "tags": [], + "label": "getAllTypes", + "description": [], + "signature": [ + "() => string[]" + ], + "path": "x-pack/plugins/alerting/server/plugin.ts", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [] + }, { "parentPluginId": "alerting", "id": "def-server.PluginStartContract.getRulesClientWithRequest", diff --git a/api_docs/alerting.mdx b/api_docs/alerting.mdx index f530f33d11f74..5da58c27ab4c3 100644 --- a/api_docs/alerting.mdx +++ b/api_docs/alerting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/alerting title: "alerting" image: https://source.unsplash.com/400x175/?github description: API docs for the alerting plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'alerting'] --- import alertingObj from './alerting.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Response Ops](https://github.com/orgs/elastic/teams/response-ops) for q | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 383 | 0 | 374 | 26 | +| 384 | 0 | 375 | 26 | ## Client diff --git a/api_docs/apm.mdx b/api_docs/apm.mdx index d07ecf0a253c2..1e449df65a7ec 100644 --- a/api_docs/apm.mdx +++ b/api_docs/apm.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/apm title: "apm" image: https://source.unsplash.com/400x175/?github description: API docs for the apm plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apm'] --- import apmObj from './apm.devdocs.json'; diff --git a/api_docs/banners.mdx b/api_docs/banners.mdx index 0ad42c9b17321..b8074030728dd 100644 --- a/api_docs/banners.mdx +++ b/api_docs/banners.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/banners title: "banners" image: https://source.unsplash.com/400x175/?github description: API docs for the banners plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'banners'] --- import bannersObj from './banners.devdocs.json'; diff --git a/api_docs/bfetch.mdx b/api_docs/bfetch.mdx index 3db90dea640f8..0b20b32cf640d 100644 --- a/api_docs/bfetch.mdx +++ b/api_docs/bfetch.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/bfetch title: "bfetch" image: https://source.unsplash.com/400x175/?github description: API docs for the bfetch plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'bfetch'] --- import bfetchObj from './bfetch.devdocs.json'; diff --git a/api_docs/canvas.mdx b/api_docs/canvas.mdx index 9e0901d75f6b1..6047f152ba2bb 100644 --- a/api_docs/canvas.mdx +++ b/api_docs/canvas.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/canvas title: "canvas" image: https://source.unsplash.com/400x175/?github description: API docs for the canvas plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'canvas'] --- import canvasObj from './canvas.devdocs.json'; diff --git a/api_docs/cases.mdx b/api_docs/cases.mdx index e7a74aacce4ae..8ac23e0e22b34 100644 --- a/api_docs/cases.mdx +++ b/api_docs/cases.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cases title: "cases" image: https://source.unsplash.com/400x175/?github description: API docs for the cases plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cases'] --- import casesObj from './cases.devdocs.json'; diff --git a/api_docs/charts.mdx b/api_docs/charts.mdx index e8838d50b0eaa..7c33895a9db9e 100644 --- a/api_docs/charts.mdx +++ b/api_docs/charts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/charts title: "charts" image: https://source.unsplash.com/400x175/?github description: API docs for the charts plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'charts'] --- import chartsObj from './charts.devdocs.json'; diff --git a/api_docs/cloud.mdx b/api_docs/cloud.mdx index f8d1163733b79..90d45ab5fe6c1 100644 --- a/api_docs/cloud.mdx +++ b/api_docs/cloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloud title: "cloud" image: https://source.unsplash.com/400x175/?github description: API docs for the cloud plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloud'] --- import cloudObj from './cloud.devdocs.json'; diff --git a/api_docs/cloud_chat.mdx b/api_docs/cloud_chat.mdx index 80ff13377bc26..ee4b8e728acfa 100644 --- a/api_docs/cloud_chat.mdx +++ b/api_docs/cloud_chat.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudChat title: "cloudChat" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudChat plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudChat'] --- import cloudChatObj from './cloud_chat.devdocs.json'; diff --git a/api_docs/cloud_experiments.mdx b/api_docs/cloud_experiments.mdx index c1b95e245680a..dc5a33367786f 100644 --- a/api_docs/cloud_experiments.mdx +++ b/api_docs/cloud_experiments.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudExperiments title: "cloudExperiments" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudExperiments plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudExperiments'] --- import cloudExperimentsObj from './cloud_experiments.devdocs.json'; diff --git a/api_docs/cloud_security_posture.mdx b/api_docs/cloud_security_posture.mdx index 4ad371b257335..805d5958316c3 100644 --- a/api_docs/cloud_security_posture.mdx +++ b/api_docs/cloud_security_posture.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudSecurityPosture title: "cloudSecurityPosture" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudSecurityPosture plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudSecurityPosture'] --- import cloudSecurityPostureObj from './cloud_security_posture.devdocs.json'; diff --git a/api_docs/console.mdx b/api_docs/console.mdx index 8fdf1ffb89ac0..7dbe582fd184e 100644 --- a/api_docs/console.mdx +++ b/api_docs/console.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/console title: "console" image: https://source.unsplash.com/400x175/?github description: API docs for the console plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'console'] --- import consoleObj from './console.devdocs.json'; diff --git a/api_docs/controls.mdx b/api_docs/controls.mdx index 6599db29e930d..2e69859a11dbf 100644 --- a/api_docs/controls.mdx +++ b/api_docs/controls.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/controls title: "controls" image: https://source.unsplash.com/400x175/?github description: API docs for the controls plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'controls'] --- import controlsObj from './controls.devdocs.json'; diff --git a/api_docs/core.mdx b/api_docs/core.mdx index 8c4220e8cf716..94defa88a150a 100644 --- a/api_docs/core.mdx +++ b/api_docs/core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/core title: "core" image: https://source.unsplash.com/400x175/?github description: API docs for the core plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'core'] --- import coreObj from './core.devdocs.json'; diff --git a/api_docs/custom_integrations.mdx b/api_docs/custom_integrations.mdx index c8cf92add3f3a..55995cdb13258 100644 --- a/api_docs/custom_integrations.mdx +++ b/api_docs/custom_integrations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/customIntegrations title: "customIntegrations" image: https://source.unsplash.com/400x175/?github description: API docs for the customIntegrations plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'customIntegrations'] --- import customIntegrationsObj from './custom_integrations.devdocs.json'; diff --git a/api_docs/dashboard.mdx b/api_docs/dashboard.mdx index 8ec36dacef78c..436ee1e60c68f 100644 --- a/api_docs/dashboard.mdx +++ b/api_docs/dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboard title: "dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboard plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboard'] --- import dashboardObj from './dashboard.devdocs.json'; diff --git a/api_docs/dashboard_enhanced.mdx b/api_docs/dashboard_enhanced.mdx index a02131a88a707..4f182f07cb86e 100644 --- a/api_docs/dashboard_enhanced.mdx +++ b/api_docs/dashboard_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboardEnhanced title: "dashboardEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboardEnhanced plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboardEnhanced'] --- import dashboardEnhancedObj from './dashboard_enhanced.devdocs.json'; diff --git a/api_docs/data.devdocs.json b/api_docs/data.devdocs.json index 553e1e7be39fc..15181498020c1 100644 --- a/api_docs/data.devdocs.json +++ b/api_docs/data.devdocs.json @@ -13399,10 +13399,6 @@ "plugin": "fleet", "path": "x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/query_bar.tsx" }, - { - "plugin": "fleet", - "path": "x-pack/plugins/fleet/public/applications/fleet/components/search_bar.tsx" - }, { "plugin": "canvas", "path": "x-pack/plugins/canvas/public/components/es_data_view_select/es_data_view_select.component.tsx" @@ -21101,10 +21097,6 @@ "plugin": "fleet", "path": "x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/query_bar.tsx" }, - { - "plugin": "fleet", - "path": "x-pack/plugins/fleet/public/applications/fleet/components/search_bar.tsx" - }, { "plugin": "canvas", "path": "x-pack/plugins/canvas/public/components/es_data_view_select/es_data_view_select.component.tsx" diff --git a/api_docs/data.mdx b/api_docs/data.mdx index f6bf34c288d68..4d82afee6ebad 100644 --- a/api_docs/data.mdx +++ b/api_docs/data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data title: "data" image: https://source.unsplash.com/400x175/?github description: API docs for the data plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data'] --- import dataObj from './data.devdocs.json'; diff --git a/api_docs/data_query.mdx b/api_docs/data_query.mdx index db9f22945d1ac..97573ad6cadb4 100644 --- a/api_docs/data_query.mdx +++ b/api_docs/data_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-query title: "data.query" image: https://source.unsplash.com/400x175/?github description: API docs for the data.query plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.query'] --- import dataQueryObj from './data_query.devdocs.json'; diff --git a/api_docs/data_search.mdx b/api_docs/data_search.mdx index b12119e1daa88..3fb119d56953b 100644 --- a/api_docs/data_search.mdx +++ b/api_docs/data_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-search title: "data.search" image: https://source.unsplash.com/400x175/?github description: API docs for the data.search plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.search'] --- import dataSearchObj from './data_search.devdocs.json'; diff --git a/api_docs/data_view_editor.mdx b/api_docs/data_view_editor.mdx index 8591c7282e883..2051c58870a00 100644 --- a/api_docs/data_view_editor.mdx +++ b/api_docs/data_view_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewEditor title: "dataViewEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewEditor plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewEditor'] --- import dataViewEditorObj from './data_view_editor.devdocs.json'; diff --git a/api_docs/data_view_field_editor.mdx b/api_docs/data_view_field_editor.mdx index c98f96208c9c4..4f4c913a97173 100644 --- a/api_docs/data_view_field_editor.mdx +++ b/api_docs/data_view_field_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewFieldEditor title: "dataViewFieldEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewFieldEditor plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewFieldEditor'] --- import dataViewFieldEditorObj from './data_view_field_editor.devdocs.json'; diff --git a/api_docs/data_view_management.mdx b/api_docs/data_view_management.mdx index 94ee7348cf66e..fc87dfe0a214f 100644 --- a/api_docs/data_view_management.mdx +++ b/api_docs/data_view_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewManagement title: "dataViewManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewManagement plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewManagement'] --- import dataViewManagementObj from './data_view_management.devdocs.json'; diff --git a/api_docs/data_views.devdocs.json b/api_docs/data_views.devdocs.json index 7c18de244ea8f..dbf671a475ede 100644 --- a/api_docs/data_views.devdocs.json +++ b/api_docs/data_views.devdocs.json @@ -587,10 +587,6 @@ "plugin": "fleet", "path": "x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/query_bar.tsx" }, - { - "plugin": "fleet", - "path": "x-pack/plugins/fleet/public/applications/fleet/components/search_bar.tsx" - }, { "plugin": "canvas", "path": "x-pack/plugins/canvas/public/components/es_data_view_select/es_data_view_select.component.tsx" @@ -8888,10 +8884,6 @@ "plugin": "fleet", "path": "x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/query_bar.tsx" }, - { - "plugin": "fleet", - "path": "x-pack/plugins/fleet/public/applications/fleet/components/search_bar.tsx" - }, { "plugin": "canvas", "path": "x-pack/plugins/canvas/public/components/es_data_view_select/es_data_view_select.component.tsx" @@ -16270,10 +16262,6 @@ "plugin": "fleet", "path": "x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/query_bar.tsx" }, - { - "plugin": "fleet", - "path": "x-pack/plugins/fleet/public/applications/fleet/components/search_bar.tsx" - }, { "plugin": "canvas", "path": "x-pack/plugins/canvas/public/components/es_data_view_select/es_data_view_select.component.tsx" diff --git a/api_docs/data_views.mdx b/api_docs/data_views.mdx index 725d6d1513885..10bcb9d197a85 100644 --- a/api_docs/data_views.mdx +++ b/api_docs/data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViews title: "dataViews" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViews plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViews'] --- import dataViewsObj from './data_views.devdocs.json'; diff --git a/api_docs/data_visualizer.mdx b/api_docs/data_visualizer.mdx index 044f63182b7b7..cca8d6d78f0fd 100644 --- a/api_docs/data_visualizer.mdx +++ b/api_docs/data_visualizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataVisualizer title: "dataVisualizer" image: https://source.unsplash.com/400x175/?github description: API docs for the dataVisualizer plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataVisualizer'] --- import dataVisualizerObj from './data_visualizer.devdocs.json'; diff --git a/api_docs/deprecations_by_api.mdx b/api_docs/deprecations_by_api.mdx index 4e3a8df5e4bdf..92f967d07bbb3 100644 --- a/api_docs/deprecations_by_api.mdx +++ b/api_docs/deprecations_by_api.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByApi slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-api title: Deprecated API usage by API description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index eb573d7b20274..d9294f0da0699 100644 --- a/api_docs/deprecations_by_plugin.mdx +++ b/api_docs/deprecations_by_plugin.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByPlugin slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-plugin title: Deprecated API usage by plugin description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -481,9 +481,9 @@ so TS and code-reference navigation might not highlight them. | | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| -| | [filter_dataset.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/filter_dataset.tsx#:~:text=title), [filter_log_level.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/filter_log_level.tsx#:~:text=title), [query_bar.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/query_bar.tsx#:~:text=title), [search_bar.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/components/search_bar.tsx#:~:text=title), [filter_dataset.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/filter_dataset.tsx#:~:text=title), [filter_log_level.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/filter_log_level.tsx#:~:text=title), [query_bar.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/query_bar.tsx#:~:text=title), [search_bar.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/components/search_bar.tsx#:~:text=title) | - | -| | [filter_dataset.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/filter_dataset.tsx#:~:text=title), [filter_log_level.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/filter_log_level.tsx#:~:text=title), [query_bar.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/query_bar.tsx#:~:text=title), [search_bar.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/components/search_bar.tsx#:~:text=title), [filter_dataset.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/filter_dataset.tsx#:~:text=title), [filter_log_level.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/filter_log_level.tsx#:~:text=title), [query_bar.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/query_bar.tsx#:~:text=title), [search_bar.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/components/search_bar.tsx#:~:text=title) | - | -| | [filter_dataset.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/filter_dataset.tsx#:~:text=title), [filter_log_level.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/filter_log_level.tsx#:~:text=title), [query_bar.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/query_bar.tsx#:~:text=title), [search_bar.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/components/search_bar.tsx#:~:text=title) | - | +| | [filter_dataset.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/filter_dataset.tsx#:~:text=title), [filter_log_level.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/filter_log_level.tsx#:~:text=title), [query_bar.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/query_bar.tsx#:~:text=title), [filter_dataset.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/filter_dataset.tsx#:~:text=title), [filter_log_level.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/filter_log_level.tsx#:~:text=title), [query_bar.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/query_bar.tsx#:~:text=title) | - | +| | [filter_dataset.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/filter_dataset.tsx#:~:text=title), [filter_log_level.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/filter_log_level.tsx#:~:text=title), [query_bar.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/query_bar.tsx#:~:text=title), [filter_dataset.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/filter_dataset.tsx#:~:text=title), [filter_log_level.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/filter_log_level.tsx#:~:text=title), [query_bar.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/query_bar.tsx#:~:text=title) | - | +| | [filter_dataset.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/filter_dataset.tsx#:~:text=title), [filter_log_level.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/filter_log_level.tsx#:~:text=title), [query_bar.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/query_bar.tsx#:~:text=title) | - | | | [use_get_logs_discover_link.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/multi_page_layout/hooks/use_get_logs_discover_link.tsx#:~:text=indexPatternId) | - | | | [tutorial_directory_header_link.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/components/home_integration/tutorial_directory_header_link.tsx#:~:text=RedirectAppLinks), [tutorial_directory_header_link.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/components/home_integration/tutorial_directory_header_link.tsx#:~:text=RedirectAppLinks), [tutorial_directory_header_link.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/components/home_integration/tutorial_directory_header_link.tsx#:~:text=RedirectAppLinks), [custom_assets_accordion.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/components/custom_assets_accordion.tsx#:~:text=RedirectAppLinks), [custom_assets_accordion.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/components/custom_assets_accordion.tsx#:~:text=RedirectAppLinks), [custom_assets_accordion.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/components/custom_assets_accordion.tsx#:~:text=RedirectAppLinks), [agent_logs.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/agent_logs.tsx#:~:text=RedirectAppLinks), [agent_logs.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/agent_logs.tsx#:~:text=RedirectAppLinks), [agent_logs.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_logs/agent_logs.tsx#:~:text=RedirectAppLinks), [app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/public/applications/integrations/app.tsx#:~:text=RedirectAppLinks)+ 5 more | - | | | [plugin.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/fleet/server/plugin.ts#:~:text=disabled) | 8.8.0 | diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index 818676792f91c..c7311050cdf5e 100644 --- a/api_docs/deprecations_by_team.mdx +++ b/api_docs/deprecations_by_team.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsDueByTeam slug: /kibana-dev-docs/api-meta/deprecations-due-by-team title: Deprecated APIs due to be removed, by team description: Lists the teams that are referencing deprecated APIs with a remove by date. -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index 3eccaa28d481d..016caf397fa15 100644 --- a/api_docs/dev_tools.mdx +++ b/api_docs/dev_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/devTools title: "devTools" image: https://source.unsplash.com/400x175/?github description: API docs for the devTools plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'devTools'] --- import devToolsObj from './dev_tools.devdocs.json'; diff --git a/api_docs/discover.mdx b/api_docs/discover.mdx index aa18ecbfecc3c..a9b6af99dd77e 100644 --- a/api_docs/discover.mdx +++ b/api_docs/discover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discover title: "discover" image: https://source.unsplash.com/400x175/?github description: API docs for the discover plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discover'] --- import discoverObj from './discover.devdocs.json'; diff --git a/api_docs/discover_enhanced.mdx b/api_docs/discover_enhanced.mdx index 93d44e5df3b1b..0db95822d49a8 100644 --- a/api_docs/discover_enhanced.mdx +++ b/api_docs/discover_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discoverEnhanced title: "discoverEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the discoverEnhanced plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverEnhanced'] --- import discoverEnhancedObj from './discover_enhanced.devdocs.json'; diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index 5fd3ab983e6c8..a37f160e9856c 100644 --- a/api_docs/embeddable.mdx +++ b/api_docs/embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddable title: "embeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddable plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddable'] --- import embeddableObj from './embeddable.devdocs.json'; diff --git a/api_docs/embeddable_enhanced.mdx b/api_docs/embeddable_enhanced.mdx index 258f0710fafc2..95acf704c066f 100644 --- a/api_docs/embeddable_enhanced.mdx +++ b/api_docs/embeddable_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddableEnhanced title: "embeddableEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddableEnhanced plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddableEnhanced'] --- import embeddableEnhancedObj from './embeddable_enhanced.devdocs.json'; diff --git a/api_docs/encrypted_saved_objects.mdx b/api_docs/encrypted_saved_objects.mdx index 1d34e7432e4a6..55196daed59f5 100644 --- a/api_docs/encrypted_saved_objects.mdx +++ b/api_docs/encrypted_saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/encryptedSavedObjects title: "encryptedSavedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the encryptedSavedObjects plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'encryptedSavedObjects'] --- import encryptedSavedObjectsObj from './encrypted_saved_objects.devdocs.json'; diff --git a/api_docs/enterprise_search.mdx b/api_docs/enterprise_search.mdx index eb7322768c918..b05fe04353180 100644 --- a/api_docs/enterprise_search.mdx +++ b/api_docs/enterprise_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/enterpriseSearch title: "enterpriseSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the enterpriseSearch plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'enterpriseSearch'] --- import enterpriseSearchObj from './enterprise_search.devdocs.json'; diff --git a/api_docs/es_ui_shared.mdx b/api_docs/es_ui_shared.mdx index 6c210de4a3eb7..c279a171ef789 100644 --- a/api_docs/es_ui_shared.mdx +++ b/api_docs/es_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/esUiShared title: "esUiShared" image: https://source.unsplash.com/400x175/?github description: API docs for the esUiShared plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] --- import esUiSharedObj from './es_ui_shared.devdocs.json'; diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index 9b62890d42a8c..6f2a2d753bfc2 100644 --- a/api_docs/event_annotation.mdx +++ b/api_docs/event_annotation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventAnnotation title: "eventAnnotation" image: https://source.unsplash.com/400x175/?github description: API docs for the eventAnnotation plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotation'] --- import eventAnnotationObj from './event_annotation.devdocs.json'; diff --git a/api_docs/event_log.mdx b/api_docs/event_log.mdx index 9251a09f4331d..ea9b7aa97352c 100644 --- a/api_docs/event_log.mdx +++ b/api_docs/event_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventLog title: "eventLog" image: https://source.unsplash.com/400x175/?github description: API docs for the eventLog plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventLog'] --- import eventLogObj from './event_log.devdocs.json'; diff --git a/api_docs/expression_error.mdx b/api_docs/expression_error.mdx index 12c514f316fe7..6e6f778e96deb 100644 --- a/api_docs/expression_error.mdx +++ b/api_docs/expression_error.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionError title: "expressionError" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionError plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionError'] --- import expressionErrorObj from './expression_error.devdocs.json'; diff --git a/api_docs/expression_gauge.mdx b/api_docs/expression_gauge.mdx index 038248c69857f..fb56b758dd6af 100644 --- a/api_docs/expression_gauge.mdx +++ b/api_docs/expression_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionGauge title: "expressionGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionGauge plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionGauge'] --- import expressionGaugeObj from './expression_gauge.devdocs.json'; diff --git a/api_docs/expression_heatmap.mdx b/api_docs/expression_heatmap.mdx index 0844b3e94a269..8541a49468ea5 100644 --- a/api_docs/expression_heatmap.mdx +++ b/api_docs/expression_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionHeatmap title: "expressionHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionHeatmap plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionHeatmap'] --- import expressionHeatmapObj from './expression_heatmap.devdocs.json'; diff --git a/api_docs/expression_image.mdx b/api_docs/expression_image.mdx index d12e3d10d06cc..340521a94c01f 100644 --- a/api_docs/expression_image.mdx +++ b/api_docs/expression_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionImage title: "expressionImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionImage plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionImage'] --- import expressionImageObj from './expression_image.devdocs.json'; diff --git a/api_docs/expression_legacy_metric_vis.mdx b/api_docs/expression_legacy_metric_vis.mdx index 06725c77e3b9a..3cc007b2f8c70 100644 --- a/api_docs/expression_legacy_metric_vis.mdx +++ b/api_docs/expression_legacy_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionLegacyMetricVis title: "expressionLegacyMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionLegacyMetricVis plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionLegacyMetricVis'] --- import expressionLegacyMetricVisObj from './expression_legacy_metric_vis.devdocs.json'; diff --git a/api_docs/expression_metric.mdx b/api_docs/expression_metric.mdx index aa5cc4b4c2b33..455050e452e59 100644 --- a/api_docs/expression_metric.mdx +++ b/api_docs/expression_metric.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetric title: "expressionMetric" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetric plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetric'] --- import expressionMetricObj from './expression_metric.devdocs.json'; diff --git a/api_docs/expression_metric_vis.devdocs.json b/api_docs/expression_metric_vis.devdocs.json index 052d886583c4a..5d837dadafaf1 100644 --- a/api_docs/expression_metric_vis.devdocs.json +++ b/api_docs/expression_metric_vis.devdocs.json @@ -1086,6 +1086,64 @@ "deprecated": false, "trackAdoption": false, "initialIsOpen": false + }, + { + "parentPluginId": "expressionMetricVis", + "id": "def-common.TrendlineExpressionFunctionDefinition", + "type": "Type", + "tags": [], + "label": "TrendlineExpressionFunctionDefinition", + "description": [], + "signature": [ + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.ExpressionFunctionDefinition", + "text": "ExpressionFunctionDefinition" + }, + "<\"metricTrendline\", ", + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.Datatable", + "text": "Datatable" + }, + ", ", + "TrendlineArguments", + ", ", + "TrendlineResult", + ", ", + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.ExecutionContext", + "text": "ExecutionContext" + }, + "<", + { + "pluginId": "inspector", + "scope": "common", + "docId": "kibInspectorPluginApi", + "section": "def-common.Adapters", + "text": "Adapters" + }, + ", ", + { + "pluginId": "@kbn/utility-types", + "scope": "server", + "docId": "kibKbnUtilityTypesPluginApi", + "section": "def-server.SerializableRecord", + "text": "SerializableRecord" + }, + ">>" + ], + "path": "src/plugins/chart_expressions/expression_metric/common/types/expression_functions.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false } ], "objects": [] diff --git a/api_docs/expression_metric_vis.mdx b/api_docs/expression_metric_vis.mdx index 82ce89f2e9b72..73f0f7ad1235a 100644 --- a/api_docs/expression_metric_vis.mdx +++ b/api_docs/expression_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetricVis title: "expressionMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetricVis plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetricVis'] --- import expressionMetricVisObj from './expression_metric_vis.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 62 | 0 | 62 | 1 | +| 63 | 0 | 63 | 2 | ## Client diff --git a/api_docs/expression_partition_vis.devdocs.json b/api_docs/expression_partition_vis.devdocs.json index 5c3b0a81120ca..f9a606bdebd30 100644 --- a/api_docs/expression_partition_vis.devdocs.json +++ b/api_docs/expression_partition_vis.devdocs.json @@ -1219,6 +1219,70 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "expressionPartitionVis", + "id": "def-common.PartitionLabelsExpressionFunctionDefinition", + "type": "Type", + "tags": [], + "label": "PartitionLabelsExpressionFunctionDefinition", + "description": [], + "signature": [ + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.ExpressionFunctionDefinition", + "text": "ExpressionFunctionDefinition" + }, + "<\"partitionLabels\", ", + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.Datatable", + "text": "Datatable" + }, + " | null, ", + "PartitionLabelsArguments", + ", ", + { + "pluginId": "expressionPartitionVis", + "scope": "common", + "docId": "kibExpressionPartitionVisPluginApi", + "section": "def-common.ExpressionValuePartitionLabels", + "text": "ExpressionValuePartitionLabels" + }, + ", ", + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.ExecutionContext", + "text": "ExecutionContext" + }, + "<", + { + "pluginId": "inspector", + "scope": "common", + "docId": "kibInspectorPluginApi", + "section": "def-common.Adapters", + "text": "Adapters" + }, + ", ", + { + "pluginId": "@kbn/utility-types", + "scope": "server", + "docId": "kibKbnUtilityTypesPluginApi", + "section": "def-server.SerializableRecord", + "text": "SerializableRecord" + }, + ">>" + ], + "path": "src/plugins/chart_expressions/expression_partition_vis/common/types/expression_functions.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "expressionPartitionVis", "id": "def-common.PIE_VIS_EXPRESSION_NAME", diff --git a/api_docs/expression_partition_vis.mdx b/api_docs/expression_partition_vis.mdx index 0b5b547c7fa26..ed3632ca4a00f 100644 --- a/api_docs/expression_partition_vis.mdx +++ b/api_docs/expression_partition_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionPartitionVis title: "expressionPartitionVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionPartitionVis plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionPartitionVis'] --- import expressionPartitionVisObj from './expression_partition_vis.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 70 | 0 | 70 | 2 | +| 71 | 0 | 71 | 2 | ## Client diff --git a/api_docs/expression_repeat_image.mdx b/api_docs/expression_repeat_image.mdx index 2a6c6bc3acc9e..82b7ebb310ed5 100644 --- a/api_docs/expression_repeat_image.mdx +++ b/api_docs/expression_repeat_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRepeatImage title: "expressionRepeatImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRepeatImage plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRepeatImage'] --- import expressionRepeatImageObj from './expression_repeat_image.devdocs.json'; diff --git a/api_docs/expression_reveal_image.mdx b/api_docs/expression_reveal_image.mdx index e67e8d2f2adf9..931a50523440c 100644 --- a/api_docs/expression_reveal_image.mdx +++ b/api_docs/expression_reveal_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRevealImage title: "expressionRevealImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRevealImage plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRevealImage'] --- import expressionRevealImageObj from './expression_reveal_image.devdocs.json'; diff --git a/api_docs/expression_shape.mdx b/api_docs/expression_shape.mdx index 43c6376b76d1a..d7daa95bff846 100644 --- a/api_docs/expression_shape.mdx +++ b/api_docs/expression_shape.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionShape title: "expressionShape" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionShape plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionShape'] --- import expressionShapeObj from './expression_shape.devdocs.json'; diff --git a/api_docs/expression_tagcloud.mdx b/api_docs/expression_tagcloud.mdx index a4f2b1c54a11b..e408a004cc33f 100644 --- a/api_docs/expression_tagcloud.mdx +++ b/api_docs/expression_tagcloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionTagcloud title: "expressionTagcloud" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionTagcloud plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionTagcloud'] --- import expressionTagcloudObj from './expression_tagcloud.devdocs.json'; diff --git a/api_docs/expression_x_y.mdx b/api_docs/expression_x_y.mdx index c8399afdaac75..ea2853fff9008 100644 --- a/api_docs/expression_x_y.mdx +++ b/api_docs/expression_x_y.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionXY title: "expressionXY" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionXY plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionXY'] --- import expressionXYObj from './expression_x_y.devdocs.json'; diff --git a/api_docs/expressions.devdocs.json b/api_docs/expressions.devdocs.json index a1b86d1c267b6..dc286cf76daa6 100644 --- a/api_docs/expressions.devdocs.json +++ b/api_docs/expressions.devdocs.json @@ -37572,7 +37572,7 @@ "section": "def-common.MathArguments", "text": "MathArguments" }, - " & { id: string; name?: string | undefined; copyMetaFrom?: string | null | undefined; }" + " & { id: string; name?: string | undefined; castColumns?: string[] | undefined; copyMetaFrom?: string | null | undefined; }" ], "path": "src/plugins/expressions/common/expression_functions/specs/math_column.ts", "deprecated": false, @@ -42294,6 +42294,75 @@ } ] }, + { + "parentPluginId": "expressions", + "id": "def-common.mathColumn.args.castColumns", + "type": "Object", + "tags": [], + "label": "castColumns", + "description": [], + "path": "src/plugins/expressions/common/expression_functions/specs/math_column.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "expressions", + "id": "def-common.mathColumn.args.castColumns.types", + "type": "Array", + "tags": [], + "label": "types", + "description": [], + "signature": [ + "\"string\"[]" + ], + "path": "src/plugins/expressions/common/expression_functions/specs/math_column.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "expressions", + "id": "def-common.mathColumn.args.castColumns.multi", + "type": "boolean", + "tags": [], + "label": "multi", + "description": [], + "signature": [ + "true" + ], + "path": "src/plugins/expressions/common/expression_functions/specs/math_column.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "expressions", + "id": "def-common.mathColumn.args.castColumns.help", + "type": "Any", + "tags": [], + "label": "help", + "description": [], + "signature": [ + "any" + ], + "path": "src/plugins/expressions/common/expression_functions/specs/math_column.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "expressions", + "id": "def-common.mathColumn.args.castColumns.required", + "type": "boolean", + "tags": [], + "label": "required", + "description": [], + "signature": [ + "false" + ], + "path": "src/plugins/expressions/common/expression_functions/specs/math_column.ts", + "deprecated": false, + "trackAdoption": false + } + ] + }, { "parentPluginId": "expressions", "id": "def-common.mathColumn.args.copyMetaFrom", diff --git a/api_docs/expressions.mdx b/api_docs/expressions.mdx index e62db4abe9aba..d30e3fe086b66 100644 --- a/api_docs/expressions.mdx +++ b/api_docs/expressions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressions title: "expressions" image: https://source.unsplash.com/400x175/?github description: API docs for the expressions plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressions'] --- import expressionsObj from './expressions.devdocs.json'; @@ -21,7 +21,7 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 2191 | 73 | 1734 | 5 | +| 2196 | 74 | 1739 | 5 | ## Client diff --git a/api_docs/features.mdx b/api_docs/features.mdx index 684232c6bb419..21ee873128033 100644 --- a/api_docs/features.mdx +++ b/api_docs/features.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/features title: "features" image: https://source.unsplash.com/400x175/?github description: API docs for the features plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'features'] --- import featuresObj from './features.devdocs.json'; diff --git a/api_docs/field_formats.mdx b/api_docs/field_formats.mdx index 78fc717977236..420432acec141 100644 --- a/api_docs/field_formats.mdx +++ b/api_docs/field_formats.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fieldFormats title: "fieldFormats" image: https://source.unsplash.com/400x175/?github description: API docs for the fieldFormats plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fieldFormats'] --- import fieldFormatsObj from './field_formats.devdocs.json'; diff --git a/api_docs/file_upload.mdx b/api_docs/file_upload.mdx index 7d3ce796501b1..3345f4652c979 100644 --- a/api_docs/file_upload.mdx +++ b/api_docs/file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fileUpload title: "fileUpload" image: https://source.unsplash.com/400x175/?github description: API docs for the fileUpload plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fileUpload'] --- import fileUploadObj from './file_upload.devdocs.json'; diff --git a/api_docs/files.devdocs.json b/api_docs/files.devdocs.json index 94f495ecaaf41..55601ee2dbb95 100644 --- a/api_docs/files.devdocs.json +++ b/api_docs/files.devdocs.json @@ -1329,6 +1329,24 @@ "path": "src/plugins/files/public/components/file_picker/file_picker.tsx", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "files", + "id": "def-public.Props.multiple", + "type": "CompoundType", + "tags": [ + "default" + ], + "label": "multiple", + "description": [ + "\nWhether you can select one or more files\n" + ], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/files/public/components/file_picker/file_picker.tsx", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/files.mdx b/api_docs/files.mdx index e9d3976bbf623..3843c12d4136f 100644 --- a/api_docs/files.mdx +++ b/api_docs/files.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/files title: "files" image: https://source.unsplash.com/400x175/?github description: API docs for the files plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'files'] --- import filesObj from './files.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-app-services](https://github.com/orgs/elastic/teams/tea | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 275 | 0 | 19 | 3 | +| 276 | 0 | 19 | 3 | ## Client diff --git a/api_docs/fleet.devdocs.json b/api_docs/fleet.devdocs.json index 9b000a45b2696..2feb3907e35dd 100644 --- a/api_docs/fleet.devdocs.json +++ b/api_docs/fleet.devdocs.json @@ -13780,6 +13780,20 @@ "path": "x-pack/plugins/fleet/common/types/models/epm.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "fleet", + "id": "def-common.RegistryElasticsearch.source_mode", + "type": "CompoundType", + "tags": [], + "label": "source_mode", + "description": [], + "signature": [ + "\"default\" | \"synthetic\" | undefined" + ], + "path": "x-pack/plugins/fleet/common/types/models/epm.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/fleet.mdx b/api_docs/fleet.mdx index f30580dda5f04..6fc456035b9a3 100644 --- a/api_docs/fleet.mdx +++ b/api_docs/fleet.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fleet title: "fleet" image: https://source.unsplash.com/400x175/?github description: API docs for the fleet plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fleet'] --- import fleetObj from './fleet.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Fleet](https://github.com/orgs/elastic/teams/fleet) for questions regar | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 1000 | 3 | 897 | 18 | +| 1001 | 3 | 898 | 18 | ## Client diff --git a/api_docs/global_search.mdx b/api_docs/global_search.mdx index 048aaec803587..64e25357c4231 100644 --- a/api_docs/global_search.mdx +++ b/api_docs/global_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/globalSearch title: "globalSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the globalSearch plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'globalSearch'] --- import globalSearchObj from './global_search.devdocs.json'; diff --git a/api_docs/guided_onboarding.mdx b/api_docs/guided_onboarding.mdx index 2f9c1dfdac76b..ae8a5d824ef89 100644 --- a/api_docs/guided_onboarding.mdx +++ b/api_docs/guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/guidedOnboarding title: "guidedOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the guidedOnboarding plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'guidedOnboarding'] --- import guidedOnboardingObj from './guided_onboarding.devdocs.json'; diff --git a/api_docs/home.mdx b/api_docs/home.mdx index a32112e8123c1..2f01a404aac13 100644 --- a/api_docs/home.mdx +++ b/api_docs/home.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/home title: "home" image: https://source.unsplash.com/400x175/?github description: API docs for the home plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'home'] --- import homeObj from './home.devdocs.json'; diff --git a/api_docs/index_lifecycle_management.mdx b/api_docs/index_lifecycle_management.mdx index 510ff24e2c251..60edf798cc446 100644 --- a/api_docs/index_lifecycle_management.mdx +++ b/api_docs/index_lifecycle_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexLifecycleManagement title: "indexLifecycleManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexLifecycleManagement plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexLifecycleManagement'] --- import indexLifecycleManagementObj from './index_lifecycle_management.devdocs.json'; diff --git a/api_docs/index_management.mdx b/api_docs/index_management.mdx index 3bbdb688692ea..e320714989ef6 100644 --- a/api_docs/index_management.mdx +++ b/api_docs/index_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexManagement title: "indexManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexManagement plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexManagement'] --- import indexManagementObj from './index_management.devdocs.json'; diff --git a/api_docs/infra.mdx b/api_docs/infra.mdx index e1c9ff267d7dd..31687ba20fa21 100644 --- a/api_docs/infra.mdx +++ b/api_docs/infra.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/infra title: "infra" image: https://source.unsplash.com/400x175/?github description: API docs for the infra plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'infra'] --- import infraObj from './infra.devdocs.json'; diff --git a/api_docs/inspector.mdx b/api_docs/inspector.mdx index b3d3c815e2d2d..9336a32be0598 100644 --- a/api_docs/inspector.mdx +++ b/api_docs/inspector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/inspector title: "inspector" image: https://source.unsplash.com/400x175/?github description: API docs for the inspector plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'inspector'] --- import inspectorObj from './inspector.devdocs.json'; diff --git a/api_docs/interactive_setup.mdx b/api_docs/interactive_setup.mdx index 27942d7369d3d..629fa3d39a7fb 100644 --- a/api_docs/interactive_setup.mdx +++ b/api_docs/interactive_setup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/interactiveSetup title: "interactiveSetup" image: https://source.unsplash.com/400x175/?github description: API docs for the interactiveSetup plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'interactiveSetup'] --- import interactiveSetupObj from './interactive_setup.devdocs.json'; diff --git a/api_docs/kbn_ace.mdx b/api_docs/kbn_ace.mdx index 4bfcff1578434..fb7203c81faa8 100644 --- a/api_docs/kbn_ace.mdx +++ b/api_docs/kbn_ace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ace title: "@kbn/ace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ace plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ace'] --- import kbnAceObj from './kbn_ace.devdocs.json'; diff --git a/api_docs/kbn_aiops_components.mdx b/api_docs/kbn_aiops_components.mdx index cefdbda3681fe..b68d2d21a3496 100644 --- a/api_docs/kbn_aiops_components.mdx +++ b/api_docs/kbn_aiops_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-components title: "@kbn/aiops-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-components plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-components'] --- import kbnAiopsComponentsObj from './kbn_aiops_components.devdocs.json'; diff --git a/api_docs/kbn_aiops_utils.mdx b/api_docs/kbn_aiops_utils.mdx index 41604e4bde28d..89e0b4725b53c 100644 --- a/api_docs/kbn_aiops_utils.mdx +++ b/api_docs/kbn_aiops_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-utils title: "@kbn/aiops-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-utils plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-utils'] --- import kbnAiopsUtilsObj from './kbn_aiops_utils.devdocs.json'; diff --git a/api_docs/kbn_alerts.mdx b/api_docs/kbn_alerts.mdx index d006f31f28b8f..15d7e647bf111 100644 --- a/api_docs/kbn_alerts.mdx +++ b/api_docs/kbn_alerts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts title: "@kbn/alerts" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts'] --- import kbnAlertsObj from './kbn_alerts.devdocs.json'; diff --git a/api_docs/kbn_analytics.mdx b/api_docs/kbn_analytics.mdx index 94c015954b749..38a266e59cf94 100644 --- a/api_docs/kbn_analytics.mdx +++ b/api_docs/kbn_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics title: "@kbn/analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics'] --- import kbnAnalyticsObj from './kbn_analytics.devdocs.json'; diff --git a/api_docs/kbn_analytics_client.mdx b/api_docs/kbn_analytics_client.mdx index 7295871ca7197..ac32161c59fd1 100644 --- a/api_docs/kbn_analytics_client.mdx +++ b/api_docs/kbn_analytics_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-client title: "@kbn/analytics-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-client plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-client'] --- import kbnAnalyticsClientObj from './kbn_analytics_client.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx index b9071bf78dc00..325340598ba49 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-browser title: "@kbn/analytics-shippers-elastic-v3-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-browser plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-browser'] --- import kbnAnalyticsShippersElasticV3BrowserObj from './kbn_analytics_shippers_elastic_v3_browser.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx index 6be0962a8bec1..ec055e27289d1 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-common title: "@kbn/analytics-shippers-elastic-v3-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-common plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-common'] --- import kbnAnalyticsShippersElasticV3CommonObj from './kbn_analytics_shippers_elastic_v3_common.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx index 2a18ed135769b..0ed7af3bbe2a6 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-server title: "@kbn/analytics-shippers-elastic-v3-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-server plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-server'] --- import kbnAnalyticsShippersElasticV3ServerObj from './kbn_analytics_shippers_elastic_v3_server.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_fullstory.mdx b/api_docs/kbn_analytics_shippers_fullstory.mdx index ef030cc0cf79a..f240f890ccdc1 100644 --- a/api_docs/kbn_analytics_shippers_fullstory.mdx +++ b/api_docs/kbn_analytics_shippers_fullstory.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-fullstory title: "@kbn/analytics-shippers-fullstory" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-fullstory plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-fullstory'] --- import kbnAnalyticsShippersFullstoryObj from './kbn_analytics_shippers_fullstory.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_gainsight.mdx b/api_docs/kbn_analytics_shippers_gainsight.mdx index 03a74158fb62d..b03f239d4c7f9 100644 --- a/api_docs/kbn_analytics_shippers_gainsight.mdx +++ b/api_docs/kbn_analytics_shippers_gainsight.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-gainsight title: "@kbn/analytics-shippers-gainsight" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-gainsight plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-gainsight'] --- import kbnAnalyticsShippersGainsightObj from './kbn_analytics_shippers_gainsight.devdocs.json'; diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index ada09206af9f6..e3d4ba2fad3fc 100644 --- a/api_docs/kbn_apm_config_loader.mdx +++ b/api_docs/kbn_apm_config_loader.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-config-loader title: "@kbn/apm-config-loader" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-config-loader plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-config-loader'] --- import kbnApmConfigLoaderObj from './kbn_apm_config_loader.devdocs.json'; diff --git a/api_docs/kbn_apm_synthtrace.mdx b/api_docs/kbn_apm_synthtrace.mdx index 8290e7b16cae8..0f2760630787c 100644 --- a/api_docs/kbn_apm_synthtrace.mdx +++ b/api_docs/kbn_apm_synthtrace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace title: "@kbn/apm-synthtrace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace'] --- import kbnApmSynthtraceObj from './kbn_apm_synthtrace.devdocs.json'; diff --git a/api_docs/kbn_apm_utils.mdx b/api_docs/kbn_apm_utils.mdx index d36b1fd4b2a1c..e172eb68ba0d1 100644 --- a/api_docs/kbn_apm_utils.mdx +++ b/api_docs/kbn_apm_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-utils title: "@kbn/apm-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-utils plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-utils'] --- import kbnApmUtilsObj from './kbn_apm_utils.devdocs.json'; diff --git a/api_docs/kbn_axe_config.mdx b/api_docs/kbn_axe_config.mdx index c7ce93dd0cf0c..9f070de5b32d5 100644 --- a/api_docs/kbn_axe_config.mdx +++ b/api_docs/kbn_axe_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-axe-config title: "@kbn/axe-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/axe-config plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/axe-config'] --- import kbnAxeConfigObj from './kbn_axe_config.devdocs.json'; diff --git a/api_docs/kbn_cases_components.mdx b/api_docs/kbn_cases_components.mdx index ddd535d9e8c90..70d459d4a3229 100644 --- a/api_docs/kbn_cases_components.mdx +++ b/api_docs/kbn_cases_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cases-components title: "@kbn/cases-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cases-components plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cases-components'] --- import kbnCasesComponentsObj from './kbn_cases_components.devdocs.json'; diff --git a/api_docs/kbn_chart_icons.mdx b/api_docs/kbn_chart_icons.mdx index 2cd4a2ad70d8b..9bac9d9cb8919 100644 --- a/api_docs/kbn_chart_icons.mdx +++ b/api_docs/kbn_chart_icons.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-icons title: "@kbn/chart-icons" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-icons plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/chart-icons'] --- import kbnChartIconsObj from './kbn_chart_icons.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_core.mdx b/api_docs/kbn_ci_stats_core.mdx index a083756345726..18c73cbe904b5 100644 --- a/api_docs/kbn_ci_stats_core.mdx +++ b/api_docs/kbn_ci_stats_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-core title: "@kbn/ci-stats-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-core plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-core'] --- import kbnCiStatsCoreObj from './kbn_ci_stats_core.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_performance_metrics.mdx b/api_docs/kbn_ci_stats_performance_metrics.mdx index 0311d32eef9f4..38981eb15b391 100644 --- a/api_docs/kbn_ci_stats_performance_metrics.mdx +++ b/api_docs/kbn_ci_stats_performance_metrics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-performance-metrics title: "@kbn/ci-stats-performance-metrics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-performance-metrics plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-performance-metrics'] --- import kbnCiStatsPerformanceMetricsObj from './kbn_ci_stats_performance_metrics.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_reporter.mdx b/api_docs/kbn_ci_stats_reporter.mdx index 1ddbffaaf9256..28222594047b7 100644 --- a/api_docs/kbn_ci_stats_reporter.mdx +++ b/api_docs/kbn_ci_stats_reporter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-reporter title: "@kbn/ci-stats-reporter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-reporter plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-reporter'] --- import kbnCiStatsReporterObj from './kbn_ci_stats_reporter.devdocs.json'; diff --git a/api_docs/kbn_cli_dev_mode.mdx b/api_docs/kbn_cli_dev_mode.mdx index 14c9634cf1529..8cfe2f8b99aaf 100644 --- a/api_docs/kbn_cli_dev_mode.mdx +++ b/api_docs/kbn_cli_dev_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cli-dev-mode title: "@kbn/cli-dev-mode" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cli-dev-mode plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cli-dev-mode'] --- import kbnCliDevModeObj from './kbn_cli_dev_mode.devdocs.json'; diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx index 6559237d7c043..7b14a6c77e7c1 100644 --- a/api_docs/kbn_coloring.mdx +++ b/api_docs/kbn_coloring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-coloring title: "@kbn/coloring" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/coloring plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/coloring'] --- import kbnColoringObj from './kbn_coloring.devdocs.json'; diff --git a/api_docs/kbn_config.mdx b/api_docs/kbn_config.mdx index 41a9a67465b00..b20e2fdf6f0dd 100644 --- a/api_docs/kbn_config.mdx +++ b/api_docs/kbn_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config title: "@kbn/config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config'] --- import kbnConfigObj from './kbn_config.devdocs.json'; diff --git a/api_docs/kbn_config_mocks.mdx b/api_docs/kbn_config_mocks.mdx index f3e0fcd2bb6a6..bb650a3d83589 100644 --- a/api_docs/kbn_config_mocks.mdx +++ b/api_docs/kbn_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-mocks title: "@kbn/config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-mocks'] --- import kbnConfigMocksObj from './kbn_config_mocks.devdocs.json'; diff --git a/api_docs/kbn_config_schema.mdx b/api_docs/kbn_config_schema.mdx index 4c5e16cc878b4..85d34b44c8d68 100644 --- a/api_docs/kbn_config_schema.mdx +++ b/api_docs/kbn_config_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-schema title: "@kbn/config-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-schema plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-schema'] --- import kbnConfigSchemaObj from './kbn_config_schema.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list.mdx b/api_docs/kbn_content_management_table_list.mdx index 1f6a3bfaf876b..9a669546c3fb0 100644 --- a/api_docs/kbn_content_management_table_list.mdx +++ b/api_docs/kbn_content_management_table_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list title: "@kbn/content-management-table-list" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list'] --- import kbnContentManagementTableListObj from './kbn_content_management_table_list.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser.mdx b/api_docs/kbn_core_analytics_browser.mdx index 4c443f79b5200..aeaa4aa93cb6c 100644 --- a/api_docs/kbn_core_analytics_browser.mdx +++ b/api_docs/kbn_core_analytics_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser title: "@kbn/core-analytics-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser'] --- import kbnCoreAnalyticsBrowserObj from './kbn_core_analytics_browser.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_internal.mdx b/api_docs/kbn_core_analytics_browser_internal.mdx index 780e2e63973b1..f4d7180e92675 100644 --- a/api_docs/kbn_core_analytics_browser_internal.mdx +++ b/api_docs/kbn_core_analytics_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-internal title: "@kbn/core-analytics-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-internal'] --- import kbnCoreAnalyticsBrowserInternalObj from './kbn_core_analytics_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_mocks.mdx b/api_docs/kbn_core_analytics_browser_mocks.mdx index 6c12d9f559765..366eb4a0efc7d 100644 --- a/api_docs/kbn_core_analytics_browser_mocks.mdx +++ b/api_docs/kbn_core_analytics_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-mocks title: "@kbn/core-analytics-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-mocks'] --- import kbnCoreAnalyticsBrowserMocksObj from './kbn_core_analytics_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server.mdx b/api_docs/kbn_core_analytics_server.mdx index 7994ddbe86ab0..f11f638fb4833 100644 --- a/api_docs/kbn_core_analytics_server.mdx +++ b/api_docs/kbn_core_analytics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server title: "@kbn/core-analytics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server'] --- import kbnCoreAnalyticsServerObj from './kbn_core_analytics_server.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_internal.mdx b/api_docs/kbn_core_analytics_server_internal.mdx index 93c2233ce32a3..c3a05704928e2 100644 --- a/api_docs/kbn_core_analytics_server_internal.mdx +++ b/api_docs/kbn_core_analytics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-internal title: "@kbn/core-analytics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-internal'] --- import kbnCoreAnalyticsServerInternalObj from './kbn_core_analytics_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_mocks.mdx b/api_docs/kbn_core_analytics_server_mocks.mdx index f5abc3b0f925b..d5dcd89817adc 100644 --- a/api_docs/kbn_core_analytics_server_mocks.mdx +++ b/api_docs/kbn_core_analytics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-mocks title: "@kbn/core-analytics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-mocks'] --- import kbnCoreAnalyticsServerMocksObj from './kbn_core_analytics_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser.mdx b/api_docs/kbn_core_application_browser.mdx index 623dfb256f7f6..bbb62d9cf8429 100644 --- a/api_docs/kbn_core_application_browser.mdx +++ b/api_docs/kbn_core_application_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser title: "@kbn/core-application-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser'] --- import kbnCoreApplicationBrowserObj from './kbn_core_application_browser.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser_internal.mdx b/api_docs/kbn_core_application_browser_internal.mdx index f6d9f4b8d08aa..85fa3e0d7f935 100644 --- a/api_docs/kbn_core_application_browser_internal.mdx +++ b/api_docs/kbn_core_application_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-internal title: "@kbn/core-application-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser-internal'] --- import kbnCoreApplicationBrowserInternalObj from './kbn_core_application_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser_mocks.mdx b/api_docs/kbn_core_application_browser_mocks.mdx index 9e617b857cfe8..160327c3e75a0 100644 --- a/api_docs/kbn_core_application_browser_mocks.mdx +++ b/api_docs/kbn_core_application_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-mocks title: "@kbn/core-application-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser-mocks'] --- import kbnCoreApplicationBrowserMocksObj from './kbn_core_application_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_application_common.mdx b/api_docs/kbn_core_application_common.mdx index fb70ab512b203..5e3a390fb8ae9 100644 --- a/api_docs/kbn_core_application_common.mdx +++ b/api_docs/kbn_core_application_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-common title: "@kbn/core-application-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-common plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-common'] --- import kbnCoreApplicationCommonObj from './kbn_core_application_common.devdocs.json'; diff --git a/api_docs/kbn_core_apps_browser_internal.mdx b/api_docs/kbn_core_apps_browser_internal.mdx index 06c24e6dec2f3..2d6ffa13a4f6a 100644 --- a/api_docs/kbn_core_apps_browser_internal.mdx +++ b/api_docs/kbn_core_apps_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-internal title: "@kbn/core-apps-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-browser-internal'] --- import kbnCoreAppsBrowserInternalObj from './kbn_core_apps_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_apps_browser_mocks.mdx b/api_docs/kbn_core_apps_browser_mocks.mdx index 57cde218ed910..3ef896542209e 100644 --- a/api_docs/kbn_core_apps_browser_mocks.mdx +++ b/api_docs/kbn_core_apps_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-mocks title: "@kbn/core-apps-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-browser-mocks'] --- import kbnCoreAppsBrowserMocksObj from './kbn_core_apps_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_apps_server_internal.mdx b/api_docs/kbn_core_apps_server_internal.mdx index 2f9e033f81f35..76e75f50f34e1 100644 --- a/api_docs/kbn_core_apps_server_internal.mdx +++ b/api_docs/kbn_core_apps_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-server-internal title: "@kbn/core-apps-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-server-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-server-internal'] --- import kbnCoreAppsServerInternalObj from './kbn_core_apps_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_base_browser_mocks.mdx b/api_docs/kbn_core_base_browser_mocks.mdx index fd21d52c3f49f..b349246244e69 100644 --- a/api_docs/kbn_core_base_browser_mocks.mdx +++ b/api_docs/kbn_core_base_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-browser-mocks title: "@kbn/core-base-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-browser-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-browser-mocks'] --- import kbnCoreBaseBrowserMocksObj from './kbn_core_base_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_base_common.mdx b/api_docs/kbn_core_base_common.mdx index 87dbae0e75558..a88467df074b6 100644 --- a/api_docs/kbn_core_base_common.mdx +++ b/api_docs/kbn_core_base_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-common title: "@kbn/core-base-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-common plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-common'] --- import kbnCoreBaseCommonObj from './kbn_core_base_common.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_internal.mdx b/api_docs/kbn_core_base_server_internal.mdx index a80a78f266cef..5df1006cd91c1 100644 --- a/api_docs/kbn_core_base_server_internal.mdx +++ b/api_docs/kbn_core_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-internal title: "@kbn/core-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-internal'] --- import kbnCoreBaseServerInternalObj from './kbn_core_base_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_mocks.mdx b/api_docs/kbn_core_base_server_mocks.mdx index 4c9a5171e53c5..9a8a251629944 100644 --- a/api_docs/kbn_core_base_server_mocks.mdx +++ b/api_docs/kbn_core_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-mocks title: "@kbn/core-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-mocks'] --- import kbnCoreBaseServerMocksObj from './kbn_core_base_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_browser_mocks.mdx b/api_docs/kbn_core_capabilities_browser_mocks.mdx index 872e7b659bcec..8dbd52acc2524 100644 --- a/api_docs/kbn_core_capabilities_browser_mocks.mdx +++ b/api_docs/kbn_core_capabilities_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-browser-mocks title: "@kbn/core-capabilities-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-browser-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-browser-mocks'] --- import kbnCoreCapabilitiesBrowserMocksObj from './kbn_core_capabilities_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_common.mdx b/api_docs/kbn_core_capabilities_common.mdx index a8c1a06c9e724..ab0ef9ae1a0c5 100644 --- a/api_docs/kbn_core_capabilities_common.mdx +++ b/api_docs/kbn_core_capabilities_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-common title: "@kbn/core-capabilities-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-common plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-common'] --- import kbnCoreCapabilitiesCommonObj from './kbn_core_capabilities_common.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server.mdx b/api_docs/kbn_core_capabilities_server.mdx index f243b980ec621..6d28bd7cf4028 100644 --- a/api_docs/kbn_core_capabilities_server.mdx +++ b/api_docs/kbn_core_capabilities_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server title: "@kbn/core-capabilities-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server'] --- import kbnCoreCapabilitiesServerObj from './kbn_core_capabilities_server.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server_mocks.mdx b/api_docs/kbn_core_capabilities_server_mocks.mdx index 6828ca933412f..a24a759643bae 100644 --- a/api_docs/kbn_core_capabilities_server_mocks.mdx +++ b/api_docs/kbn_core_capabilities_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server-mocks title: "@kbn/core-capabilities-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server-mocks'] --- import kbnCoreCapabilitiesServerMocksObj from './kbn_core_capabilities_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser.mdx b/api_docs/kbn_core_chrome_browser.mdx index ce7ffad8d42b2..f672a2ed5cf29 100644 --- a/api_docs/kbn_core_chrome_browser.mdx +++ b/api_docs/kbn_core_chrome_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser title: "@kbn/core-chrome-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-chrome-browser'] --- import kbnCoreChromeBrowserObj from './kbn_core_chrome_browser.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser_mocks.mdx b/api_docs/kbn_core_chrome_browser_mocks.mdx index 333fe8565485e..8e410c374cd45 100644 --- a/api_docs/kbn_core_chrome_browser_mocks.mdx +++ b/api_docs/kbn_core_chrome_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser-mocks title: "@kbn/core-chrome-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-chrome-browser-mocks'] --- import kbnCoreChromeBrowserMocksObj from './kbn_core_chrome_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_config_server_internal.mdx b/api_docs/kbn_core_config_server_internal.mdx index ae2beb727c431..293788a5bc40d 100644 --- a/api_docs/kbn_core_config_server_internal.mdx +++ b/api_docs/kbn_core_config_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-config-server-internal title: "@kbn/core-config-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-config-server-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-config-server-internal'] --- import kbnCoreConfigServerInternalObj from './kbn_core_config_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser.mdx b/api_docs/kbn_core_deprecations_browser.mdx index 0fd0d145f9bd0..0703652536749 100644 --- a/api_docs/kbn_core_deprecations_browser.mdx +++ b/api_docs/kbn_core_deprecations_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser title: "@kbn/core-deprecations-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser'] --- import kbnCoreDeprecationsBrowserObj from './kbn_core_deprecations_browser.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_internal.mdx b/api_docs/kbn_core_deprecations_browser_internal.mdx index d39b2a261712c..10469e6c2cc5a 100644 --- a/api_docs/kbn_core_deprecations_browser_internal.mdx +++ b/api_docs/kbn_core_deprecations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-internal title: "@kbn/core-deprecations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-internal'] --- import kbnCoreDeprecationsBrowserInternalObj from './kbn_core_deprecations_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_mocks.mdx b/api_docs/kbn_core_deprecations_browser_mocks.mdx index b3fd6253f8010..f2fd26ce2a2a2 100644 --- a/api_docs/kbn_core_deprecations_browser_mocks.mdx +++ b/api_docs/kbn_core_deprecations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-mocks title: "@kbn/core-deprecations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-mocks'] --- import kbnCoreDeprecationsBrowserMocksObj from './kbn_core_deprecations_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_common.mdx b/api_docs/kbn_core_deprecations_common.mdx index d1cceba47468d..b61676bfa6372 100644 --- a/api_docs/kbn_core_deprecations_common.mdx +++ b/api_docs/kbn_core_deprecations_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-common title: "@kbn/core-deprecations-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-common plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-common'] --- import kbnCoreDeprecationsCommonObj from './kbn_core_deprecations_common.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server.mdx b/api_docs/kbn_core_deprecations_server.mdx index b4f8af3d056d0..0bc0005f52787 100644 --- a/api_docs/kbn_core_deprecations_server.mdx +++ b/api_docs/kbn_core_deprecations_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server title: "@kbn/core-deprecations-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server'] --- import kbnCoreDeprecationsServerObj from './kbn_core_deprecations_server.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server_internal.mdx b/api_docs/kbn_core_deprecations_server_internal.mdx index cccd51bf32540..f08477e6c30fd 100644 --- a/api_docs/kbn_core_deprecations_server_internal.mdx +++ b/api_docs/kbn_core_deprecations_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-internal title: "@kbn/core-deprecations-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server-internal'] --- import kbnCoreDeprecationsServerInternalObj from './kbn_core_deprecations_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server_mocks.mdx b/api_docs/kbn_core_deprecations_server_mocks.mdx index 33c846e27475d..1b026808412fa 100644 --- a/api_docs/kbn_core_deprecations_server_mocks.mdx +++ b/api_docs/kbn_core_deprecations_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-mocks title: "@kbn/core-deprecations-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server-mocks'] --- import kbnCoreDeprecationsServerMocksObj from './kbn_core_deprecations_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser.mdx b/api_docs/kbn_core_doc_links_browser.mdx index 68f68551a9ba4..009a19ea44e56 100644 --- a/api_docs/kbn_core_doc_links_browser.mdx +++ b/api_docs/kbn_core_doc_links_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser title: "@kbn/core-doc-links-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser'] --- import kbnCoreDocLinksBrowserObj from './kbn_core_doc_links_browser.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser_mocks.mdx b/api_docs/kbn_core_doc_links_browser_mocks.mdx index 7c4df83bc1215..532516320594f 100644 --- a/api_docs/kbn_core_doc_links_browser_mocks.mdx +++ b/api_docs/kbn_core_doc_links_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser-mocks title: "@kbn/core-doc-links-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser-mocks'] --- import kbnCoreDocLinksBrowserMocksObj from './kbn_core_doc_links_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server.mdx b/api_docs/kbn_core_doc_links_server.mdx index 0f6af09a74ca5..c81171e491934 100644 --- a/api_docs/kbn_core_doc_links_server.mdx +++ b/api_docs/kbn_core_doc_links_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server title: "@kbn/core-doc-links-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server'] --- import kbnCoreDocLinksServerObj from './kbn_core_doc_links_server.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server_mocks.mdx b/api_docs/kbn_core_doc_links_server_mocks.mdx index 4f472412bdd8b..473fd5bdbd193 100644 --- a/api_docs/kbn_core_doc_links_server_mocks.mdx +++ b/api_docs/kbn_core_doc_links_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server-mocks title: "@kbn/core-doc-links-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server-mocks'] --- import kbnCoreDocLinksServerMocksObj from './kbn_core_doc_links_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx index 63744d087509d..b5275e8aa00fb 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-internal title: "@kbn/core-elasticsearch-client-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-internal'] --- import kbnCoreElasticsearchClientServerInternalObj from './kbn_core_elasticsearch_client_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx index d3a648b7fdfd9..33bd7088a4f99 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-mocks title: "@kbn/core-elasticsearch-client-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-mocks'] --- import kbnCoreElasticsearchClientServerMocksObj from './kbn_core_elasticsearch_client_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server.mdx b/api_docs/kbn_core_elasticsearch_server.mdx index e746c5322c337..e212dbecd1747 100644 --- a/api_docs/kbn_core_elasticsearch_server.mdx +++ b/api_docs/kbn_core_elasticsearch_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server title: "@kbn/core-elasticsearch-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server'] --- import kbnCoreElasticsearchServerObj from './kbn_core_elasticsearch_server.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server_internal.mdx b/api_docs/kbn_core_elasticsearch_server_internal.mdx index 92b2d6dde7365..0619ef91465ff 100644 --- a/api_docs/kbn_core_elasticsearch_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-internal title: "@kbn/core-elasticsearch-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-internal'] --- import kbnCoreElasticsearchServerInternalObj from './kbn_core_elasticsearch_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_server_mocks.mdx index 2c5f9df73db81..aae99cc209af1 100644 --- a/api_docs/kbn_core_elasticsearch_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-mocks title: "@kbn/core-elasticsearch-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-mocks'] --- import kbnCoreElasticsearchServerMocksObj from './kbn_core_elasticsearch_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_environment_server_internal.mdx b/api_docs/kbn_core_environment_server_internal.mdx index d905712e08c31..dda2348e09059 100644 --- a/api_docs/kbn_core_environment_server_internal.mdx +++ b/api_docs/kbn_core_environment_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-internal title: "@kbn/core-environment-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-internal'] --- import kbnCoreEnvironmentServerInternalObj from './kbn_core_environment_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_environment_server_mocks.mdx b/api_docs/kbn_core_environment_server_mocks.mdx index 8f7ae5491b91d..d93d428bb6cd8 100644 --- a/api_docs/kbn_core_environment_server_mocks.mdx +++ b/api_docs/kbn_core_environment_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-mocks title: "@kbn/core-environment-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-mocks'] --- import kbnCoreEnvironmentServerMocksObj from './kbn_core_environment_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser.mdx b/api_docs/kbn_core_execution_context_browser.mdx index d934b7bb79687..f6816a16cd2c0 100644 --- a/api_docs/kbn_core_execution_context_browser.mdx +++ b/api_docs/kbn_core_execution_context_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser title: "@kbn/core-execution-context-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser'] --- import kbnCoreExecutionContextBrowserObj from './kbn_core_execution_context_browser.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser_internal.mdx b/api_docs/kbn_core_execution_context_browser_internal.mdx index bf240bdd9f054..f27ba64cbd6e1 100644 --- a/api_docs/kbn_core_execution_context_browser_internal.mdx +++ b/api_docs/kbn_core_execution_context_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-internal title: "@kbn/core-execution-context-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-internal'] --- import kbnCoreExecutionContextBrowserInternalObj from './kbn_core_execution_context_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser_mocks.mdx b/api_docs/kbn_core_execution_context_browser_mocks.mdx index d875d5253be7a..7484b7ada0521 100644 --- a/api_docs/kbn_core_execution_context_browser_mocks.mdx +++ b/api_docs/kbn_core_execution_context_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-mocks title: "@kbn/core-execution-context-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-mocks'] --- import kbnCoreExecutionContextBrowserMocksObj from './kbn_core_execution_context_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_common.mdx b/api_docs/kbn_core_execution_context_common.mdx index 7554063a4cb50..41ee6ef9680bf 100644 --- a/api_docs/kbn_core_execution_context_common.mdx +++ b/api_docs/kbn_core_execution_context_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-common title: "@kbn/core-execution-context-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-common plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-common'] --- import kbnCoreExecutionContextCommonObj from './kbn_core_execution_context_common.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server.mdx b/api_docs/kbn_core_execution_context_server.mdx index bb741053c2df8..f5665a2eb87e9 100644 --- a/api_docs/kbn_core_execution_context_server.mdx +++ b/api_docs/kbn_core_execution_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server title: "@kbn/core-execution-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server'] --- import kbnCoreExecutionContextServerObj from './kbn_core_execution_context_server.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server_internal.mdx b/api_docs/kbn_core_execution_context_server_internal.mdx index ad67db44a5615..c66e9f6c4aa2c 100644 --- a/api_docs/kbn_core_execution_context_server_internal.mdx +++ b/api_docs/kbn_core_execution_context_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-internal title: "@kbn/core-execution-context-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-internal'] --- import kbnCoreExecutionContextServerInternalObj from './kbn_core_execution_context_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server_mocks.mdx b/api_docs/kbn_core_execution_context_server_mocks.mdx index 50ee73e86694d..d4d3dce50c9aa 100644 --- a/api_docs/kbn_core_execution_context_server_mocks.mdx +++ b/api_docs/kbn_core_execution_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-mocks title: "@kbn/core-execution-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-mocks'] --- import kbnCoreExecutionContextServerMocksObj from './kbn_core_execution_context_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_fatal_errors_browser.mdx b/api_docs/kbn_core_fatal_errors_browser.mdx index 7cd7156000f04..b3d43a02ddb43 100644 --- a/api_docs/kbn_core_fatal_errors_browser.mdx +++ b/api_docs/kbn_core_fatal_errors_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser title: "@kbn/core-fatal-errors-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser'] --- import kbnCoreFatalErrorsBrowserObj from './kbn_core_fatal_errors_browser.devdocs.json'; diff --git a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx index a38a0fce2de59..346c050ce131b 100644 --- a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx +++ b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser-mocks title: "@kbn/core-fatal-errors-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser-mocks'] --- import kbnCoreFatalErrorsBrowserMocksObj from './kbn_core_fatal_errors_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser.mdx b/api_docs/kbn_core_http_browser.mdx index 76a522d4eca03..adc6aec485fad 100644 --- a/api_docs/kbn_core_http_browser.mdx +++ b/api_docs/kbn_core_http_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser title: "@kbn/core-http-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser'] --- import kbnCoreHttpBrowserObj from './kbn_core_http_browser.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser_internal.mdx b/api_docs/kbn_core_http_browser_internal.mdx index 9118df8ff644e..887b04436e344 100644 --- a/api_docs/kbn_core_http_browser_internal.mdx +++ b/api_docs/kbn_core_http_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-internal title: "@kbn/core-http-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-internal'] --- import kbnCoreHttpBrowserInternalObj from './kbn_core_http_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser_mocks.mdx b/api_docs/kbn_core_http_browser_mocks.mdx index bab2376399243..a8ea881fe65d9 100644 --- a/api_docs/kbn_core_http_browser_mocks.mdx +++ b/api_docs/kbn_core_http_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-mocks title: "@kbn/core-http-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-mocks'] --- import kbnCoreHttpBrowserMocksObj from './kbn_core_http_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_common.mdx b/api_docs/kbn_core_http_common.mdx index a33ce776e8e5b..8eb238f135f8e 100644 --- a/api_docs/kbn_core_http_common.mdx +++ b/api_docs/kbn_core_http_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-common title: "@kbn/core-http-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-common plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-common'] --- import kbnCoreHttpCommonObj from './kbn_core_http_common.devdocs.json'; diff --git a/api_docs/kbn_core_http_context_server_mocks.mdx b/api_docs/kbn_core_http_context_server_mocks.mdx index bd055bed28bbc..8d66471bf2428 100644 --- a/api_docs/kbn_core_http_context_server_mocks.mdx +++ b/api_docs/kbn_core_http_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-context-server-mocks title: "@kbn/core-http-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-context-server-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-context-server-mocks'] --- import kbnCoreHttpContextServerMocksObj from './kbn_core_http_context_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_request_handler_context_server.mdx b/api_docs/kbn_core_http_request_handler_context_server.mdx index 28fcd57a5f38d..df50f32cd64cd 100644 --- a/api_docs/kbn_core_http_request_handler_context_server.mdx +++ b/api_docs/kbn_core_http_request_handler_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-request-handler-context-server title: "@kbn/core-http-request-handler-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-request-handler-context-server plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-request-handler-context-server'] --- import kbnCoreHttpRequestHandlerContextServerObj from './kbn_core_http_request_handler_context_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server.mdx b/api_docs/kbn_core_http_resources_server.mdx index 52ff60dfaddfc..d0a9c57a2f7f9 100644 --- a/api_docs/kbn_core_http_resources_server.mdx +++ b/api_docs/kbn_core_http_resources_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server title: "@kbn/core-http-resources-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server'] --- import kbnCoreHttpResourcesServerObj from './kbn_core_http_resources_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server_internal.mdx b/api_docs/kbn_core_http_resources_server_internal.mdx index 003723baf0962..fcfe1776d0629 100644 --- a/api_docs/kbn_core_http_resources_server_internal.mdx +++ b/api_docs/kbn_core_http_resources_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-internal title: "@kbn/core-http-resources-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server-internal'] --- import kbnCoreHttpResourcesServerInternalObj from './kbn_core_http_resources_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server_mocks.mdx b/api_docs/kbn_core_http_resources_server_mocks.mdx index 76944528962cf..b5982fe7e2fb5 100644 --- a/api_docs/kbn_core_http_resources_server_mocks.mdx +++ b/api_docs/kbn_core_http_resources_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-mocks title: "@kbn/core-http-resources-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server-mocks'] --- import kbnCoreHttpResourcesServerMocksObj from './kbn_core_http_resources_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_router_server_internal.mdx b/api_docs/kbn_core_http_router_server_internal.mdx index a072eca8454c9..651fa802b5f1b 100644 --- a/api_docs/kbn_core_http_router_server_internal.mdx +++ b/api_docs/kbn_core_http_router_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-internal title: "@kbn/core-http-router-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-internal'] --- import kbnCoreHttpRouterServerInternalObj from './kbn_core_http_router_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_router_server_mocks.mdx b/api_docs/kbn_core_http_router_server_mocks.mdx index e00cb4d0c9e51..ce3c5fd03425b 100644 --- a/api_docs/kbn_core_http_router_server_mocks.mdx +++ b/api_docs/kbn_core_http_router_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-mocks title: "@kbn/core-http-router-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-mocks'] --- import kbnCoreHttpRouterServerMocksObj from './kbn_core_http_router_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_server.mdx b/api_docs/kbn_core_http_server.mdx index 42b0cb168a4bb..b40387f70004c 100644 --- a/api_docs/kbn_core_http_server.mdx +++ b/api_docs/kbn_core_http_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server title: "@kbn/core-http-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server'] --- import kbnCoreHttpServerObj from './kbn_core_http_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_server_internal.mdx b/api_docs/kbn_core_http_server_internal.mdx index f3823bc677458..d4b8d224f4c70 100644 --- a/api_docs/kbn_core_http_server_internal.mdx +++ b/api_docs/kbn_core_http_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-internal title: "@kbn/core-http-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-internal'] --- import kbnCoreHttpServerInternalObj from './kbn_core_http_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_server_mocks.mdx b/api_docs/kbn_core_http_server_mocks.mdx index 25ee758ebf646..f475dd8c34066 100644 --- a/api_docs/kbn_core_http_server_mocks.mdx +++ b/api_docs/kbn_core_http_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-mocks title: "@kbn/core-http-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-mocks'] --- import kbnCoreHttpServerMocksObj from './kbn_core_http_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_browser.mdx b/api_docs/kbn_core_i18n_browser.mdx index dfc344ca4f136..561f6c658c979 100644 --- a/api_docs/kbn_core_i18n_browser.mdx +++ b/api_docs/kbn_core_i18n_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser title: "@kbn/core-i18n-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser'] --- import kbnCoreI18nBrowserObj from './kbn_core_i18n_browser.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_browser_mocks.mdx b/api_docs/kbn_core_i18n_browser_mocks.mdx index a7dc446696dad..e62002bc377f7 100644 --- a/api_docs/kbn_core_i18n_browser_mocks.mdx +++ b/api_docs/kbn_core_i18n_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser-mocks title: "@kbn/core-i18n-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser-mocks'] --- import kbnCoreI18nBrowserMocksObj from './kbn_core_i18n_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server.mdx b/api_docs/kbn_core_i18n_server.mdx index 0348097dd34a6..317d1f330d952 100644 --- a/api_docs/kbn_core_i18n_server.mdx +++ b/api_docs/kbn_core_i18n_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server title: "@kbn/core-i18n-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server'] --- import kbnCoreI18nServerObj from './kbn_core_i18n_server.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server_internal.mdx b/api_docs/kbn_core_i18n_server_internal.mdx index 61b58a74d2b60..a4238639bbb67 100644 --- a/api_docs/kbn_core_i18n_server_internal.mdx +++ b/api_docs/kbn_core_i18n_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-internal title: "@kbn/core-i18n-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server-internal'] --- import kbnCoreI18nServerInternalObj from './kbn_core_i18n_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server_mocks.mdx b/api_docs/kbn_core_i18n_server_mocks.mdx index cb75ed42018f8..db5aca875202f 100644 --- a/api_docs/kbn_core_i18n_server_mocks.mdx +++ b/api_docs/kbn_core_i18n_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-mocks title: "@kbn/core-i18n-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server-mocks'] --- import kbnCoreI18nServerMocksObj from './kbn_core_i18n_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_injected_metadata_browser.mdx b/api_docs/kbn_core_injected_metadata_browser.mdx index 4bb70ca9d64a7..a31e12d7c934e 100644 --- a/api_docs/kbn_core_injected_metadata_browser.mdx +++ b/api_docs/kbn_core_injected_metadata_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-injected-metadata-browser title: "@kbn/core-injected-metadata-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-injected-metadata-browser plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-injected-metadata-browser'] --- import kbnCoreInjectedMetadataBrowserObj from './kbn_core_injected_metadata_browser.devdocs.json'; diff --git a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx index c4bd5559fb542..894a9385c3839 100644 --- a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx +++ b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-injected-metadata-browser-mocks title: "@kbn/core-injected-metadata-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-injected-metadata-browser-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-injected-metadata-browser-mocks'] --- import kbnCoreInjectedMetadataBrowserMocksObj from './kbn_core_injected_metadata_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_integrations_browser_internal.mdx b/api_docs/kbn_core_integrations_browser_internal.mdx index a80e801e1c56a..9095becc0e879 100644 --- a/api_docs/kbn_core_integrations_browser_internal.mdx +++ b/api_docs/kbn_core_integrations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-internal title: "@kbn/core-integrations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-integrations-browser-internal'] --- import kbnCoreIntegrationsBrowserInternalObj from './kbn_core_integrations_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_integrations_browser_mocks.mdx b/api_docs/kbn_core_integrations_browser_mocks.mdx index 8d633d69edbd8..de1f712ae8f1b 100644 --- a/api_docs/kbn_core_integrations_browser_mocks.mdx +++ b/api_docs/kbn_core_integrations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-mocks title: "@kbn/core-integrations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-integrations-browser-mocks'] --- import kbnCoreIntegrationsBrowserMocksObj from './kbn_core_integrations_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_browser.mdx b/api_docs/kbn_core_lifecycle_browser.mdx index d89918520e374..cafc6f20630e7 100644 --- a/api_docs/kbn_core_lifecycle_browser.mdx +++ b/api_docs/kbn_core_lifecycle_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser title: "@kbn/core-lifecycle-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-browser'] --- import kbnCoreLifecycleBrowserObj from './kbn_core_lifecycle_browser.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_browser_mocks.mdx b/api_docs/kbn_core_lifecycle_browser_mocks.mdx index 0e264ea94fd62..2f7726ffc1bc9 100644 --- a/api_docs/kbn_core_lifecycle_browser_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser-mocks title: "@kbn/core-lifecycle-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-browser-mocks'] --- import kbnCoreLifecycleBrowserMocksObj from './kbn_core_lifecycle_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_server.mdx b/api_docs/kbn_core_lifecycle_server.mdx index c718afd217eb5..31e9b24ead87d 100644 --- a/api_docs/kbn_core_lifecycle_server.mdx +++ b/api_docs/kbn_core_lifecycle_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server title: "@kbn/core-lifecycle-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-server'] --- import kbnCoreLifecycleServerObj from './kbn_core_lifecycle_server.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_server_mocks.mdx b/api_docs/kbn_core_lifecycle_server_mocks.mdx index ded04f346c0e6..99f55b5b93d0f 100644 --- a/api_docs/kbn_core_lifecycle_server_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server-mocks title: "@kbn/core-lifecycle-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-server-mocks'] --- import kbnCoreLifecycleServerMocksObj from './kbn_core_lifecycle_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_logging_browser_mocks.mdx b/api_docs/kbn_core_logging_browser_mocks.mdx index 4daa57807ebd0..142a90ab579bb 100644 --- a/api_docs/kbn_core_logging_browser_mocks.mdx +++ b/api_docs/kbn_core_logging_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-browser-mocks title: "@kbn/core-logging-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-browser-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-browser-mocks'] --- import kbnCoreLoggingBrowserMocksObj from './kbn_core_logging_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_logging_common_internal.mdx b/api_docs/kbn_core_logging_common_internal.mdx index 80fe581a042e1..663c608fac979 100644 --- a/api_docs/kbn_core_logging_common_internal.mdx +++ b/api_docs/kbn_core_logging_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-common-internal title: "@kbn/core-logging-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-common-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-common-internal'] --- import kbnCoreLoggingCommonInternalObj from './kbn_core_logging_common_internal.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server.mdx b/api_docs/kbn_core_logging_server.mdx index a1c07c85165bb..deb4fb1b4059f 100644 --- a/api_docs/kbn_core_logging_server.mdx +++ b/api_docs/kbn_core_logging_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server title: "@kbn/core-logging-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server'] --- import kbnCoreLoggingServerObj from './kbn_core_logging_server.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server_internal.mdx b/api_docs/kbn_core_logging_server_internal.mdx index 01f15e5eaeb6a..94a15c91bf5e0 100644 --- a/api_docs/kbn_core_logging_server_internal.mdx +++ b/api_docs/kbn_core_logging_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-internal title: "@kbn/core-logging-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-internal'] --- import kbnCoreLoggingServerInternalObj from './kbn_core_logging_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server_mocks.mdx b/api_docs/kbn_core_logging_server_mocks.mdx index c68b3be5767f0..5f689ce204902 100644 --- a/api_docs/kbn_core_logging_server_mocks.mdx +++ b/api_docs/kbn_core_logging_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-mocks title: "@kbn/core-logging-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-mocks'] --- import kbnCoreLoggingServerMocksObj from './kbn_core_logging_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_collectors_server_internal.mdx b/api_docs/kbn_core_metrics_collectors_server_internal.mdx index 2fdeaf591126d..fafc7916a9880 100644 --- a/api_docs/kbn_core_metrics_collectors_server_internal.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-internal title: "@kbn/core-metrics-collectors-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-collectors-server-internal'] --- import kbnCoreMetricsCollectorsServerInternalObj from './kbn_core_metrics_collectors_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx index 257f1a6d7b50a..be01e12a7db97 100644 --- a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-mocks title: "@kbn/core-metrics-collectors-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-collectors-server-mocks'] --- import kbnCoreMetricsCollectorsServerMocksObj from './kbn_core_metrics_collectors_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server.mdx b/api_docs/kbn_core_metrics_server.mdx index cca5e84f387c1..3af95c647d79b 100644 --- a/api_docs/kbn_core_metrics_server.mdx +++ b/api_docs/kbn_core_metrics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server title: "@kbn/core-metrics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server'] --- import kbnCoreMetricsServerObj from './kbn_core_metrics_server.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server_internal.mdx b/api_docs/kbn_core_metrics_server_internal.mdx index f243656c5170c..6761e13376562 100644 --- a/api_docs/kbn_core_metrics_server_internal.mdx +++ b/api_docs/kbn_core_metrics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-internal title: "@kbn/core-metrics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server-internal'] --- import kbnCoreMetricsServerInternalObj from './kbn_core_metrics_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server_mocks.mdx b/api_docs/kbn_core_metrics_server_mocks.mdx index ad61b8805ce20..d3877477dde44 100644 --- a/api_docs/kbn_core_metrics_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-mocks title: "@kbn/core-metrics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server-mocks'] --- import kbnCoreMetricsServerMocksObj from './kbn_core_metrics_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_mount_utils_browser.mdx b/api_docs/kbn_core_mount_utils_browser.mdx index cc67c969aa74e..5b8ec23210d75 100644 --- a/api_docs/kbn_core_mount_utils_browser.mdx +++ b/api_docs/kbn_core_mount_utils_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-mount-utils-browser title: "@kbn/core-mount-utils-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-mount-utils-browser plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-mount-utils-browser'] --- import kbnCoreMountUtilsBrowserObj from './kbn_core_mount_utils_browser.devdocs.json'; diff --git a/api_docs/kbn_core_node_server.mdx b/api_docs/kbn_core_node_server.mdx index c70487b056f69..075191f0d1526 100644 --- a/api_docs/kbn_core_node_server.mdx +++ b/api_docs/kbn_core_node_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server title: "@kbn/core-node-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server'] --- import kbnCoreNodeServerObj from './kbn_core_node_server.devdocs.json'; diff --git a/api_docs/kbn_core_node_server_internal.mdx b/api_docs/kbn_core_node_server_internal.mdx index 6e977bfa546f4..cfe7b9124f84c 100644 --- a/api_docs/kbn_core_node_server_internal.mdx +++ b/api_docs/kbn_core_node_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-internal title: "@kbn/core-node-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server-internal'] --- import kbnCoreNodeServerInternalObj from './kbn_core_node_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_node_server_mocks.mdx b/api_docs/kbn_core_node_server_mocks.mdx index eb1dbabe16886..cddfe3e1f18ad 100644 --- a/api_docs/kbn_core_node_server_mocks.mdx +++ b/api_docs/kbn_core_node_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-mocks title: "@kbn/core-node-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server-mocks'] --- import kbnCoreNodeServerMocksObj from './kbn_core_node_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser.mdx b/api_docs/kbn_core_notifications_browser.mdx index b36920c3a7653..bfcf953ccbb5a 100644 --- a/api_docs/kbn_core_notifications_browser.mdx +++ b/api_docs/kbn_core_notifications_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser title: "@kbn/core-notifications-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser'] --- import kbnCoreNotificationsBrowserObj from './kbn_core_notifications_browser.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser_internal.mdx b/api_docs/kbn_core_notifications_browser_internal.mdx index 511d3b25e9197..8c4996dd77c7f 100644 --- a/api_docs/kbn_core_notifications_browser_internal.mdx +++ b/api_docs/kbn_core_notifications_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-internal title: "@kbn/core-notifications-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser-internal'] --- import kbnCoreNotificationsBrowserInternalObj from './kbn_core_notifications_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser_mocks.mdx b/api_docs/kbn_core_notifications_browser_mocks.mdx index fba28978dd254..69677b4edf7e3 100644 --- a/api_docs/kbn_core_notifications_browser_mocks.mdx +++ b/api_docs/kbn_core_notifications_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-mocks title: "@kbn/core-notifications-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser-mocks'] --- import kbnCoreNotificationsBrowserMocksObj from './kbn_core_notifications_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser.mdx b/api_docs/kbn_core_overlays_browser.mdx index 937c446f32083..4139544d0b0ef 100644 --- a/api_docs/kbn_core_overlays_browser.mdx +++ b/api_docs/kbn_core_overlays_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser title: "@kbn/core-overlays-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser'] --- import kbnCoreOverlaysBrowserObj from './kbn_core_overlays_browser.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser_internal.mdx b/api_docs/kbn_core_overlays_browser_internal.mdx index 2ab8aeaaa4407..24d3119d0a89d 100644 --- a/api_docs/kbn_core_overlays_browser_internal.mdx +++ b/api_docs/kbn_core_overlays_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-internal title: "@kbn/core-overlays-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser-internal'] --- import kbnCoreOverlaysBrowserInternalObj from './kbn_core_overlays_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser_mocks.mdx b/api_docs/kbn_core_overlays_browser_mocks.mdx index 34f7e00350084..60a97e3ed4127 100644 --- a/api_docs/kbn_core_overlays_browser_mocks.mdx +++ b/api_docs/kbn_core_overlays_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-mocks title: "@kbn/core-overlays-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser-mocks'] --- import kbnCoreOverlaysBrowserMocksObj from './kbn_core_overlays_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_browser.mdx b/api_docs/kbn_core_plugins_browser.mdx index aa6a513394639..13a5664d073c6 100644 --- a/api_docs/kbn_core_plugins_browser.mdx +++ b/api_docs/kbn_core_plugins_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser title: "@kbn/core-plugins-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser'] --- import kbnCorePluginsBrowserObj from './kbn_core_plugins_browser.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_browser_mocks.mdx b/api_docs/kbn_core_plugins_browser_mocks.mdx index 2e00eb9e6a013..b571ddf71ef6b 100644 --- a/api_docs/kbn_core_plugins_browser_mocks.mdx +++ b/api_docs/kbn_core_plugins_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser-mocks title: "@kbn/core-plugins-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser-mocks'] --- import kbnCorePluginsBrowserMocksObj from './kbn_core_plugins_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_server.mdx b/api_docs/kbn_core_plugins_server.mdx index 66fb1fcf765d3..c71e001357f75 100644 --- a/api_docs/kbn_core_plugins_server.mdx +++ b/api_docs/kbn_core_plugins_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server title: "@kbn/core-plugins-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-server'] --- import kbnCorePluginsServerObj from './kbn_core_plugins_server.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_server_mocks.mdx b/api_docs/kbn_core_plugins_server_mocks.mdx index 9a89a05323a30..51990b39a6a99 100644 --- a/api_docs/kbn_core_plugins_server_mocks.mdx +++ b/api_docs/kbn_core_plugins_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server-mocks title: "@kbn/core-plugins-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-server-mocks'] --- import kbnCorePluginsServerMocksObj from './kbn_core_plugins_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_preboot_server.mdx b/api_docs/kbn_core_preboot_server.mdx index b9508fd323f05..4825a594e637b 100644 --- a/api_docs/kbn_core_preboot_server.mdx +++ b/api_docs/kbn_core_preboot_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server title: "@kbn/core-preboot-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-preboot-server'] --- import kbnCorePrebootServerObj from './kbn_core_preboot_server.devdocs.json'; diff --git a/api_docs/kbn_core_preboot_server_mocks.mdx b/api_docs/kbn_core_preboot_server_mocks.mdx index 54d52da2cf241..7978c224019f0 100644 --- a/api_docs/kbn_core_preboot_server_mocks.mdx +++ b/api_docs/kbn_core_preboot_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server-mocks title: "@kbn/core-preboot-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-preboot-server-mocks'] --- import kbnCorePrebootServerMocksObj from './kbn_core_preboot_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_browser_mocks.mdx b/api_docs/kbn_core_rendering_browser_mocks.mdx index 485dfbf9ab419..ed0d1bc0e4260 100644 --- a/api_docs/kbn_core_rendering_browser_mocks.mdx +++ b/api_docs/kbn_core_rendering_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-browser-mocks title: "@kbn/core-rendering-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-browser-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-browser-mocks'] --- import kbnCoreRenderingBrowserMocksObj from './kbn_core_rendering_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_server_internal.mdx b/api_docs/kbn_core_rendering_server_internal.mdx index 0f27b3a4760df..e6c13e9a8f95d 100644 --- a/api_docs/kbn_core_rendering_server_internal.mdx +++ b/api_docs/kbn_core_rendering_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-internal title: "@kbn/core-rendering-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-server-internal'] --- import kbnCoreRenderingServerInternalObj from './kbn_core_rendering_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_server_mocks.mdx b/api_docs/kbn_core_rendering_server_mocks.mdx index 51f8a59803f9e..f7ef09383fd1e 100644 --- a/api_docs/kbn_core_rendering_server_mocks.mdx +++ b/api_docs/kbn_core_rendering_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-mocks title: "@kbn/core-rendering-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-server-mocks'] --- import kbnCoreRenderingServerMocksObj from './kbn_core_rendering_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_browser.mdx b/api_docs/kbn_core_saved_objects_api_browser.mdx index aa11edf4360a2..7a6bef562b961 100644 --- a/api_docs/kbn_core_saved_objects_api_browser.mdx +++ b/api_docs/kbn_core_saved_objects_api_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-browser title: "@kbn/core-saved-objects-api-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-browser plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-browser'] --- import kbnCoreSavedObjectsApiBrowserObj from './kbn_core_saved_objects_api_browser.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server.mdx b/api_docs/kbn_core_saved_objects_api_server.mdx index cef9bedd2cf94..39838c6c43e72 100644 --- a/api_docs/kbn_core_saved_objects_api_server.mdx +++ b/api_docs/kbn_core_saved_objects_api_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server title: "@kbn/core-saved-objects-api-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server'] --- import kbnCoreSavedObjectsApiServerObj from './kbn_core_saved_objects_api_server.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server_internal.mdx b/api_docs/kbn_core_saved_objects_api_server_internal.mdx index ac6cfd8104896..10385c3c18d2a 100644 --- a/api_docs/kbn_core_saved_objects_api_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_api_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server-internal title: "@kbn/core-saved-objects-api-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server-internal'] --- import kbnCoreSavedObjectsApiServerInternalObj from './kbn_core_saved_objects_api_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx index 7e6eb3ec7e296..94a7930fec06b 100644 --- a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server-mocks title: "@kbn/core-saved-objects-api-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server-mocks'] --- import kbnCoreSavedObjectsApiServerMocksObj from './kbn_core_saved_objects_api_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_base_server_internal.mdx b/api_docs/kbn_core_saved_objects_base_server_internal.mdx index 03a440f60ec5c..d606aafa75e76 100644 --- a/api_docs/kbn_core_saved_objects_base_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-internal title: "@kbn/core-saved-objects-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-base-server-internal'] --- import kbnCoreSavedObjectsBaseServerInternalObj from './kbn_core_saved_objects_base_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx index 7028bf5e77a13..da6f0285c7bc7 100644 --- a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-mocks title: "@kbn/core-saved-objects-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-base-server-mocks'] --- import kbnCoreSavedObjectsBaseServerMocksObj from './kbn_core_saved_objects_base_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser.mdx b/api_docs/kbn_core_saved_objects_browser.mdx index eed0d7d39f146..2a456892261ff 100644 --- a/api_docs/kbn_core_saved_objects_browser.mdx +++ b/api_docs/kbn_core_saved_objects_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser title: "@kbn/core-saved-objects-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser'] --- import kbnCoreSavedObjectsBrowserObj from './kbn_core_saved_objects_browser.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser_internal.mdx b/api_docs/kbn_core_saved_objects_browser_internal.mdx index 7d11724080b87..51e5f375ae791 100644 --- a/api_docs/kbn_core_saved_objects_browser_internal.mdx +++ b/api_docs/kbn_core_saved_objects_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-internal title: "@kbn/core-saved-objects-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-internal'] --- import kbnCoreSavedObjectsBrowserInternalObj from './kbn_core_saved_objects_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser_mocks.mdx b/api_docs/kbn_core_saved_objects_browser_mocks.mdx index fca87cd64e0de..69a767792f76d 100644 --- a/api_docs/kbn_core_saved_objects_browser_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-mocks title: "@kbn/core-saved-objects-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-mocks'] --- import kbnCoreSavedObjectsBrowserMocksObj from './kbn_core_saved_objects_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_common.mdx b/api_docs/kbn_core_saved_objects_common.mdx index 1a371683da5cc..f9cced1eadf4b 100644 --- a/api_docs/kbn_core_saved_objects_common.mdx +++ b/api_docs/kbn_core_saved_objects_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-common title: "@kbn/core-saved-objects-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-common plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-common'] --- import kbnCoreSavedObjectsCommonObj from './kbn_core_saved_objects_common.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx index 66b97c8b6fcac..9c9a9ccf2bb31 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-internal title: "@kbn/core-saved-objects-import-export-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-import-export-server-internal'] --- import kbnCoreSavedObjectsImportExportServerInternalObj from './kbn_core_saved_objects_import_export_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx index f5f702644b6be..04fc476913733 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-mocks title: "@kbn/core-saved-objects-import-export-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-import-export-server-mocks'] --- import kbnCoreSavedObjectsImportExportServerMocksObj from './kbn_core_saved_objects_import_export_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx index 456f52f1ccc56..5d6c32533ecbd 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-internal title: "@kbn/core-saved-objects-migration-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-migration-server-internal'] --- import kbnCoreSavedObjectsMigrationServerInternalObj from './kbn_core_saved_objects_migration_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx index 4dabda6f1bdfe..39d7c8c3e38f3 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-mocks title: "@kbn/core-saved-objects-migration-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-migration-server-mocks'] --- import kbnCoreSavedObjectsMigrationServerMocksObj from './kbn_core_saved_objects_migration_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server.mdx b/api_docs/kbn_core_saved_objects_server.mdx index 6ec1e83b817a8..59b04f730ab9b 100644 --- a/api_docs/kbn_core_saved_objects_server.mdx +++ b/api_docs/kbn_core_saved_objects_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server title: "@kbn/core-saved-objects-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server'] --- import kbnCoreSavedObjectsServerObj from './kbn_core_saved_objects_server.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server_internal.mdx b/api_docs/kbn_core_saved_objects_server_internal.mdx index 914dc4459a0cd..1370568f1f7b2 100644 --- a/api_docs/kbn_core_saved_objects_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-internal title: "@kbn/core-saved-objects-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server-internal'] --- import kbnCoreSavedObjectsServerInternalObj from './kbn_core_saved_objects_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server_mocks.mdx b/api_docs/kbn_core_saved_objects_server_mocks.mdx index 2884262be26d7..d62a9b2621c27 100644 --- a/api_docs/kbn_core_saved_objects_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-mocks title: "@kbn/core-saved-objects-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server-mocks'] --- import kbnCoreSavedObjectsServerMocksObj from './kbn_core_saved_objects_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_utils_server.mdx b/api_docs/kbn_core_saved_objects_utils_server.mdx index 6588a9fd252b6..ab50cc4a4ccb3 100644 --- a/api_docs/kbn_core_saved_objects_utils_server.mdx +++ b/api_docs/kbn_core_saved_objects_utils_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-utils-server title: "@kbn/core-saved-objects-utils-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-utils-server plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-utils-server'] --- import kbnCoreSavedObjectsUtilsServerObj from './kbn_core_saved_objects_utils_server.devdocs.json'; diff --git a/api_docs/kbn_core_status_common.mdx b/api_docs/kbn_core_status_common.mdx index c9fb44d77cddc..a6ea3b9a0d467 100644 --- a/api_docs/kbn_core_status_common.mdx +++ b/api_docs/kbn_core_status_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common title: "@kbn/core-status-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-common'] --- import kbnCoreStatusCommonObj from './kbn_core_status_common.devdocs.json'; diff --git a/api_docs/kbn_core_status_common_internal.mdx b/api_docs/kbn_core_status_common_internal.mdx index 2fddd2801e3f3..5dcdc1614eced 100644 --- a/api_docs/kbn_core_status_common_internal.mdx +++ b/api_docs/kbn_core_status_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common-internal title: "@kbn/core-status-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-common-internal'] --- import kbnCoreStatusCommonInternalObj from './kbn_core_status_common_internal.devdocs.json'; diff --git a/api_docs/kbn_core_status_server.mdx b/api_docs/kbn_core_status_server.mdx index f89bc8d977a58..532bf26fdeb13 100644 --- a/api_docs/kbn_core_status_server.mdx +++ b/api_docs/kbn_core_status_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server title: "@kbn/core-status-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server'] --- import kbnCoreStatusServerObj from './kbn_core_status_server.devdocs.json'; diff --git a/api_docs/kbn_core_status_server_internal.mdx b/api_docs/kbn_core_status_server_internal.mdx index 3cb0b73fa179d..ccee2c8aae6c6 100644 --- a/api_docs/kbn_core_status_server_internal.mdx +++ b/api_docs/kbn_core_status_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-internal title: "@kbn/core-status-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server-internal'] --- import kbnCoreStatusServerInternalObj from './kbn_core_status_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_status_server_mocks.mdx b/api_docs/kbn_core_status_server_mocks.mdx index 1fb9f5e772953..d5acf9332bbb3 100644 --- a/api_docs/kbn_core_status_server_mocks.mdx +++ b/api_docs/kbn_core_status_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-mocks title: "@kbn/core-status-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server-mocks'] --- import kbnCoreStatusServerMocksObj from './kbn_core_status_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx index 58a0e75f8d109..4430e455c62db 100644 --- a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx +++ b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-deprecations-getters title: "@kbn/core-test-helpers-deprecations-getters" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-deprecations-getters plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-deprecations-getters'] --- import kbnCoreTestHelpersDeprecationsGettersObj from './kbn_core_test_helpers_deprecations_getters.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx index 6c319eeb2a8b0..5d6f3776a5524 100644 --- a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx +++ b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-http-setup-browser title: "@kbn/core-test-helpers-http-setup-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-http-setup-browser plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-http-setup-browser'] --- import kbnCoreTestHelpersHttpSetupBrowserObj from './kbn_core_test_helpers_http_setup_browser.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx index bde5ce63233e9..dd1b669134e62 100644 --- a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx +++ b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-so-type-serializer title: "@kbn/core-test-helpers-so-type-serializer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-so-type-serializer plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-so-type-serializer'] --- import kbnCoreTestHelpersSoTypeSerializerObj from './kbn_core_test_helpers_so_type_serializer.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_test_utils.mdx b/api_docs/kbn_core_test_helpers_test_utils.mdx index 187f1a45dfd8e..4885889e561e1 100644 --- a/api_docs/kbn_core_test_helpers_test_utils.mdx +++ b/api_docs/kbn_core_test_helpers_test_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-test-utils title: "@kbn/core-test-helpers-test-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-test-utils plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-test-utils'] --- import kbnCoreTestHelpersTestUtilsObj from './kbn_core_test_helpers_test_utils.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser.mdx b/api_docs/kbn_core_theme_browser.mdx index 9878491edc07b..023aadb814a44 100644 --- a/api_docs/kbn_core_theme_browser.mdx +++ b/api_docs/kbn_core_theme_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser title: "@kbn/core-theme-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser'] --- import kbnCoreThemeBrowserObj from './kbn_core_theme_browser.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_internal.mdx b/api_docs/kbn_core_theme_browser_internal.mdx index 908d5228ca595..13e0b2fc792f4 100644 --- a/api_docs/kbn_core_theme_browser_internal.mdx +++ b/api_docs/kbn_core_theme_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-internal title: "@kbn/core-theme-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-internal'] --- import kbnCoreThemeBrowserInternalObj from './kbn_core_theme_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_mocks.mdx b/api_docs/kbn_core_theme_browser_mocks.mdx index 0ef580f50db61..06a2332a5d713 100644 --- a/api_docs/kbn_core_theme_browser_mocks.mdx +++ b/api_docs/kbn_core_theme_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-mocks title: "@kbn/core-theme-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-mocks'] --- import kbnCoreThemeBrowserMocksObj from './kbn_core_theme_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser.mdx b/api_docs/kbn_core_ui_settings_browser.mdx index 9f8c994b5290d..ea4655f88e80c 100644 --- a/api_docs/kbn_core_ui_settings_browser.mdx +++ b/api_docs/kbn_core_ui_settings_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser title: "@kbn/core-ui-settings-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser'] --- import kbnCoreUiSettingsBrowserObj from './kbn_core_ui_settings_browser.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser_internal.mdx b/api_docs/kbn_core_ui_settings_browser_internal.mdx index c0abf7f7707b0..6e033dd53a2f4 100644 --- a/api_docs/kbn_core_ui_settings_browser_internal.mdx +++ b/api_docs/kbn_core_ui_settings_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-internal title: "@kbn/core-ui-settings-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser-internal'] --- import kbnCoreUiSettingsBrowserInternalObj from './kbn_core_ui_settings_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser_mocks.mdx b/api_docs/kbn_core_ui_settings_browser_mocks.mdx index 752659a90ebd5..a36d2dbf5a0c7 100644 --- a/api_docs/kbn_core_ui_settings_browser_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-mocks title: "@kbn/core-ui-settings-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser-mocks'] --- import kbnCoreUiSettingsBrowserMocksObj from './kbn_core_ui_settings_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_common.mdx b/api_docs/kbn_core_ui_settings_common.mdx index bcaa05f381695..5138d73d828ea 100644 --- a/api_docs/kbn_core_ui_settings_common.mdx +++ b/api_docs/kbn_core_ui_settings_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-common title: "@kbn/core-ui-settings-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-common plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-common'] --- import kbnCoreUiSettingsCommonObj from './kbn_core_ui_settings_common.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server.mdx b/api_docs/kbn_core_ui_settings_server.mdx index 82dbb79cc0e85..e48cd79faa840 100644 --- a/api_docs/kbn_core_ui_settings_server.mdx +++ b/api_docs/kbn_core_ui_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server title: "@kbn/core-ui-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server'] --- import kbnCoreUiSettingsServerObj from './kbn_core_ui_settings_server.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server_internal.mdx b/api_docs/kbn_core_ui_settings_server_internal.mdx index 0e8a45969c6dc..619bd7390d9b9 100644 --- a/api_docs/kbn_core_ui_settings_server_internal.mdx +++ b/api_docs/kbn_core_ui_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-internal title: "@kbn/core-ui-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server-internal'] --- import kbnCoreUiSettingsServerInternalObj from './kbn_core_ui_settings_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server_mocks.mdx b/api_docs/kbn_core_ui_settings_server_mocks.mdx index 403a2f8e52bcc..62380ad814790 100644 --- a/api_docs/kbn_core_ui_settings_server_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-mocks title: "@kbn/core-ui-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server-mocks'] --- import kbnCoreUiSettingsServerMocksObj from './kbn_core_ui_settings_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server.mdx b/api_docs/kbn_core_usage_data_server.mdx index f5bb8dd8510bd..78de2c22b489e 100644 --- a/api_docs/kbn_core_usage_data_server.mdx +++ b/api_docs/kbn_core_usage_data_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server title: "@kbn/core-usage-data-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server'] --- import kbnCoreUsageDataServerObj from './kbn_core_usage_data_server.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server_internal.mdx b/api_docs/kbn_core_usage_data_server_internal.mdx index 6c631a99e4bd0..923ad2c17a4e7 100644 --- a/api_docs/kbn_core_usage_data_server_internal.mdx +++ b/api_docs/kbn_core_usage_data_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-internal title: "@kbn/core-usage-data-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-internal plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-internal'] --- import kbnCoreUsageDataServerInternalObj from './kbn_core_usage_data_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server_mocks.mdx b/api_docs/kbn_core_usage_data_server_mocks.mdx index aeaf777a777d3..81a3ebcfd017a 100644 --- a/api_docs/kbn_core_usage_data_server_mocks.mdx +++ b/api_docs/kbn_core_usage_data_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-mocks title: "@kbn/core-usage-data-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-mocks'] --- import kbnCoreUsageDataServerMocksObj from './kbn_core_usage_data_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_crypto.mdx b/api_docs/kbn_crypto.mdx index 2617374bccad3..029b6cea15b4c 100644 --- a/api_docs/kbn_crypto.mdx +++ b/api_docs/kbn_crypto.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto title: "@kbn/crypto" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto'] --- import kbnCryptoObj from './kbn_crypto.devdocs.json'; diff --git a/api_docs/kbn_crypto_browser.mdx b/api_docs/kbn_crypto_browser.mdx index fa6b09adc14b7..b19cf2b65f34d 100644 --- a/api_docs/kbn_crypto_browser.mdx +++ b/api_docs/kbn_crypto_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto-browser title: "@kbn/crypto-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto-browser plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto-browser'] --- import kbnCryptoBrowserObj from './kbn_crypto_browser.devdocs.json'; diff --git a/api_docs/kbn_datemath.mdx b/api_docs/kbn_datemath.mdx index 564b5e8ed82f5..51f9fc42dbcdd 100644 --- a/api_docs/kbn_datemath.mdx +++ b/api_docs/kbn_datemath.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-datemath title: "@kbn/datemath" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/datemath plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/datemath'] --- import kbnDatemathObj from './kbn_datemath.devdocs.json'; diff --git a/api_docs/kbn_dev_cli_errors.mdx b/api_docs/kbn_dev_cli_errors.mdx index 932b13eea4ea9..8bc9321ade81b 100644 --- a/api_docs/kbn_dev_cli_errors.mdx +++ b/api_docs/kbn_dev_cli_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-errors title: "@kbn/dev-cli-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-errors plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-errors'] --- import kbnDevCliErrorsObj from './kbn_dev_cli_errors.devdocs.json'; diff --git a/api_docs/kbn_dev_cli_runner.mdx b/api_docs/kbn_dev_cli_runner.mdx index 4f1735d40ab4e..389629bd44eb9 100644 --- a/api_docs/kbn_dev_cli_runner.mdx +++ b/api_docs/kbn_dev_cli_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-runner title: "@kbn/dev-cli-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-runner plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-runner'] --- import kbnDevCliRunnerObj from './kbn_dev_cli_runner.devdocs.json'; diff --git a/api_docs/kbn_dev_proc_runner.mdx b/api_docs/kbn_dev_proc_runner.mdx index 175292a832693..34bf867a7c774 100644 --- a/api_docs/kbn_dev_proc_runner.mdx +++ b/api_docs/kbn_dev_proc_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-proc-runner title: "@kbn/dev-proc-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-proc-runner plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-proc-runner'] --- import kbnDevProcRunnerObj from './kbn_dev_proc_runner.devdocs.json'; diff --git a/api_docs/kbn_dev_utils.mdx b/api_docs/kbn_dev_utils.mdx index ebc21ca0d3547..e9bfdac8df31f 100644 --- a/api_docs/kbn_dev_utils.mdx +++ b/api_docs/kbn_dev_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-utils title: "@kbn/dev-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-utils plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-utils'] --- import kbnDevUtilsObj from './kbn_dev_utils.devdocs.json'; diff --git a/api_docs/kbn_doc_links.mdx b/api_docs/kbn_doc_links.mdx index 7da2cb5f75081..51bcfae891fee 100644 --- a/api_docs/kbn_doc_links.mdx +++ b/api_docs/kbn_doc_links.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-doc-links title: "@kbn/doc-links" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/doc-links plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/doc-links'] --- import kbnDocLinksObj from './kbn_doc_links.devdocs.json'; diff --git a/api_docs/kbn_docs_utils.mdx b/api_docs/kbn_docs_utils.mdx index 94d7c9f7536d7..2742de20660a7 100644 --- a/api_docs/kbn_docs_utils.mdx +++ b/api_docs/kbn_docs_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-docs-utils title: "@kbn/docs-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/docs-utils plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/docs-utils'] --- import kbnDocsUtilsObj from './kbn_docs_utils.devdocs.json'; diff --git a/api_docs/kbn_ebt_tools.mdx b/api_docs/kbn_ebt_tools.mdx index 2ef5daaf2f4d0..2d907a8db72e0 100644 --- a/api_docs/kbn_ebt_tools.mdx +++ b/api_docs/kbn_ebt_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ebt-tools title: "@kbn/ebt-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ebt-tools plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ebt-tools'] --- import kbnEbtToolsObj from './kbn_ebt_tools.devdocs.json'; diff --git a/api_docs/kbn_es.mdx b/api_docs/kbn_es.mdx index 8fcc7db656094..9858f457eda0e 100644 --- a/api_docs/kbn_es.mdx +++ b/api_docs/kbn_es.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es title: "@kbn/es" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es'] --- import kbnEsObj from './kbn_es.devdocs.json'; diff --git a/api_docs/kbn_es_archiver.mdx b/api_docs/kbn_es_archiver.mdx index eccdea020c017..8bc82110d3d7e 100644 --- a/api_docs/kbn_es_archiver.mdx +++ b/api_docs/kbn_es_archiver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-archiver title: "@kbn/es-archiver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-archiver plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-archiver'] --- import kbnEsArchiverObj from './kbn_es_archiver.devdocs.json'; diff --git a/api_docs/kbn_es_errors.mdx b/api_docs/kbn_es_errors.mdx index e941bf44f19c4..f96d717e3c166 100644 --- a/api_docs/kbn_es_errors.mdx +++ b/api_docs/kbn_es_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-errors title: "@kbn/es-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-errors plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-errors'] --- import kbnEsErrorsObj from './kbn_es_errors.devdocs.json'; diff --git a/api_docs/kbn_es_query.mdx b/api_docs/kbn_es_query.mdx index 5743a11f21ddf..1bff0299c6a58 100644 --- a/api_docs/kbn_es_query.mdx +++ b/api_docs/kbn_es_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-query title: "@kbn/es-query" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-query plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-query'] --- import kbnEsQueryObj from './kbn_es_query.devdocs.json'; diff --git a/api_docs/kbn_es_types.mdx b/api_docs/kbn_es_types.mdx index 3a5d9b06d5ad7..d18029b0d2f51 100644 --- a/api_docs/kbn_es_types.mdx +++ b/api_docs/kbn_es_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-types title: "@kbn/es-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-types plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-types'] --- import kbnEsTypesObj from './kbn_es_types.devdocs.json'; diff --git a/api_docs/kbn_eslint_plugin_imports.mdx b/api_docs/kbn_eslint_plugin_imports.mdx index 1bdc8b6a3e58c..9283dfdd4b038 100644 --- a/api_docs/kbn_eslint_plugin_imports.mdx +++ b/api_docs/kbn_eslint_plugin_imports.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-eslint-plugin-imports title: "@kbn/eslint-plugin-imports" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/eslint-plugin-imports plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/eslint-plugin-imports'] --- import kbnEslintPluginImportsObj from './kbn_eslint_plugin_imports.devdocs.json'; diff --git a/api_docs/kbn_field_types.mdx b/api_docs/kbn_field_types.mdx index 9ffc3daf34dd6..92ecfdf507070 100644 --- a/api_docs/kbn_field_types.mdx +++ b/api_docs/kbn_field_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-field-types title: "@kbn/field-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/field-types plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-types'] --- import kbnFieldTypesObj from './kbn_field_types.devdocs.json'; diff --git a/api_docs/kbn_find_used_node_modules.mdx b/api_docs/kbn_find_used_node_modules.mdx index d861898bc30ef..e6ad954273b1d 100644 --- a/api_docs/kbn_find_used_node_modules.mdx +++ b/api_docs/kbn_find_used_node_modules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-find-used-node-modules title: "@kbn/find-used-node-modules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/find-used-node-modules plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/find-used-node-modules'] --- import kbnFindUsedNodeModulesObj from './kbn_find_used_node_modules.devdocs.json'; diff --git a/api_docs/kbn_ftr_common_functional_services.mdx b/api_docs/kbn_ftr_common_functional_services.mdx index 92296916487ac..08111dcfb9986 100644 --- a/api_docs/kbn_ftr_common_functional_services.mdx +++ b/api_docs/kbn_ftr_common_functional_services.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ftr-common-functional-services title: "@kbn/ftr-common-functional-services" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ftr-common-functional-services plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ftr-common-functional-services'] --- import kbnFtrCommonFunctionalServicesObj from './kbn_ftr_common_functional_services.devdocs.json'; diff --git a/api_docs/kbn_generate.mdx b/api_docs/kbn_generate.mdx index 6e98224c55442..42ba848e0f9c5 100644 --- a/api_docs/kbn_generate.mdx +++ b/api_docs/kbn_generate.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate title: "@kbn/generate" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate'] --- import kbnGenerateObj from './kbn_generate.devdocs.json'; diff --git a/api_docs/kbn_get_repo_files.mdx b/api_docs/kbn_get_repo_files.mdx index ce429eb8b64ce..6de71207a8992 100644 --- a/api_docs/kbn_get_repo_files.mdx +++ b/api_docs/kbn_get_repo_files.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-get-repo-files title: "@kbn/get-repo-files" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/get-repo-files plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/get-repo-files'] --- import kbnGetRepoFilesObj from './kbn_get_repo_files.devdocs.json'; diff --git a/api_docs/kbn_guided_onboarding.mdx b/api_docs/kbn_guided_onboarding.mdx index 0aa31bf438def..56165175704ac 100644 --- a/api_docs/kbn_guided_onboarding.mdx +++ b/api_docs/kbn_guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-guided-onboarding title: "@kbn/guided-onboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/guided-onboarding plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/guided-onboarding'] --- import kbnGuidedOnboardingObj from './kbn_guided_onboarding.devdocs.json'; diff --git a/api_docs/kbn_handlebars.mdx b/api_docs/kbn_handlebars.mdx index dc05bc2ced4b5..faa3a8ba7cbe8 100644 --- a/api_docs/kbn_handlebars.mdx +++ b/api_docs/kbn_handlebars.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-handlebars title: "@kbn/handlebars" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/handlebars plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/handlebars'] --- import kbnHandlebarsObj from './kbn_handlebars.devdocs.json'; diff --git a/api_docs/kbn_hapi_mocks.mdx b/api_docs/kbn_hapi_mocks.mdx index 3df3e8485fce9..2e9959306d2a9 100644 --- a/api_docs/kbn_hapi_mocks.mdx +++ b/api_docs/kbn_hapi_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-hapi-mocks title: "@kbn/hapi-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/hapi-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/hapi-mocks'] --- import kbnHapiMocksObj from './kbn_hapi_mocks.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_card.mdx b/api_docs/kbn_home_sample_data_card.mdx index 12024c463b405..0480d63b81ef8 100644 --- a/api_docs/kbn_home_sample_data_card.mdx +++ b/api_docs/kbn_home_sample_data_card.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-card title: "@kbn/home-sample-data-card" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-card plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-card'] --- import kbnHomeSampleDataCardObj from './kbn_home_sample_data_card.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_tab.mdx b/api_docs/kbn_home_sample_data_tab.mdx index 6d0bb66f99cd9..48a30e95242a2 100644 --- a/api_docs/kbn_home_sample_data_tab.mdx +++ b/api_docs/kbn_home_sample_data_tab.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-tab title: "@kbn/home-sample-data-tab" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-tab plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-tab'] --- import kbnHomeSampleDataTabObj from './kbn_home_sample_data_tab.devdocs.json'; diff --git a/api_docs/kbn_i18n.mdx b/api_docs/kbn_i18n.mdx index f249672864a0e..0d35a6f799975 100644 --- a/api_docs/kbn_i18n.mdx +++ b/api_docs/kbn_i18n.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n title: "@kbn/i18n" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/i18n'] --- import kbnI18nObj from './kbn_i18n.devdocs.json'; diff --git a/api_docs/kbn_i18n_react.mdx b/api_docs/kbn_i18n_react.mdx index ea94ff42d9076..4bdf16a010603 100644 --- a/api_docs/kbn_i18n_react.mdx +++ b/api_docs/kbn_i18n_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n-react title: "@kbn/i18n-react" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n-react plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/i18n-react'] --- import kbnI18nReactObj from './kbn_i18n_react.devdocs.json'; diff --git a/api_docs/kbn_import_resolver.mdx b/api_docs/kbn_import_resolver.mdx index 90fba8660ebdf..5b56f2de74601 100644 --- a/api_docs/kbn_import_resolver.mdx +++ b/api_docs/kbn_import_resolver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-import-resolver title: "@kbn/import-resolver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/import-resolver plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/import-resolver'] --- import kbnImportResolverObj from './kbn_import_resolver.devdocs.json'; diff --git a/api_docs/kbn_interpreter.mdx b/api_docs/kbn_interpreter.mdx index e3c797fbab46b..9427c5f7647ec 100644 --- a/api_docs/kbn_interpreter.mdx +++ b/api_docs/kbn_interpreter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-interpreter title: "@kbn/interpreter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/interpreter plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/interpreter'] --- import kbnInterpreterObj from './kbn_interpreter.devdocs.json'; diff --git a/api_docs/kbn_io_ts_utils.mdx b/api_docs/kbn_io_ts_utils.mdx index 39b1fc5311cc3..80bed28bf863b 100644 --- a/api_docs/kbn_io_ts_utils.mdx +++ b/api_docs/kbn_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-io-ts-utils title: "@kbn/io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/io-ts-utils plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/io-ts-utils'] --- import kbnIoTsUtilsObj from './kbn_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_jest_serializers.mdx b/api_docs/kbn_jest_serializers.mdx index 065823d9e9644..063e75f99c727 100644 --- a/api_docs/kbn_jest_serializers.mdx +++ b/api_docs/kbn_jest_serializers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-jest-serializers title: "@kbn/jest-serializers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/jest-serializers plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/jest-serializers'] --- import kbnJestSerializersObj from './kbn_jest_serializers.devdocs.json'; diff --git a/api_docs/kbn_journeys.mdx b/api_docs/kbn_journeys.mdx index 09e3d0971ab93..4bcc084f61e7e 100644 --- a/api_docs/kbn_journeys.mdx +++ b/api_docs/kbn_journeys.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-journeys title: "@kbn/journeys" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/journeys plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/journeys'] --- import kbnJourneysObj from './kbn_journeys.devdocs.json'; diff --git a/api_docs/kbn_kibana_manifest_schema.mdx b/api_docs/kbn_kibana_manifest_schema.mdx index 57f9fc396e597..dd02776975efb 100644 --- a/api_docs/kbn_kibana_manifest_schema.mdx +++ b/api_docs/kbn_kibana_manifest_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-kibana-manifest-schema title: "@kbn/kibana-manifest-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/kibana-manifest-schema plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/kibana-manifest-schema'] --- import kbnKibanaManifestSchemaObj from './kbn_kibana_manifest_schema.devdocs.json'; diff --git a/api_docs/kbn_language_documentation_popover.mdx b/api_docs/kbn_language_documentation_popover.mdx index 5d3db245585c2..53178b9eb11c4 100644 --- a/api_docs/kbn_language_documentation_popover.mdx +++ b/api_docs/kbn_language_documentation_popover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-language-documentation-popover title: "@kbn/language-documentation-popover" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/language-documentation-popover plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/language-documentation-popover'] --- import kbnLanguageDocumentationPopoverObj from './kbn_language_documentation_popover.devdocs.json'; diff --git a/api_docs/kbn_logging.mdx b/api_docs/kbn_logging.mdx index 23c6c1cd2263c..0dd9a1ce39d08 100644 --- a/api_docs/kbn_logging.mdx +++ b/api_docs/kbn_logging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging title: "@kbn/logging" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging'] --- import kbnLoggingObj from './kbn_logging.devdocs.json'; diff --git a/api_docs/kbn_logging_mocks.mdx b/api_docs/kbn_logging_mocks.mdx index 4f5150c82ef25..32c30478d1658 100644 --- a/api_docs/kbn_logging_mocks.mdx +++ b/api_docs/kbn_logging_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging-mocks title: "@kbn/logging-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging-mocks'] --- import kbnLoggingMocksObj from './kbn_logging_mocks.devdocs.json'; diff --git a/api_docs/kbn_managed_vscode_config.mdx b/api_docs/kbn_managed_vscode_config.mdx index 9006c6eb7e893..6c94f20ac5473 100644 --- a/api_docs/kbn_managed_vscode_config.mdx +++ b/api_docs/kbn_managed_vscode_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-managed-vscode-config title: "@kbn/managed-vscode-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/managed-vscode-config plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/managed-vscode-config'] --- import kbnManagedVscodeConfigObj from './kbn_managed_vscode_config.devdocs.json'; diff --git a/api_docs/kbn_mapbox_gl.mdx b/api_docs/kbn_mapbox_gl.mdx index f62ce92ea9ca7..a4421418dc22f 100644 --- a/api_docs/kbn_mapbox_gl.mdx +++ b/api_docs/kbn_mapbox_gl.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-mapbox-gl title: "@kbn/mapbox-gl" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/mapbox-gl plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/mapbox-gl'] --- import kbnMapboxGlObj from './kbn_mapbox_gl.devdocs.json'; diff --git a/api_docs/kbn_ml_agg_utils.mdx b/api_docs/kbn_ml_agg_utils.mdx index 07dc1327976ee..7ec4e30da83ad 100644 --- a/api_docs/kbn_ml_agg_utils.mdx +++ b/api_docs/kbn_ml_agg_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-agg-utils title: "@kbn/ml-agg-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-agg-utils plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-agg-utils'] --- import kbnMlAggUtilsObj from './kbn_ml_agg_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_is_populated_object.mdx b/api_docs/kbn_ml_is_populated_object.mdx index 47431b91ad968..5e658542fe081 100644 --- a/api_docs/kbn_ml_is_populated_object.mdx +++ b/api_docs/kbn_ml_is_populated_object.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-populated-object title: "@kbn/ml-is-populated-object" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-populated-object plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-is-populated-object'] --- import kbnMlIsPopulatedObjectObj from './kbn_ml_is_populated_object.devdocs.json'; diff --git a/api_docs/kbn_ml_string_hash.mdx b/api_docs/kbn_ml_string_hash.mdx index e7cfafa592ae0..932c3bdaec1c4 100644 --- a/api_docs/kbn_ml_string_hash.mdx +++ b/api_docs/kbn_ml_string_hash.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-string-hash title: "@kbn/ml-string-hash" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-string-hash plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-string-hash'] --- import kbnMlStringHashObj from './kbn_ml_string_hash.devdocs.json'; diff --git a/api_docs/kbn_monaco.mdx b/api_docs/kbn_monaco.mdx index 09eb21cde5b97..afcd51b074193 100644 --- a/api_docs/kbn_monaco.mdx +++ b/api_docs/kbn_monaco.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-monaco title: "@kbn/monaco" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/monaco plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/monaco'] --- import kbnMonacoObj from './kbn_monaco.devdocs.json'; diff --git a/api_docs/kbn_optimizer.mdx b/api_docs/kbn_optimizer.mdx index afd7005408cf8..08c25292886a9 100644 --- a/api_docs/kbn_optimizer.mdx +++ b/api_docs/kbn_optimizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer title: "@kbn/optimizer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer'] --- import kbnOptimizerObj from './kbn_optimizer.devdocs.json'; diff --git a/api_docs/kbn_optimizer_webpack_helpers.mdx b/api_docs/kbn_optimizer_webpack_helpers.mdx index 546be539cfa0f..f29d7b1eca0db 100644 --- a/api_docs/kbn_optimizer_webpack_helpers.mdx +++ b/api_docs/kbn_optimizer_webpack_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer-webpack-helpers title: "@kbn/optimizer-webpack-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer-webpack-helpers plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer-webpack-helpers'] --- import kbnOptimizerWebpackHelpersObj from './kbn_optimizer_webpack_helpers.devdocs.json'; diff --git a/api_docs/kbn_osquery_io_ts_types.mdx b/api_docs/kbn_osquery_io_ts_types.mdx index 6f75eb70e0277..402c9d0a958be 100644 --- a/api_docs/kbn_osquery_io_ts_types.mdx +++ b/api_docs/kbn_osquery_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-osquery-io-ts-types title: "@kbn/osquery-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/osquery-io-ts-types plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/osquery-io-ts-types'] --- import kbnOsqueryIoTsTypesObj from './kbn_osquery_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_performance_testing_dataset_extractor.mdx b/api_docs/kbn_performance_testing_dataset_extractor.mdx index b7b19661b2cf9..e8ed20274ef11 100644 --- a/api_docs/kbn_performance_testing_dataset_extractor.mdx +++ b/api_docs/kbn_performance_testing_dataset_extractor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-performance-testing-dataset-extractor title: "@kbn/performance-testing-dataset-extractor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/performance-testing-dataset-extractor plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/performance-testing-dataset-extractor'] --- import kbnPerformanceTestingDatasetExtractorObj from './kbn_performance_testing_dataset_extractor.devdocs.json'; diff --git a/api_docs/kbn_plugin_generator.mdx b/api_docs/kbn_plugin_generator.mdx index a8676e99d4294..7275cba70f24f 100644 --- a/api_docs/kbn_plugin_generator.mdx +++ b/api_docs/kbn_plugin_generator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-generator title: "@kbn/plugin-generator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-generator plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-generator'] --- import kbnPluginGeneratorObj from './kbn_plugin_generator.devdocs.json'; diff --git a/api_docs/kbn_plugin_helpers.mdx b/api_docs/kbn_plugin_helpers.mdx index 09677f9c6b65d..9b9b4ca1f9a4e 100644 --- a/api_docs/kbn_plugin_helpers.mdx +++ b/api_docs/kbn_plugin_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-helpers title: "@kbn/plugin-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-helpers plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-helpers'] --- import kbnPluginHelpersObj from './kbn_plugin_helpers.devdocs.json'; diff --git a/api_docs/kbn_react_field.mdx b/api_docs/kbn_react_field.mdx index 4e080c19295dc..3f0ab220126a7 100644 --- a/api_docs/kbn_react_field.mdx +++ b/api_docs/kbn_react_field.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-field title: "@kbn/react-field" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-field plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] --- import kbnReactFieldObj from './kbn_react_field.devdocs.json'; diff --git a/api_docs/kbn_repo_source_classifier.mdx b/api_docs/kbn_repo_source_classifier.mdx index d01f493861762..9341eff6ea912 100644 --- a/api_docs/kbn_repo_source_classifier.mdx +++ b/api_docs/kbn_repo_source_classifier.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-source-classifier title: "@kbn/repo-source-classifier" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-source-classifier plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-source-classifier'] --- import kbnRepoSourceClassifierObj from './kbn_repo_source_classifier.devdocs.json'; diff --git a/api_docs/kbn_rule_data_utils.mdx b/api_docs/kbn_rule_data_utils.mdx index e6b923f480260..eedea9c6404a2 100644 --- a/api_docs/kbn_rule_data_utils.mdx +++ b/api_docs/kbn_rule_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rule-data-utils title: "@kbn/rule-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rule-data-utils plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rule-data-utils'] --- import kbnRuleDataUtilsObj from './kbn_rule_data_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_autocomplete.mdx b/api_docs/kbn_securitysolution_autocomplete.mdx index 793a249d94c81..112cec83335a9 100644 --- a/api_docs/kbn_securitysolution_autocomplete.mdx +++ b/api_docs/kbn_securitysolution_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-autocomplete title: "@kbn/securitysolution-autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-autocomplete plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-autocomplete'] --- import kbnSecuritysolutionAutocompleteObj from './kbn_securitysolution_autocomplete.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_es_utils.mdx b/api_docs/kbn_securitysolution_es_utils.mdx index 4d65817a6674a..ac0977ee48be3 100644 --- a/api_docs/kbn_securitysolution_es_utils.mdx +++ b/api_docs/kbn_securitysolution_es_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-es-utils title: "@kbn/securitysolution-es-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-es-utils plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-es-utils'] --- import kbnSecuritysolutionEsUtilsObj from './kbn_securitysolution_es_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_exception_list_components.mdx b/api_docs/kbn_securitysolution_exception_list_components.mdx index f10cbd6b5da35..efadd56695fe0 100644 --- a/api_docs/kbn_securitysolution_exception_list_components.mdx +++ b/api_docs/kbn_securitysolution_exception_list_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-exception-list-components title: "@kbn/securitysolution-exception-list-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-exception-list-components plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-exception-list-components'] --- import kbnSecuritysolutionExceptionListComponentsObj from './kbn_securitysolution_exception_list_components.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_hook_utils.mdx b/api_docs/kbn_securitysolution_hook_utils.mdx index 6dc50be6e8fb9..fb78d31b3c675 100644 --- a/api_docs/kbn_securitysolution_hook_utils.mdx +++ b/api_docs/kbn_securitysolution_hook_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-hook-utils title: "@kbn/securitysolution-hook-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-hook-utils plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-hook-utils'] --- import kbnSecuritysolutionHookUtilsObj from './kbn_securitysolution_hook_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx index 0623581817fbe..c74f638ccb9af 100644 --- a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-alerting-types title: "@kbn/securitysolution-io-ts-alerting-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-alerting-types plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-alerting-types'] --- import kbnSecuritysolutionIoTsAlertingTypesObj from './kbn_securitysolution_io_ts_alerting_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_list_types.mdx b/api_docs/kbn_securitysolution_io_ts_list_types.mdx index 791921a3b2fa3..98f5f6faa9653 100644 --- a/api_docs/kbn_securitysolution_io_ts_list_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_list_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-list-types title: "@kbn/securitysolution-io-ts-list-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-list-types plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-list-types'] --- import kbnSecuritysolutionIoTsListTypesObj from './kbn_securitysolution_io_ts_list_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_types.mdx b/api_docs/kbn_securitysolution_io_ts_types.mdx index 0bd93ca61eac2..9199c484b35f8 100644 --- a/api_docs/kbn_securitysolution_io_ts_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-types title: "@kbn/securitysolution-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-types plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-types'] --- import kbnSecuritysolutionIoTsTypesObj from './kbn_securitysolution_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_utils.mdx b/api_docs/kbn_securitysolution_io_ts_utils.mdx index f1247503fc91e..7718129f3884e 100644 --- a/api_docs/kbn_securitysolution_io_ts_utils.mdx +++ b/api_docs/kbn_securitysolution_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-utils title: "@kbn/securitysolution-io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-utils plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-utils'] --- import kbnSecuritysolutionIoTsUtilsObj from './kbn_securitysolution_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_api.mdx b/api_docs/kbn_securitysolution_list_api.mdx index 5b7acd2f00534..7cf8c073f6650 100644 --- a/api_docs/kbn_securitysolution_list_api.mdx +++ b/api_docs/kbn_securitysolution_list_api.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-api title: "@kbn/securitysolution-list-api" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-api plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-api'] --- import kbnSecuritysolutionListApiObj from './kbn_securitysolution_list_api.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_constants.mdx b/api_docs/kbn_securitysolution_list_constants.mdx index 4bfb0dfd8093f..1a6633eb18015 100644 --- a/api_docs/kbn_securitysolution_list_constants.mdx +++ b/api_docs/kbn_securitysolution_list_constants.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-constants title: "@kbn/securitysolution-list-constants" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-constants plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-constants'] --- import kbnSecuritysolutionListConstantsObj from './kbn_securitysolution_list_constants.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_hooks.mdx b/api_docs/kbn_securitysolution_list_hooks.mdx index 1c4f5e60fa838..25d12cea27ad2 100644 --- a/api_docs/kbn_securitysolution_list_hooks.mdx +++ b/api_docs/kbn_securitysolution_list_hooks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-hooks title: "@kbn/securitysolution-list-hooks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-hooks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-hooks'] --- import kbnSecuritysolutionListHooksObj from './kbn_securitysolution_list_hooks.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_utils.mdx b/api_docs/kbn_securitysolution_list_utils.mdx index aca2121cc54ee..000c155a3c917 100644 --- a/api_docs/kbn_securitysolution_list_utils.mdx +++ b/api_docs/kbn_securitysolution_list_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-utils title: "@kbn/securitysolution-list-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-utils plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-utils'] --- import kbnSecuritysolutionListUtilsObj from './kbn_securitysolution_list_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_rules.mdx b/api_docs/kbn_securitysolution_rules.mdx index 1ac856e5e506b..a5d39a95a0a05 100644 --- a/api_docs/kbn_securitysolution_rules.mdx +++ b/api_docs/kbn_securitysolution_rules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-rules title: "@kbn/securitysolution-rules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-rules plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-rules'] --- import kbnSecuritysolutionRulesObj from './kbn_securitysolution_rules.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_t_grid.mdx b/api_docs/kbn_securitysolution_t_grid.mdx index fa290646271f5..5447f4359262e 100644 --- a/api_docs/kbn_securitysolution_t_grid.mdx +++ b/api_docs/kbn_securitysolution_t_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-t-grid title: "@kbn/securitysolution-t-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-t-grid plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-t-grid'] --- import kbnSecuritysolutionTGridObj from './kbn_securitysolution_t_grid.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_utils.mdx b/api_docs/kbn_securitysolution_utils.mdx index 9ee1289f2552a..60b71a497165c 100644 --- a/api_docs/kbn_securitysolution_utils.mdx +++ b/api_docs/kbn_securitysolution_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-utils title: "@kbn/securitysolution-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-utils plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-utils'] --- import kbnSecuritysolutionUtilsObj from './kbn_securitysolution_utils.devdocs.json'; diff --git a/api_docs/kbn_server_http_tools.mdx b/api_docs/kbn_server_http_tools.mdx index 44222c6294693..2a6683c3deeae 100644 --- a/api_docs/kbn_server_http_tools.mdx +++ b/api_docs/kbn_server_http_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-http-tools title: "@kbn/server-http-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-http-tools plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-http-tools'] --- import kbnServerHttpToolsObj from './kbn_server_http_tools.devdocs.json'; diff --git a/api_docs/kbn_server_route_repository.mdx b/api_docs/kbn_server_route_repository.mdx index ff6532bbdc9e0..e7168e4341f78 100644 --- a/api_docs/kbn_server_route_repository.mdx +++ b/api_docs/kbn_server_route_repository.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-route-repository title: "@kbn/server-route-repository" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-route-repository plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository'] --- import kbnServerRouteRepositoryObj from './kbn_server_route_repository.devdocs.json'; diff --git a/api_docs/kbn_shared_svg.mdx b/api_docs/kbn_shared_svg.mdx index a1a24268fc15f..1cc302abf32a3 100644 --- a/api_docs/kbn_shared_svg.mdx +++ b/api_docs/kbn_shared_svg.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-svg title: "@kbn/shared-svg" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-svg plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-svg'] --- import kbnSharedSvgObj from './kbn_shared_svg.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_avatar_solution.mdx b/api_docs/kbn_shared_ux_avatar_solution.mdx index ef6911aec3b73..470a14f2a9eae 100644 --- a/api_docs/kbn_shared_ux_avatar_solution.mdx +++ b/api_docs/kbn_shared_ux_avatar_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-solution title: "@kbn/shared-ux-avatar-solution" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-solution plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-solution'] --- import kbnSharedUxAvatarSolutionObj from './kbn_shared_ux_avatar_solution.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx index 905ed473f7c98..9c899661f1e83 100644 --- a/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx +++ b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-user-profile-components title: "@kbn/shared-ux-avatar-user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-user-profile-components plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-user-profile-components'] --- import kbnSharedUxAvatarUserProfileComponentsObj from './kbn_shared_ux_avatar_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx index 60ab35bff1665..49eb0f4b54440 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen title: "@kbn/shared-ux-button-exit-full-screen" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen'] --- import kbnSharedUxButtonExitFullScreenObj from './kbn_shared_ux_button_exit_full_screen.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx index 97d6137bca9ed..b447edc179446 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen-mocks title: "@kbn/shared-ux-button-exit-full-screen-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen-mocks'] --- import kbnSharedUxButtonExitFullScreenMocksObj from './kbn_shared_ux_button_exit_full_screen_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_toolbar.mdx b/api_docs/kbn_shared_ux_button_toolbar.mdx index f19aa0d197cdc..4187890ebea42 100644 --- a/api_docs/kbn_shared_ux_button_toolbar.mdx +++ b/api_docs/kbn_shared_ux_button_toolbar.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-toolbar title: "@kbn/shared-ux-button-toolbar" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-toolbar plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-toolbar'] --- import kbnSharedUxButtonToolbarObj from './kbn_shared_ux_button_toolbar.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_card_no_data.mdx b/api_docs/kbn_shared_ux_card_no_data.mdx index 007de1e1fd8b8..2528aaa0483b1 100644 --- a/api_docs/kbn_shared_ux_card_no_data.mdx +++ b/api_docs/kbn_shared_ux_card_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data title: "@kbn/shared-ux-card-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data'] --- import kbnSharedUxCardNoDataObj from './kbn_shared_ux_card_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx index 25b1b57d0fd9c..9761cee4caa2d 100644 --- a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data-mocks title: "@kbn/shared-ux-card-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data-mocks'] --- import kbnSharedUxCardNoDataMocksObj from './kbn_shared_ux_card_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_link_redirect_app.mdx b/api_docs/kbn_shared_ux_link_redirect_app.mdx index 70d9b703add44..7301c277be2f2 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app title: "@kbn/shared-ux-link-redirect-app" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-link-redirect-app'] --- import kbnSharedUxLinkRedirectAppObj from './kbn_shared_ux_link_redirect_app.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx index 69926b3eae2e3..828fe690e0f9a 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app-mocks title: "@kbn/shared-ux-link-redirect-app-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-link-redirect-app-mocks'] --- import kbnSharedUxLinkRedirectAppMocksObj from './kbn_shared_ux_link_redirect_app_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_markdown.mdx b/api_docs/kbn_shared_ux_markdown.mdx index 1fa7b11407c37..c5e66a9b54c49 100644 --- a/api_docs/kbn_shared_ux_markdown.mdx +++ b/api_docs/kbn_shared_ux_markdown.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown title: "@kbn/shared-ux-markdown" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-markdown'] --- import kbnSharedUxMarkdownObj from './kbn_shared_ux_markdown.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_markdown_mocks.mdx b/api_docs/kbn_shared_ux_markdown_mocks.mdx index 08c8baa9c6c84..c219c206979fd 100644 --- a/api_docs/kbn_shared_ux_markdown_mocks.mdx +++ b/api_docs/kbn_shared_ux_markdown_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown-mocks title: "@kbn/shared-ux-markdown-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-markdown-mocks'] --- import kbnSharedUxMarkdownMocksObj from './kbn_shared_ux_markdown_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx index 7c94ef35c4278..2274c9565bb78 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data title: "@kbn/shared-ux-page-analytics-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data'] --- import kbnSharedUxPageAnalyticsNoDataObj from './kbn_shared_ux_page_analytics_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx index 8523c994a8d49..ac3ba812dd1e4 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data-mocks title: "@kbn/shared-ux-page-analytics-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data-mocks'] --- import kbnSharedUxPageAnalyticsNoDataMocksObj from './kbn_shared_ux_page_analytics_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx index f2305434606e4..d82cb4d0f2957 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data title: "@kbn/shared-ux-page-kibana-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data'] --- import kbnSharedUxPageKibanaNoDataObj from './kbn_shared_ux_page_kibana_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx index a3b9cc9894d63..9f850e4e6ad41 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data-mocks title: "@kbn/shared-ux-page-kibana-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data-mocks'] --- import kbnSharedUxPageKibanaNoDataMocksObj from './kbn_shared_ux_page_kibana_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_template.mdx b/api_docs/kbn_shared_ux_page_kibana_template.mdx index 357a198f95c61..10553bceee471 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template title: "@kbn/shared-ux-page-kibana-template" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-template'] --- import kbnSharedUxPageKibanaTemplateObj from './kbn_shared_ux_page_kibana_template.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx index bb170fe07ac4c..2dc6ce10bcaf8 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template-mocks title: "@kbn/shared-ux-page-kibana-template-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-template-mocks'] --- import kbnSharedUxPageKibanaTemplateMocksObj from './kbn_shared_ux_page_kibana_template_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data.mdx b/api_docs/kbn_shared_ux_page_no_data.mdx index b885897726fa6..b21a0649ca139 100644 --- a/api_docs/kbn_shared_ux_page_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data title: "@kbn/shared-ux-page-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data'] --- import kbnSharedUxPageNoDataObj from './kbn_shared_ux_page_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_config.mdx b/api_docs/kbn_shared_ux_page_no_data_config.mdx index f07e4efa4b812..7815666829e59 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config title: "@kbn/shared-ux-page-no-data-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-config'] --- import kbnSharedUxPageNoDataConfigObj from './kbn_shared_ux_page_no_data_config.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx index de2e1fa97b4fd..cf2bc05d67469 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config-mocks title: "@kbn/shared-ux-page-no-data-config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-config-mocks'] --- import kbnSharedUxPageNoDataConfigMocksObj from './kbn_shared_ux_page_no_data_config_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx index 248a97c7d1c81..4b49f9b3e11fd 100644 --- a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-mocks title: "@kbn/shared-ux-page-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-mocks'] --- import kbnSharedUxPageNoDataMocksObj from './kbn_shared_ux_page_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_solution_nav.mdx b/api_docs/kbn_shared_ux_page_solution_nav.mdx index 825eee67874ed..d3b992d5bcd8e 100644 --- a/api_docs/kbn_shared_ux_page_solution_nav.mdx +++ b/api_docs/kbn_shared_ux_page_solution_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-solution-nav title: "@kbn/shared-ux-page-solution-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-solution-nav plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-solution-nav'] --- import kbnSharedUxPageSolutionNavObj from './kbn_shared_ux_page_solution_nav.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx index 90e4d90459a76..e07da5cc2d9d9 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views title: "@kbn/shared-ux-prompt-no-data-views" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views'] --- import kbnSharedUxPromptNoDataViewsObj from './kbn_shared_ux_prompt_no_data_views.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx index a681271b2c435..226a58c0aaa8f 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views-mocks title: "@kbn/shared-ux-prompt-no-data-views-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views-mocks'] --- import kbnSharedUxPromptNoDataViewsMocksObj from './kbn_shared_ux_prompt_no_data_views_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_router.mdx b/api_docs/kbn_shared_ux_router.mdx index 97116d112b55a..864eee155833c 100644 --- a/api_docs/kbn_shared_ux_router.mdx +++ b/api_docs/kbn_shared_ux_router.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router title: "@kbn/shared-ux-router" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-router'] --- import kbnSharedUxRouterObj from './kbn_shared_ux_router.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_router_mocks.mdx b/api_docs/kbn_shared_ux_router_mocks.mdx index b2b19a1caebfa..d4b343fe1fa0a 100644 --- a/api_docs/kbn_shared_ux_router_mocks.mdx +++ b/api_docs/kbn_shared_ux_router_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router-mocks title: "@kbn/shared-ux-router-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router-mocks plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-router-mocks'] --- import kbnSharedUxRouterMocksObj from './kbn_shared_ux_router_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_storybook_config.mdx b/api_docs/kbn_shared_ux_storybook_config.mdx index a509c914f3353..898856285f77d 100644 --- a/api_docs/kbn_shared_ux_storybook_config.mdx +++ b/api_docs/kbn_shared_ux_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-config title: "@kbn/shared-ux-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-config plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-config'] --- import kbnSharedUxStorybookConfigObj from './kbn_shared_ux_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_storybook_mock.mdx b/api_docs/kbn_shared_ux_storybook_mock.mdx index 8be42b6dd64b4..74866474a3c71 100644 --- a/api_docs/kbn_shared_ux_storybook_mock.mdx +++ b/api_docs/kbn_shared_ux_storybook_mock.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-mock title: "@kbn/shared-ux-storybook-mock" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-mock plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-mock'] --- import kbnSharedUxStorybookMockObj from './kbn_shared_ux_storybook_mock.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_utility.mdx b/api_docs/kbn_shared_ux_utility.mdx index 97eaab20edc04..4e6ff7fc7c850 100644 --- a/api_docs/kbn_shared_ux_utility.mdx +++ b/api_docs/kbn_shared_ux_utility.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-utility title: "@kbn/shared-ux-utility" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-utility plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-utility'] --- import kbnSharedUxUtilityObj from './kbn_shared_ux_utility.devdocs.json'; diff --git a/api_docs/kbn_some_dev_log.mdx b/api_docs/kbn_some_dev_log.mdx index f5975faa298a3..fa8650096202a 100644 --- a/api_docs/kbn_some_dev_log.mdx +++ b/api_docs/kbn_some_dev_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-some-dev-log title: "@kbn/some-dev-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/some-dev-log plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/some-dev-log'] --- import kbnSomeDevLogObj from './kbn_some_dev_log.devdocs.json'; diff --git a/api_docs/kbn_sort_package_json.mdx b/api_docs/kbn_sort_package_json.mdx index c75725f555600..d1e4f20ee5f2f 100644 --- a/api_docs/kbn_sort_package_json.mdx +++ b/api_docs/kbn_sort_package_json.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-sort-package-json title: "@kbn/sort-package-json" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/sort-package-json plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/sort-package-json'] --- import kbnSortPackageJsonObj from './kbn_sort_package_json.devdocs.json'; diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index 7b382d339f228..7b45a362084e2 100644 --- a/api_docs/kbn_std.mdx +++ b/api_docs/kbn_std.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-std title: "@kbn/std" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/std plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/std'] --- import kbnStdObj from './kbn_std.devdocs.json'; diff --git a/api_docs/kbn_stdio_dev_helpers.mdx b/api_docs/kbn_stdio_dev_helpers.mdx index 24a000f94beb5..70d789c67d885 100644 --- a/api_docs/kbn_stdio_dev_helpers.mdx +++ b/api_docs/kbn_stdio_dev_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-stdio-dev-helpers title: "@kbn/stdio-dev-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/stdio-dev-helpers plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/stdio-dev-helpers'] --- import kbnStdioDevHelpersObj from './kbn_stdio_dev_helpers.devdocs.json'; diff --git a/api_docs/kbn_storybook.mdx b/api_docs/kbn_storybook.mdx index fad4ed3b27081..0a6efa67f2837 100644 --- a/api_docs/kbn_storybook.mdx +++ b/api_docs/kbn_storybook.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-storybook title: "@kbn/storybook" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/storybook plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/storybook'] --- import kbnStorybookObj from './kbn_storybook.devdocs.json'; diff --git a/api_docs/kbn_telemetry_tools.mdx b/api_docs/kbn_telemetry_tools.mdx index 0e363e370570f..e971f2d17208c 100644 --- a/api_docs/kbn_telemetry_tools.mdx +++ b/api_docs/kbn_telemetry_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-telemetry-tools title: "@kbn/telemetry-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/telemetry-tools plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/telemetry-tools'] --- import kbnTelemetryToolsObj from './kbn_telemetry_tools.devdocs.json'; diff --git a/api_docs/kbn_test.mdx b/api_docs/kbn_test.mdx index c5cbe8e6ba447..68d0ba52e9823 100644 --- a/api_docs/kbn_test.mdx +++ b/api_docs/kbn_test.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test title: "@kbn/test" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test'] --- import kbnTestObj from './kbn_test.devdocs.json'; diff --git a/api_docs/kbn_test_jest_helpers.mdx b/api_docs/kbn_test_jest_helpers.mdx index 470e108023f3e..7c87588c287d3 100644 --- a/api_docs/kbn_test_jest_helpers.mdx +++ b/api_docs/kbn_test_jest_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-jest-helpers title: "@kbn/test-jest-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-jest-helpers plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-jest-helpers'] --- import kbnTestJestHelpersObj from './kbn_test_jest_helpers.devdocs.json'; diff --git a/api_docs/kbn_test_subj_selector.mdx b/api_docs/kbn_test_subj_selector.mdx index 9f49f13e4e438..42cf10ecaafca 100644 --- a/api_docs/kbn_test_subj_selector.mdx +++ b/api_docs/kbn_test_subj_selector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-subj-selector title: "@kbn/test-subj-selector" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-subj-selector plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-subj-selector'] --- import kbnTestSubjSelectorObj from './kbn_test_subj_selector.devdocs.json'; diff --git a/api_docs/kbn_tooling_log.mdx b/api_docs/kbn_tooling_log.mdx index dbd461a7f2973..48f1d165cd73c 100644 --- a/api_docs/kbn_tooling_log.mdx +++ b/api_docs/kbn_tooling_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-tooling-log title: "@kbn/tooling-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/tooling-log plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log'] --- import kbnToolingLogObj from './kbn_tooling_log.devdocs.json'; diff --git a/api_docs/kbn_type_summarizer.mdx b/api_docs/kbn_type_summarizer.mdx index 7c099ced6fbd1..75cd1b7819eab 100644 --- a/api_docs/kbn_type_summarizer.mdx +++ b/api_docs/kbn_type_summarizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-type-summarizer title: "@kbn/type-summarizer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/type-summarizer plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/type-summarizer'] --- import kbnTypeSummarizerObj from './kbn_type_summarizer.devdocs.json'; diff --git a/api_docs/kbn_type_summarizer_core.mdx b/api_docs/kbn_type_summarizer_core.mdx index 5ade197f7c552..3bfc170fb8c87 100644 --- a/api_docs/kbn_type_summarizer_core.mdx +++ b/api_docs/kbn_type_summarizer_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-type-summarizer-core title: "@kbn/type-summarizer-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/type-summarizer-core plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/type-summarizer-core'] --- import kbnTypeSummarizerCoreObj from './kbn_type_summarizer_core.devdocs.json'; diff --git a/api_docs/kbn_typed_react_router_config.mdx b/api_docs/kbn_typed_react_router_config.mdx index c2d182c4e1952..671755c80ea4d 100644 --- a/api_docs/kbn_typed_react_router_config.mdx +++ b/api_docs/kbn_typed_react_router_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-typed-react-router-config title: "@kbn/typed-react-router-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/typed-react-router-config plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/typed-react-router-config'] --- import kbnTypedReactRouterConfigObj from './kbn_typed_react_router_config.devdocs.json'; diff --git a/api_docs/kbn_ui_shared_deps_src.mdx b/api_docs/kbn_ui_shared_deps_src.mdx index cbffe401bb099..139e07985d675 100644 --- a/api_docs/kbn_ui_shared_deps_src.mdx +++ b/api_docs/kbn_ui_shared_deps_src.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-shared-deps-src title: "@kbn/ui-shared-deps-src" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-shared-deps-src plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-shared-deps-src'] --- import kbnUiSharedDepsSrcObj from './kbn_ui_shared_deps_src.devdocs.json'; diff --git a/api_docs/kbn_ui_theme.mdx b/api_docs/kbn_ui_theme.mdx index 78eebf1992c48..7a58697489db9 100644 --- a/api_docs/kbn_ui_theme.mdx +++ b/api_docs/kbn_ui_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-theme title: "@kbn/ui-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-theme plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme'] --- import kbnUiThemeObj from './kbn_ui_theme.devdocs.json'; diff --git a/api_docs/kbn_user_profile_components.mdx b/api_docs/kbn_user_profile_components.mdx index 577466bf033a6..727447a9c5ddc 100644 --- a/api_docs/kbn_user_profile_components.mdx +++ b/api_docs/kbn_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-user-profile-components title: "@kbn/user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/user-profile-components plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/user-profile-components'] --- import kbnUserProfileComponentsObj from './kbn_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_utility_types.mdx b/api_docs/kbn_utility_types.mdx index 2fb001354e0c0..ff9958a2cce12 100644 --- a/api_docs/kbn_utility_types.mdx +++ b/api_docs/kbn_utility_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types title: "@kbn/utility-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types'] --- import kbnUtilityTypesObj from './kbn_utility_types.devdocs.json'; diff --git a/api_docs/kbn_utility_types_jest.mdx b/api_docs/kbn_utility_types_jest.mdx index 698d5fc4f897b..995f198c7e0e6 100644 --- a/api_docs/kbn_utility_types_jest.mdx +++ b/api_docs/kbn_utility_types_jest.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types-jest title: "@kbn/utility-types-jest" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types-jest plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types-jest'] --- import kbnUtilityTypesJestObj from './kbn_utility_types_jest.devdocs.json'; diff --git a/api_docs/kbn_utils.mdx b/api_docs/kbn_utils.mdx index dfdf80678aa9c..ac1156d4b2645 100644 --- a/api_docs/kbn_utils.mdx +++ b/api_docs/kbn_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utils title: "@kbn/utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utils plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utils'] --- import kbnUtilsObj from './kbn_utils.devdocs.json'; diff --git a/api_docs/kbn_yarn_lock_validator.mdx b/api_docs/kbn_yarn_lock_validator.mdx index 61ec7ae48f9e3..cad5009c10027 100644 --- a/api_docs/kbn_yarn_lock_validator.mdx +++ b/api_docs/kbn_yarn_lock_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-yarn-lock-validator title: "@kbn/yarn-lock-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/yarn-lock-validator plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/yarn-lock-validator'] --- import kbnYarnLockValidatorObj from './kbn_yarn_lock_validator.devdocs.json'; diff --git a/api_docs/kibana_overview.mdx b/api_docs/kibana_overview.mdx index 710079b304ac2..9d30d3b8cdf5c 100644 --- a/api_docs/kibana_overview.mdx +++ b/api_docs/kibana_overview.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaOverview title: "kibanaOverview" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaOverview plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaOverview'] --- import kibanaOverviewObj from './kibana_overview.devdocs.json'; diff --git a/api_docs/kibana_react.mdx b/api_docs/kibana_react.mdx index 41de441b14cb2..e957e84fc1155 100644 --- a/api_docs/kibana_react.mdx +++ b/api_docs/kibana_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaReact title: "kibanaReact" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaReact plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaReact'] --- import kibanaReactObj from './kibana_react.devdocs.json'; diff --git a/api_docs/kibana_utils.mdx b/api_docs/kibana_utils.mdx index a8bcbbe417a1f..e1a8d4f7ff253 100644 --- a/api_docs/kibana_utils.mdx +++ b/api_docs/kibana_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaUtils title: "kibanaUtils" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaUtils plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaUtils'] --- import kibanaUtilsObj from './kibana_utils.devdocs.json'; diff --git a/api_docs/kubernetes_security.mdx b/api_docs/kubernetes_security.mdx index 6d912f3dd27d3..5fae2e27224a6 100644 --- a/api_docs/kubernetes_security.mdx +++ b/api_docs/kubernetes_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kubernetesSecurity title: "kubernetesSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the kubernetesSecurity plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kubernetesSecurity'] --- import kubernetesSecurityObj from './kubernetes_security.devdocs.json'; diff --git a/api_docs/lens.mdx b/api_docs/lens.mdx index dcf014e8c95f1..7f6625427ca18 100644 --- a/api_docs/lens.mdx +++ b/api_docs/lens.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lens title: "lens" image: https://source.unsplash.com/400x175/?github description: API docs for the lens plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lens'] --- import lensObj from './lens.devdocs.json'; diff --git a/api_docs/license_api_guard.mdx b/api_docs/license_api_guard.mdx index b8dddff891acc..6ee555a03335c 100644 --- a/api_docs/license_api_guard.mdx +++ b/api_docs/license_api_guard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseApiGuard title: "licenseApiGuard" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseApiGuard plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseApiGuard'] --- import licenseApiGuardObj from './license_api_guard.devdocs.json'; diff --git a/api_docs/license_management.mdx b/api_docs/license_management.mdx index 6c46e65dbdda0..52237d3e8e942 100644 --- a/api_docs/license_management.mdx +++ b/api_docs/license_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseManagement title: "licenseManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseManagement plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseManagement'] --- import licenseManagementObj from './license_management.devdocs.json'; diff --git a/api_docs/licensing.mdx b/api_docs/licensing.mdx index 13842df636289..f7d88b5e77eb6 100644 --- a/api_docs/licensing.mdx +++ b/api_docs/licensing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licensing title: "licensing" image: https://source.unsplash.com/400x175/?github description: API docs for the licensing plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licensing'] --- import licensingObj from './licensing.devdocs.json'; diff --git a/api_docs/lists.mdx b/api_docs/lists.mdx index 500276696f06c..011c07bd2f2ec 100644 --- a/api_docs/lists.mdx +++ b/api_docs/lists.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lists title: "lists" image: https://source.unsplash.com/400x175/?github description: API docs for the lists plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists'] --- import listsObj from './lists.devdocs.json'; diff --git a/api_docs/management.mdx b/api_docs/management.mdx index 78bd8739c2c11..961e47eaa4622 100644 --- a/api_docs/management.mdx +++ b/api_docs/management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/management title: "management" image: https://source.unsplash.com/400x175/?github description: API docs for the management plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'management'] --- import managementObj from './management.devdocs.json'; diff --git a/api_docs/maps.mdx b/api_docs/maps.mdx index 54b3ff5152633..3cef004e7a063 100644 --- a/api_docs/maps.mdx +++ b/api_docs/maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/maps title: "maps" image: https://source.unsplash.com/400x175/?github description: API docs for the maps plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'maps'] --- import mapsObj from './maps.devdocs.json'; diff --git a/api_docs/maps_ems.mdx b/api_docs/maps_ems.mdx index 74fd473915c49..b7f8593146200 100644 --- a/api_docs/maps_ems.mdx +++ b/api_docs/maps_ems.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mapsEms title: "mapsEms" image: https://source.unsplash.com/400x175/?github description: API docs for the mapsEms plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mapsEms'] --- import mapsEmsObj from './maps_ems.devdocs.json'; diff --git a/api_docs/ml.mdx b/api_docs/ml.mdx index 5507b92045e15..71c2c88639b17 100644 --- a/api_docs/ml.mdx +++ b/api_docs/ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ml title: "ml" image: https://source.unsplash.com/400x175/?github description: API docs for the ml plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ml'] --- import mlObj from './ml.devdocs.json'; diff --git a/api_docs/monitoring.mdx b/api_docs/monitoring.mdx index 784d80d7b1d19..65b7983715e27 100644 --- a/api_docs/monitoring.mdx +++ b/api_docs/monitoring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoring title: "monitoring" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoring plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoring'] --- import monitoringObj from './monitoring.devdocs.json'; diff --git a/api_docs/monitoring_collection.mdx b/api_docs/monitoring_collection.mdx index 8e68980d1a6fb..af2b90f6ae2e1 100644 --- a/api_docs/monitoring_collection.mdx +++ b/api_docs/monitoring_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoringCollection title: "monitoringCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoringCollection plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoringCollection'] --- import monitoringCollectionObj from './monitoring_collection.devdocs.json'; diff --git a/api_docs/navigation.mdx b/api_docs/navigation.mdx index ceeada3f14bcf..a71fe908dea03 100644 --- a/api_docs/navigation.mdx +++ b/api_docs/navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/navigation title: "navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the navigation plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'navigation'] --- import navigationObj from './navigation.devdocs.json'; diff --git a/api_docs/newsfeed.mdx b/api_docs/newsfeed.mdx index 1e216762b0084..e4e2db741c1dd 100644 --- a/api_docs/newsfeed.mdx +++ b/api_docs/newsfeed.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/newsfeed title: "newsfeed" image: https://source.unsplash.com/400x175/?github description: API docs for the newsfeed plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'newsfeed'] --- import newsfeedObj from './newsfeed.devdocs.json'; diff --git a/api_docs/notifications.devdocs.json b/api_docs/notifications.devdocs.json new file mode 100644 index 0000000000000..f7508b16dcdba --- /dev/null +++ b/api_docs/notifications.devdocs.json @@ -0,0 +1,59 @@ +{ + "id": "notifications", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [], + "start": { + "parentPluginId": "notifications", + "id": "def-server.NotificationsPluginStart", + "type": "Type", + "tags": [], + "label": "NotificationsPluginStart", + "description": [], + "signature": [ + "EmailServiceStart" + ], + "path": "x-pack/plugins/notifications/server/types.ts", + "deprecated": false, + "trackAdoption": false, + "lifecycle": "start", + "initialIsOpen": true + } + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [ + { + "parentPluginId": "notifications", + "id": "def-common.PLUGIN_ID", + "type": "string", + "tags": [], + "label": "PLUGIN_ID", + "description": [], + "signature": [ + "\"notifications\"" + ], + "path": "x-pack/plugins/notifications/common/index.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + } + ], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/notifications.mdx b/api_docs/notifications.mdx new file mode 100644 index 0000000000000..91d0c2b7b83e3 --- /dev/null +++ b/api_docs/notifications.mdx @@ -0,0 +1,35 @@ +--- +#### +#### 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. +#### +id: kibNotificationsPluginApi +slug: /kibana-dev-docs/api/notifications +title: "notifications" +image: https://source.unsplash.com/400x175/?github +description: API docs for the notifications plugin +date: 2022-11-04 +tags: ['contributor', 'dev', 'apidocs', 'kibana', 'notifications'] +--- +import notificationsObj from './notifications.devdocs.json'; + + + +Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 2 | 0 | 2 | 1 | + +## Server + +### Start + + +## Common + +### Consts, variables and types + + diff --git a/api_docs/observability.mdx b/api_docs/observability.mdx index b75b7d428fbec..485dc98f067cc 100644 --- a/api_docs/observability.mdx +++ b/api_docs/observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observability title: "observability" image: https://source.unsplash.com/400x175/?github description: API docs for the observability plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability'] --- import observabilityObj from './observability.devdocs.json'; diff --git a/api_docs/osquery.devdocs.json b/api_docs/osquery.devdocs.json index 635153c4153e9..2b441fc69b891 100644 --- a/api_docs/osquery.devdocs.json +++ b/api_docs/osquery.devdocs.json @@ -42,7 +42,9 @@ "signature": [ "((props: ", "OsqueryActionProps", - ") => JSX.Element) | undefined" + " & { ecsData?: ", + "AlertEcsData", + " | undefined; }) => JSX.Element) | undefined" ], "path": "x-pack/plugins/osquery/public/types.ts", "deprecated": false, diff --git a/api_docs/osquery.mdx b/api_docs/osquery.mdx index b30a8f54cd56f..cf6bbb81c6163 100644 --- a/api_docs/osquery.mdx +++ b/api_docs/osquery.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/osquery title: "osquery" image: https://source.unsplash.com/400x175/?github description: API docs for the osquery plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'osquery'] --- import osqueryObj from './osquery.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Security asset management](https://github.com/orgs/elastic/teams/securi | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 21 | 0 | 21 | 3 | +| 21 | 0 | 21 | 4 | ## Client diff --git a/api_docs/plugin_directory.mdx b/api_docs/plugin_directory.mdx index ac3b928e4a481..af68a3b19f4fe 100644 --- a/api_docs/plugin_directory.mdx +++ b/api_docs/plugin_directory.mdx @@ -7,7 +7,7 @@ id: kibDevDocsPluginDirectory slug: /kibana-dev-docs/api-meta/plugin-api-directory title: Directory description: Directory of public APIs available through plugins or packages. -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -15,13 +15,13 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | Count | Plugins or Packages with a
public API | Number of teams | |--------------|----------|------------------------| -| 507 | 425 | 38 | +| 508 | 426 | 38 | ### Public API health stats | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 33241 | 514 | 23572 | 1102 | +| 33253 | 515 | 23583 | 1105 | ## Plugin Directory @@ -30,7 +30,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 225 | 8 | 220 | 24 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 36 | 1 | 32 | 2 | | | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | AIOps plugin maintained by ML team. | 9 | 0 | 0 | 2 | -| | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 383 | 0 | 374 | 26 | +| | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 384 | 0 | 375 | 26 | | | [APM UI](https://github.com/orgs/elastic/teams/apm-ui) | The user interface for Elastic APM | 41 | 0 | 41 | 58 | | | [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. | 81 | 1 | 72 | 2 | @@ -73,19 +73,19 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds 'image' function and renderer to expressions | 26 | 0 | 26 | 0 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Adds a `metric` renderer and function to the expression plugin. The renderer will display the `legacy metric` chart. | 51 | 0 | 51 | 2 | | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds 'metric' function and renderer to expressions | 32 | 0 | 27 | 0 | -| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Adds a `metric` renderer and function to the expression plugin. The renderer will display the `metric` chart. | 62 | 0 | 62 | 1 | -| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Expression Partition Visualization plugin adds a `partitionVis` renderer and `pieVis`, `mosaicVis`, `treemapVis`, `waffleVis` functions to the expression plugin. The renderer will display the `pie`, `waffle`, `treemap` and `mosaic` charts. | 70 | 0 | 70 | 2 | +| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Adds a `metric` renderer and function to the expression plugin. The renderer will display the `metric` chart. | 63 | 0 | 63 | 2 | +| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Expression Partition Visualization plugin adds a `partitionVis` renderer and `pieVis`, `mosaicVis`, `treemapVis`, `waffleVis` functions to the expression plugin. The renderer will display the `pie`, `waffle`, `treemap` and `mosaic` charts. | 71 | 0 | 71 | 2 | | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds 'repeatImage' function and renderer to expressions | 32 | 0 | 32 | 0 | | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds 'revealImage' function and renderer to expressions | 14 | 0 | 14 | 3 | | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds 'shape' function and renderer to expressions | 148 | 0 | 146 | 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. | 7 | 0 | 7 | 0 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Expression XY plugin adds a `xy` renderer and function to the expression plugin. The renderer will display the `xy` chart. | 159 | 0 | 149 | 9 | -| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds expression runtime to Kibana | 2191 | 73 | 1734 | 5 | +| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds expression runtime to Kibana | 2196 | 74 | 1739 | 5 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 227 | 0 | 96 | 2 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Index pattern fields and ambiguous values formatters | 288 | 26 | 249 | 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. | 62 | 0 | 62 | 2 | -| | [@elastic/kibana-app-services](https://github.com/orgs/elastic/teams/team:AppServicesUx) | File upload, download, sharing, and serving over HTTP implementation in Kibana. | 275 | 0 | 19 | 3 | -| | [Fleet](https://github.com/orgs/elastic/teams/fleet) | - | 1000 | 3 | 897 | 18 | +| | [@elastic/kibana-app-services](https://github.com/orgs/elastic/teams/team:AppServicesUx) | File upload, download, sharing, and serving over HTTP implementation in Kibana. | 276 | 0 | 19 | 3 | +| | [Fleet](https://github.com/orgs/elastic/teams/fleet) | - | 1001 | 3 | 898 | 18 | | | [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 | @@ -119,8 +119,9 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Stack Monitoring](https://github.com/orgs/elastic/teams/stack-monitoring-ui) | - | 9 | 0 | 9 | 0 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 34 | 0 | 34 | 2 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 17 | 0 | 17 | 0 | +| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 2 | 0 | 2 | 1 | | | [Observability UI](https://github.com/orgs/elastic/teams/observability-ui) | - | 556 | 40 | 553 | 31 | -| | [Security asset management](https://github.com/orgs/elastic/teams/security-asset-management) | - | 21 | 0 | 21 | 3 | +| | [Security asset management](https://github.com/orgs/elastic/teams/security-asset-management) | - | 21 | 0 | 21 | 4 | | 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). | 243 | 8 | 187 | 12 | | | [profiling](https://github.com/orgs/elastic/teams/profiling-ui) | - | 14 | 2 | 14 | 0 | diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index a98f465692920..f7accac2d65c0 100644 --- a/api_docs/presentation_util.mdx +++ b/api_docs/presentation_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/presentationUtil title: "presentationUtil" image: https://source.unsplash.com/400x175/?github description: API docs for the presentationUtil plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'presentationUtil'] --- import presentationUtilObj from './presentation_util.devdocs.json'; diff --git a/api_docs/profiling.mdx b/api_docs/profiling.mdx index d4d668ead8192..235e1d82f2f32 100644 --- a/api_docs/profiling.mdx +++ b/api_docs/profiling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/profiling title: "profiling" image: https://source.unsplash.com/400x175/?github description: API docs for the profiling plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'profiling'] --- import profilingObj from './profiling.devdocs.json'; diff --git a/api_docs/remote_clusters.mdx b/api_docs/remote_clusters.mdx index ede1b6feb6e18..0f8f8acc8a8bd 100644 --- a/api_docs/remote_clusters.mdx +++ b/api_docs/remote_clusters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/remoteClusters title: "remoteClusters" image: https://source.unsplash.com/400x175/?github description: API docs for the remoteClusters plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'remoteClusters'] --- import remoteClustersObj from './remote_clusters.devdocs.json'; diff --git a/api_docs/reporting.mdx b/api_docs/reporting.mdx index 9495dcca0124f..cf058a5b0072b 100644 --- a/api_docs/reporting.mdx +++ b/api_docs/reporting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/reporting title: "reporting" image: https://source.unsplash.com/400x175/?github description: API docs for the reporting plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reporting'] --- import reportingObj from './reporting.devdocs.json'; diff --git a/api_docs/rollup.mdx b/api_docs/rollup.mdx index 110d44a51ef75..05b079b13b255 100644 --- a/api_docs/rollup.mdx +++ b/api_docs/rollup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/rollup title: "rollup" image: https://source.unsplash.com/400x175/?github description: API docs for the rollup plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'rollup'] --- import rollupObj from './rollup.devdocs.json'; diff --git a/api_docs/rule_registry.mdx b/api_docs/rule_registry.mdx index a1660aa9abe9e..e563e3f6eb9e6 100644 --- a/api_docs/rule_registry.mdx +++ b/api_docs/rule_registry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ruleRegistry title: "ruleRegistry" image: https://source.unsplash.com/400x175/?github description: API docs for the ruleRegistry plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ruleRegistry'] --- import ruleRegistryObj from './rule_registry.devdocs.json'; diff --git a/api_docs/runtime_fields.mdx b/api_docs/runtime_fields.mdx index dccebb4795730..8913498cdae2b 100644 --- a/api_docs/runtime_fields.mdx +++ b/api_docs/runtime_fields.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/runtimeFields title: "runtimeFields" image: https://source.unsplash.com/400x175/?github description: API docs for the runtimeFields plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'runtimeFields'] --- import runtimeFieldsObj from './runtime_fields.devdocs.json'; diff --git a/api_docs/saved_objects.mdx b/api_docs/saved_objects.mdx index 8c6738ee3c7da..8dc7faff26225 100644 --- a/api_docs/saved_objects.mdx +++ b/api_docs/saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjects title: "savedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjects plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjects'] --- import savedObjectsObj from './saved_objects.devdocs.json'; diff --git a/api_docs/saved_objects_finder.mdx b/api_docs/saved_objects_finder.mdx index 058858737eee7..43722301fa8cd 100644 --- a/api_docs/saved_objects_finder.mdx +++ b/api_docs/saved_objects_finder.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsFinder title: "savedObjectsFinder" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsFinder plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsFinder'] --- import savedObjectsFinderObj from './saved_objects_finder.devdocs.json'; diff --git a/api_docs/saved_objects_management.mdx b/api_docs/saved_objects_management.mdx index 12e1390ec718a..a2059e1decd48 100644 --- a/api_docs/saved_objects_management.mdx +++ b/api_docs/saved_objects_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsManagement title: "savedObjectsManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsManagement plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsManagement'] --- import savedObjectsManagementObj from './saved_objects_management.devdocs.json'; diff --git a/api_docs/saved_objects_tagging.mdx b/api_docs/saved_objects_tagging.mdx index b7c52fcbfae39..abbda4fe4183d 100644 --- a/api_docs/saved_objects_tagging.mdx +++ b/api_docs/saved_objects_tagging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTagging title: "savedObjectsTagging" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTagging plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTagging'] --- import savedObjectsTaggingObj from './saved_objects_tagging.devdocs.json'; diff --git a/api_docs/saved_objects_tagging_oss.mdx b/api_docs/saved_objects_tagging_oss.mdx index d6dbfe2f6f7a6..613dfb32911c6 100644 --- a/api_docs/saved_objects_tagging_oss.mdx +++ b/api_docs/saved_objects_tagging_oss.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTaggingOss title: "savedObjectsTaggingOss" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTaggingOss plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTaggingOss'] --- import savedObjectsTaggingOssObj from './saved_objects_tagging_oss.devdocs.json'; diff --git a/api_docs/saved_search.mdx b/api_docs/saved_search.mdx index 6d2b4637af95b..70710966c4e18 100644 --- a/api_docs/saved_search.mdx +++ b/api_docs/saved_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedSearch title: "savedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the savedSearch plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedSearch'] --- import savedSearchObj from './saved_search.devdocs.json'; diff --git a/api_docs/screenshot_mode.mdx b/api_docs/screenshot_mode.mdx index f7c4ca4218cfc..8c2e6709336cd 100644 --- a/api_docs/screenshot_mode.mdx +++ b/api_docs/screenshot_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotMode title: "screenshotMode" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotMode plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotMode'] --- import screenshotModeObj from './screenshot_mode.devdocs.json'; diff --git a/api_docs/screenshotting.mdx b/api_docs/screenshotting.mdx index 56ec697de0c72..a6893ea5bd4d3 100644 --- a/api_docs/screenshotting.mdx +++ b/api_docs/screenshotting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotting title: "screenshotting" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotting plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotting'] --- import screenshottingObj from './screenshotting.devdocs.json'; diff --git a/api_docs/security.mdx b/api_docs/security.mdx index 09be20c329d7d..dc9d350bb721a 100644 --- a/api_docs/security.mdx +++ b/api_docs/security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/security title: "security" image: https://source.unsplash.com/400x175/?github description: API docs for the security plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'security'] --- import securityObj from './security.devdocs.json'; diff --git a/api_docs/security_solution.mdx b/api_docs/security_solution.mdx index 1d97d865a33e6..fca79f7451d2d 100644 --- a/api_docs/security_solution.mdx +++ b/api_docs/security_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolution title: "securitySolution" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolution plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolution'] --- import securitySolutionObj from './security_solution.devdocs.json'; diff --git a/api_docs/session_view.mdx b/api_docs/session_view.mdx index 6b8539eca6d44..b6222fcad49e7 100644 --- a/api_docs/session_view.mdx +++ b/api_docs/session_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/sessionView title: "sessionView" image: https://source.unsplash.com/400x175/?github description: API docs for the sessionView plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'sessionView'] --- import sessionViewObj from './session_view.devdocs.json'; diff --git a/api_docs/share.mdx b/api_docs/share.mdx index b2b08a6ea0b29..ad86cfd78a34f 100644 --- a/api_docs/share.mdx +++ b/api_docs/share.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/share title: "share" image: https://source.unsplash.com/400x175/?github description: API docs for the share plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'share'] --- import shareObj from './share.devdocs.json'; diff --git a/api_docs/snapshot_restore.mdx b/api_docs/snapshot_restore.mdx index e792894a664e3..5ce804043e037 100644 --- a/api_docs/snapshot_restore.mdx +++ b/api_docs/snapshot_restore.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/snapshotRestore title: "snapshotRestore" image: https://source.unsplash.com/400x175/?github description: API docs for the snapshotRestore plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'snapshotRestore'] --- import snapshotRestoreObj from './snapshot_restore.devdocs.json'; diff --git a/api_docs/spaces.mdx b/api_docs/spaces.mdx index 197746b59628d..a1137bd6123e2 100644 --- a/api_docs/spaces.mdx +++ b/api_docs/spaces.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/spaces title: "spaces" image: https://source.unsplash.com/400x175/?github description: API docs for the spaces plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'spaces'] --- import spacesObj from './spaces.devdocs.json'; diff --git a/api_docs/stack_alerts.mdx b/api_docs/stack_alerts.mdx index db8248b4cbf7b..b8c38cb7f3ac2 100644 --- a/api_docs/stack_alerts.mdx +++ b/api_docs/stack_alerts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackAlerts title: "stackAlerts" image: https://source.unsplash.com/400x175/?github description: API docs for the stackAlerts plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackAlerts'] --- import stackAlertsObj from './stack_alerts.devdocs.json'; diff --git a/api_docs/stack_connectors.mdx b/api_docs/stack_connectors.mdx index d108918642497..9fbdfa4d4f688 100644 --- a/api_docs/stack_connectors.mdx +++ b/api_docs/stack_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackConnectors title: "stackConnectors" image: https://source.unsplash.com/400x175/?github description: API docs for the stackConnectors plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackConnectors'] --- import stackConnectorsObj from './stack_connectors.devdocs.json'; diff --git a/api_docs/task_manager.mdx b/api_docs/task_manager.mdx index a1c53f2292eac..6eb6e15a37f39 100644 --- a/api_docs/task_manager.mdx +++ b/api_docs/task_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/taskManager title: "taskManager" image: https://source.unsplash.com/400x175/?github description: API docs for the taskManager plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'taskManager'] --- import taskManagerObj from './task_manager.devdocs.json'; diff --git a/api_docs/telemetry.mdx b/api_docs/telemetry.mdx index a4376a1f864a9..9b0e1c55aec49 100644 --- a/api_docs/telemetry.mdx +++ b/api_docs/telemetry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetry title: "telemetry" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetry plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetry'] --- import telemetryObj from './telemetry.devdocs.json'; diff --git a/api_docs/telemetry_collection_manager.mdx b/api_docs/telemetry_collection_manager.mdx index 62f1c72d7055c..0baf2016d4bae 100644 --- a/api_docs/telemetry_collection_manager.mdx +++ b/api_docs/telemetry_collection_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionManager title: "telemetryCollectionManager" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionManager plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionManager'] --- import telemetryCollectionManagerObj from './telemetry_collection_manager.devdocs.json'; diff --git a/api_docs/telemetry_collection_xpack.mdx b/api_docs/telemetry_collection_xpack.mdx index a8eb63367994e..1d30642a5cdf5 100644 --- a/api_docs/telemetry_collection_xpack.mdx +++ b/api_docs/telemetry_collection_xpack.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionXpack title: "telemetryCollectionXpack" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionXpack plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionXpack'] --- import telemetryCollectionXpackObj from './telemetry_collection_xpack.devdocs.json'; diff --git a/api_docs/telemetry_management_section.mdx b/api_docs/telemetry_management_section.mdx index 9a9158c4cdccc..7efd884126fe5 100644 --- a/api_docs/telemetry_management_section.mdx +++ b/api_docs/telemetry_management_section.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryManagementSection title: "telemetryManagementSection" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryManagementSection plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryManagementSection'] --- import telemetryManagementSectionObj from './telemetry_management_section.devdocs.json'; diff --git a/api_docs/threat_intelligence.mdx b/api_docs/threat_intelligence.mdx index 4dd6d24e1589d..187d403ca3b0b 100644 --- a/api_docs/threat_intelligence.mdx +++ b/api_docs/threat_intelligence.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/threatIntelligence title: "threatIntelligence" image: https://source.unsplash.com/400x175/?github description: API docs for the threatIntelligence plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'threatIntelligence'] --- import threatIntelligenceObj from './threat_intelligence.devdocs.json'; diff --git a/api_docs/timelines.mdx b/api_docs/timelines.mdx index e41d21340b255..58a2354c86333 100644 --- a/api_docs/timelines.mdx +++ b/api_docs/timelines.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/timelines title: "timelines" image: https://source.unsplash.com/400x175/?github description: API docs for the timelines plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'timelines'] --- import timelinesObj from './timelines.devdocs.json'; diff --git a/api_docs/transform.mdx b/api_docs/transform.mdx index 2a00d9e90f08d..76a13137515b8 100644 --- a/api_docs/transform.mdx +++ b/api_docs/transform.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/transform title: "transform" image: https://source.unsplash.com/400x175/?github description: API docs for the transform plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'transform'] --- import transformObj from './transform.devdocs.json'; diff --git a/api_docs/triggers_actions_ui.mdx b/api_docs/triggers_actions_ui.mdx index e2dd6b3aeda72..012ebfab0b991 100644 --- a/api_docs/triggers_actions_ui.mdx +++ b/api_docs/triggers_actions_ui.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/triggersActionsUi title: "triggersActionsUi" image: https://source.unsplash.com/400x175/?github description: API docs for the triggersActionsUi plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'triggersActionsUi'] --- import triggersActionsUiObj from './triggers_actions_ui.devdocs.json'; diff --git a/api_docs/ui_actions.mdx b/api_docs/ui_actions.mdx index 700d352d35d3a..8cc97cdd36e82 100644 --- a/api_docs/ui_actions.mdx +++ b/api_docs/ui_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActions title: "uiActions" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActions plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActions'] --- import uiActionsObj from './ui_actions.devdocs.json'; diff --git a/api_docs/ui_actions_enhanced.mdx b/api_docs/ui_actions_enhanced.mdx index 5bdb0e0ad5251..6871b38a55d23 100644 --- a/api_docs/ui_actions_enhanced.mdx +++ b/api_docs/ui_actions_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActionsEnhanced title: "uiActionsEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActionsEnhanced plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActionsEnhanced'] --- import uiActionsEnhancedObj from './ui_actions_enhanced.devdocs.json'; diff --git a/api_docs/unified_field_list.mdx b/api_docs/unified_field_list.mdx index 6a505b8b7390d..b6e2a92bfd494 100644 --- a/api_docs/unified_field_list.mdx +++ b/api_docs/unified_field_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedFieldList title: "unifiedFieldList" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedFieldList plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedFieldList'] --- import unifiedFieldListObj from './unified_field_list.devdocs.json'; diff --git a/api_docs/unified_histogram.mdx b/api_docs/unified_histogram.mdx index 45df0fff8b396..2f72f8fa10dbe 100644 --- a/api_docs/unified_histogram.mdx +++ b/api_docs/unified_histogram.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedHistogram title: "unifiedHistogram" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedHistogram plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedHistogram'] --- import unifiedHistogramObj from './unified_histogram.devdocs.json'; diff --git a/api_docs/unified_search.mdx b/api_docs/unified_search.mdx index a66f0aa97a7e0..dddb414e475a9 100644 --- a/api_docs/unified_search.mdx +++ b/api_docs/unified_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch title: "unifiedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch'] --- import unifiedSearchObj from './unified_search.devdocs.json'; diff --git a/api_docs/unified_search_autocomplete.mdx b/api_docs/unified_search_autocomplete.mdx index 82e5e71f4aab0..c8211171d6c84 100644 --- a/api_docs/unified_search_autocomplete.mdx +++ b/api_docs/unified_search_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch-autocomplete title: "unifiedSearch.autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch.autocomplete plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch.autocomplete'] --- import unifiedSearchAutocompleteObj from './unified_search_autocomplete.devdocs.json'; diff --git a/api_docs/url_forwarding.mdx b/api_docs/url_forwarding.mdx index 6a42326b36507..aca6a51537862 100644 --- a/api_docs/url_forwarding.mdx +++ b/api_docs/url_forwarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/urlForwarding title: "urlForwarding" image: https://source.unsplash.com/400x175/?github description: API docs for the urlForwarding plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'urlForwarding'] --- import urlForwardingObj from './url_forwarding.devdocs.json'; diff --git a/api_docs/usage_collection.mdx b/api_docs/usage_collection.mdx index c2d61e75f8b37..8622066fd2662 100644 --- a/api_docs/usage_collection.mdx +++ b/api_docs/usage_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/usageCollection title: "usageCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the usageCollection plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'usageCollection'] --- import usageCollectionObj from './usage_collection.devdocs.json'; diff --git a/api_docs/ux.mdx b/api_docs/ux.mdx index 3e687d886a017..f50a0dc12c7db 100644 --- a/api_docs/ux.mdx +++ b/api_docs/ux.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ux title: "ux" image: https://source.unsplash.com/400x175/?github description: API docs for the ux plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ux'] --- import uxObj from './ux.devdocs.json'; diff --git a/api_docs/vis_default_editor.mdx b/api_docs/vis_default_editor.mdx index a84e314d48ed3..8f64ae0ff9a39 100644 --- a/api_docs/vis_default_editor.mdx +++ b/api_docs/vis_default_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visDefaultEditor title: "visDefaultEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the visDefaultEditor plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visDefaultEditor'] --- import visDefaultEditorObj from './vis_default_editor.devdocs.json'; diff --git a/api_docs/vis_type_gauge.mdx b/api_docs/vis_type_gauge.mdx index 9219c4f9a3f09..0960b60a539d0 100644 --- a/api_docs/vis_type_gauge.mdx +++ b/api_docs/vis_type_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeGauge title: "visTypeGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeGauge plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeGauge'] --- import visTypeGaugeObj from './vis_type_gauge.devdocs.json'; diff --git a/api_docs/vis_type_heatmap.mdx b/api_docs/vis_type_heatmap.mdx index 84d6f3b8b8bff..cbca7e52fa5bd 100644 --- a/api_docs/vis_type_heatmap.mdx +++ b/api_docs/vis_type_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeHeatmap title: "visTypeHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeHeatmap plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeHeatmap'] --- import visTypeHeatmapObj from './vis_type_heatmap.devdocs.json'; diff --git a/api_docs/vis_type_pie.mdx b/api_docs/vis_type_pie.mdx index dc4eb99cbdce1..d2e5b5ca3e287 100644 --- a/api_docs/vis_type_pie.mdx +++ b/api_docs/vis_type_pie.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypePie title: "visTypePie" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypePie plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypePie'] --- import visTypePieObj from './vis_type_pie.devdocs.json'; diff --git a/api_docs/vis_type_table.mdx b/api_docs/vis_type_table.mdx index 67eaa3732a954..fbd9ee0072abb 100644 --- a/api_docs/vis_type_table.mdx +++ b/api_docs/vis_type_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTable title: "visTypeTable" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTable plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTable'] --- import visTypeTableObj from './vis_type_table.devdocs.json'; diff --git a/api_docs/vis_type_timelion.mdx b/api_docs/vis_type_timelion.mdx index 5f26ede150ecd..6155c8e51027e 100644 --- a/api_docs/vis_type_timelion.mdx +++ b/api_docs/vis_type_timelion.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimelion title: "visTypeTimelion" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimelion plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimelion'] --- import visTypeTimelionObj from './vis_type_timelion.devdocs.json'; diff --git a/api_docs/vis_type_timeseries.mdx b/api_docs/vis_type_timeseries.mdx index f1a6f30574612..2ac66a942b436 100644 --- a/api_docs/vis_type_timeseries.mdx +++ b/api_docs/vis_type_timeseries.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimeseries title: "visTypeTimeseries" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimeseries plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimeseries'] --- import visTypeTimeseriesObj from './vis_type_timeseries.devdocs.json'; diff --git a/api_docs/vis_type_vega.mdx b/api_docs/vis_type_vega.mdx index faab1f8013825..8cb417e14e9fa 100644 --- a/api_docs/vis_type_vega.mdx +++ b/api_docs/vis_type_vega.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVega title: "visTypeVega" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVega plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVega'] --- import visTypeVegaObj from './vis_type_vega.devdocs.json'; diff --git a/api_docs/vis_type_vislib.mdx b/api_docs/vis_type_vislib.mdx index 72bcc30d618a1..d9b6fface318a 100644 --- a/api_docs/vis_type_vislib.mdx +++ b/api_docs/vis_type_vislib.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVislib title: "visTypeVislib" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVislib plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVislib'] --- import visTypeVislibObj from './vis_type_vislib.devdocs.json'; diff --git a/api_docs/vis_type_xy.mdx b/api_docs/vis_type_xy.mdx index b6533d6e425d6..8c5c6fa6e7d30 100644 --- a/api_docs/vis_type_xy.mdx +++ b/api_docs/vis_type_xy.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeXy title: "visTypeXy" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeXy plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy'] --- import visTypeXyObj from './vis_type_xy.devdocs.json'; diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index 8fcde27cb1605..7e5bf18aa19e0 100644 --- a/api_docs/visualizations.mdx +++ b/api_docs/visualizations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visualizations title: "visualizations" image: https://source.unsplash.com/400x175/?github description: API docs for the visualizations plugin -date: 2022-11-03 +date: 2022-11-04 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; From f43da91786fc1b96804daf447e98712208a14736 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez=20Haro?= Date: Fri, 4 Nov 2022 09:22:01 +0100 Subject: [PATCH 05/31] [UsageCollection] Allow `pass_through` on `Record` types (#144571) --- .../mock_schema_with_descriptions.json | 6 +++++- .../parsed_working_collector_with_description.ts | 8 ++++++++ .../src/tools/manage_schema.ts | 10 +++++++++- .../src/tools/serializer.test.ts | 9 +++++++++ .../kbn-telemetry-tools/src/tools/serializer.ts | 11 +++++++++++ src/fixtures/telemetry_collectors/constants.ts | 1 + .../working_collector_with_description.ts | 8 ++++++++ .../usage_collection/server/collector/types.ts | 16 +++++++++++++--- .../server/usage/register_usage_collector.ts | 8 +++----- .../schema/xpack_plugins.json | 10 +++------- 10 files changed, 70 insertions(+), 17 deletions(-) diff --git a/packages/kbn-telemetry-tools/src/tools/__fixture__/mock_schema_with_descriptions.json b/packages/kbn-telemetry-tools/src/tools/__fixture__/mock_schema_with_descriptions.json index 77321327b3894..c7750f3fd0c39 100644 --- a/packages/kbn-telemetry-tools/src/tools/__fixture__/mock_schema_with_descriptions.json +++ b/packages/kbn-telemetry-tools/src/tools/__fixture__/mock_schema_with_descriptions.json @@ -50,7 +50,11 @@ } } }, - "my_str_array": { "type": "array", "items": { "type": "keyword" } } + "my_str_array": { "type": "array", "items": { "type": "keyword" } }, + "my_pass_through": { + "type": "pass_through", + "_meta": { "description": "Don't know what goes here. Simply passing it through."} + } } } } diff --git a/packages/kbn-telemetry-tools/src/tools/__fixture__/parsed_working_collector_with_description.ts b/packages/kbn-telemetry-tools/src/tools/__fixture__/parsed_working_collector_with_description.ts index a2f9379eec7ac..840cd7bb9595b 100644 --- a/packages/kbn-telemetry-tools/src/tools/__fixture__/parsed_working_collector_with_description.ts +++ b/packages/kbn-telemetry-tools/src/tools/__fixture__/parsed_working_collector_with_description.ts @@ -56,6 +56,10 @@ export const parsedCollectorWithDescription: ParsedUsageCollection = [ }, }, my_str_array: { type: 'array', items: { type: 'keyword' } }, + my_pass_through: { + type: 'pass_through', + _meta: { description: "Don't know what goes here. Simply passing it through." }, + }, }, }, fetch: { @@ -103,6 +107,10 @@ export const parsedCollectorWithDescription: ParsedUsageCollection = [ type: 'StringKeyword', }, }, + my_pass_through: { + kind: SyntaxKind.UnknownKeyword, + type: 'UnknownKeyword', + }, }, }, }, diff --git a/packages/kbn-telemetry-tools/src/tools/manage_schema.ts b/packages/kbn-telemetry-tools/src/tools/manage_schema.ts index cf7dfa6cf79d1..e66e72b00903f 100644 --- a/packages/kbn-telemetry-tools/src/tools/manage_schema.ts +++ b/packages/kbn-telemetry-tools/src/tools/manage_schema.ts @@ -10,7 +10,13 @@ import { ParsedUsageCollection } from './ts_parser'; export type AllowedSchemaNumberTypes = 'long' | 'integer' | 'short' | 'byte' | 'double' | 'float'; -export type AllowedSchemaTypes = AllowedSchemaNumberTypes | 'keyword' | 'text' | 'boolean' | 'date'; +export type AllowedSchemaTypes = + | AllowedSchemaNumberTypes + | 'keyword' + | 'text' + | 'boolean' + | 'date' + | 'pass_through'; export function compatibleSchemaTypes(type: AllowedSchemaTypes | 'array') { switch (type) { @@ -29,6 +35,8 @@ export function compatibleSchemaTypes(type: AllowedSchemaTypes | 'array') { return 'number'; case 'array': return 'array'; + case 'pass_through': + return 'unknown'; default: throw new Error(`Unknown schema type ${type}`); } diff --git a/packages/kbn-telemetry-tools/src/tools/serializer.test.ts b/packages/kbn-telemetry-tools/src/tools/serializer.test.ts index 5661db270186c..acb4d24cbd8ff 100644 --- a/packages/kbn-telemetry-tools/src/tools/serializer.test.ts +++ b/packages/kbn-telemetry-tools/src/tools/serializer.test.ts @@ -167,4 +167,13 @@ describe('getDescriptor', () => { prop5: { kind: ts.SyntaxKind.FirstLiteralToken, type: 'FirstLiteralToken' }, }); }); + + it('serializes RecordStringUnknown', () => { + const usageInterface = usageInterfaces.get('RecordStringUnknown')!; + const descriptor = getDescriptor(usageInterface, tsProgram); + expect(descriptor).toEqual({ + kind: ts.SyntaxKind.UnknownKeyword, + type: 'UnknownKeyword', + }); + }); }); diff --git a/packages/kbn-telemetry-tools/src/tools/serializer.ts b/packages/kbn-telemetry-tools/src/tools/serializer.ts index 31fad9a5dadb2..e6756f597b747 100644 --- a/packages/kbn-telemetry-tools/src/tools/serializer.ts +++ b/packages/kbn-telemetry-tools/src/tools/serializer.ts @@ -62,6 +62,8 @@ export function kindToDescriptorName(kind: number) { case ts.SyntaxKind.NumberKeyword: case ts.SyntaxKind.NumericLiteral: return 'number'; + case ts.SyntaxKind.UnknownKeyword: + return 'unknown'; default: throw new Error(`Unknown kind ${kind}`); } @@ -219,6 +221,15 @@ export function getDescriptor(node: ts.Node, program: ts.Program): Descriptor | // Support `Record` if (symbolName === 'Record') { + // Special use case `Record` + if ( + node.typeArguments![0].kind === ts.SyntaxKind.StringKeyword && + node.typeArguments![1].kind === ts.SyntaxKind.UnknownKeyword + ) { + const kind = node.typeArguments![1].kind; + return { kind, type: ts.SyntaxKind[kind] as keyof typeof ts.SyntaxKind }; + } + const descriptor = getDescriptor(node.typeArguments![1], program); if (node.typeArguments![0].kind === ts.SyntaxKind.StringKeyword) { return { '@@INDEX@@': descriptor }; diff --git a/src/fixtures/telemetry_collectors/constants.ts b/src/fixtures/telemetry_collectors/constants.ts index 8a669f9654ac4..c24588e36620f 100644 --- a/src/fixtures/telemetry_collectors/constants.ts +++ b/src/fixtures/telemetry_collectors/constants.ts @@ -63,6 +63,7 @@ export interface MappedTypes { export type RecordWithKnownProps = Record; export type RecordWithKnownAllProps = Record; +export type RecordStringUnknown = Record; export type IndexedAccessType = Pick; export type OmitIndexedAccessType = Omit; diff --git a/src/fixtures/telemetry_collectors/working_collector_with_description.ts b/src/fixtures/telemetry_collectors/working_collector_with_description.ts index c382a63ccd6fa..b1b5c8b66ba6a 100644 --- a/src/fixtures/telemetry_collectors/working_collector_with_description.ts +++ b/src/fixtures/telemetry_collectors/working_collector_with_description.ts @@ -24,6 +24,7 @@ interface Usage { my_index_signature_prop?: { [key: string]: number; }; + my_pass_through?: Record; } const SOME_NUMBER: number = 123; @@ -52,6 +53,9 @@ export const myCollector = makeUsageCollector({ }, ], my_str_array: ['hello', 'world'], + my_pass_through: { + some: 'key', + }, }; } catch (err) { return { @@ -94,5 +98,9 @@ export const myCollector = makeUsageCollector({ max: { type: 'long' }, min: { type: 'long' }, }, + my_pass_through: { + type: 'pass_through', + _meta: { description: "Don't know what goes here. Simply passing it through." }, + }, }, }); diff --git a/src/plugins/usage_collection/server/collector/types.ts b/src/plugins/usage_collection/server/collector/types.ts index 98271ef804952..ff5b7135ba5c0 100644 --- a/src/plugins/usage_collection/server/collector/types.ts +++ b/src/plugins/usage_collection/server/collector/types.ts @@ -8,7 +8,7 @@ import type { ElasticsearchClient, SavedObjectsClientContract, Logger } from '@kbn/core/server'; -import type { PossibleSchemaTypes } from '@kbn/analytics-client'; +import type { PossibleSchemaTypes, SchemaMetaOptional } from '@kbn/analytics-client'; export type { AllowedSchemaTypes, @@ -22,7 +22,17 @@ export type { * Helper to find out whether to keep recursively looking or if we are on an end value */ export type RecursiveMakeSchemaFrom = U extends object - ? MakeSchemaFrom + ? Record extends U + ? + | { + // pass_through should only be allowed for Record for now + type: 'pass_through'; + _meta: { + description: string; // Intentionally enforcing the descriptions here + } & SchemaMetaOptional; + } + | MakeSchemaFrom // But still allow being explicit in the definition if they want to. + : MakeSchemaFrom : { type: PossibleSchemaTypes; _meta?: { description: string } }; /** @@ -60,7 +70,7 @@ export interface CollectorFetchContext { /** * The fetch method has the context of the Collector itself * (this has access to all the properties of the collector like the logger) - * and the the first parameter is {@link CollectorFetchContext}. + * and the first parameter is {@link CollectorFetchContext}. */ export type CollectorFetchMethod = ( this: ICollector & ExtraOptions, // Specify the context of `this` for this.log and others to become available diff --git a/x-pack/plugins/cloud_integrations/cloud_experiments/server/usage/register_usage_collector.ts b/x-pack/plugins/cloud_integrations/cloud_experiments/server/usage/register_usage_collector.ts index 9a800dabe9fc8..8522a44a962e0 100644 --- a/x-pack/plugins/cloud_integrations/cloud_experiments/server/usage/register_usage_collector.ts +++ b/x-pack/plugins/cloud_integrations/cloud_experiments/server/usage/register_usage_collector.ts @@ -10,7 +10,7 @@ import type { LaunchDarklyClient } from '../launch_darkly_client'; export interface Usage { initialized: boolean; - flags: Record; + flags: Record; flagNames: string[]; } @@ -36,10 +36,8 @@ export function registerUsageCollector( }, // We'll likely map "flags" as `flattened`, so "flagNames" helps out to discover the key names flags: { - DYNAMIC_KEY: { - type: 'keyword', - _meta: { description: 'Flags received by the client' }, - }, + type: 'pass_through', + _meta: { description: 'Flags received by the client' }, }, flagNames: { type: 'array', diff --git a/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json b/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json index bae65335dfac3..6bf88ebf5e53d 100644 --- a/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json +++ b/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json @@ -4991,13 +4991,9 @@ } }, "flags": { - "properties": { - "DYNAMIC_KEY": { - "type": "keyword", - "_meta": { - "description": "Flags received by the client" - } - } + "type": "pass_through", + "_meta": { + "description": "Flags received by the client" } }, "flagNames": { From a7923d12d1653f6683fb2e5bf60faa176c3d7cbe Mon Sep 17 00:00:00 2001 From: Sander Philipse <94373878+sphilipse@users.noreply.github.com> Date: Fri, 4 Nov 2022 10:32:41 +0100 Subject: [PATCH 06/31] [Enterprise Search] Adds cancel syncs functionality for connectors (#144528) * [Enterprise Search] Adds cancel syncs functionality for connectors --- .../common/types/connectors.ts | 6 +- .../connector/cancel_syncs_api_logic.test.ts | 31 +++++ .../api/connector/cancel_syncs_api_logic.ts | 20 +++ .../header_actions/header_actions.test.tsx | 40 ++++++ .../header_actions/header_actions.tsx | 4 +- .../components/header_actions/sync_button.tsx | 55 -------- .../syncs_context_menu.test.tsx | 106 +++++++++++++++ .../header_actions/syncs_context_menu.tsx | 126 ++++++++++++++++++ .../connector/cancel_syncs_logic.test.ts | 72 ++++++++++ .../connector/cancel_syncs_logic.ts | 74 ++++++++++ .../search_index/index_view_logic.test.ts | 5 + .../search_index/index_view_logic.ts | 27 ++-- .../stop_crawl_popover_context_menu.tsx | 2 +- .../utils/sync_status_to_text.test.ts | 24 ++++ .../utils/sync_status_to_text.ts | 20 +++ .../lib/connectors/post_cancel_syncs.test.ts | 90 +++++++++++++ .../lib/connectors/post_cancel_syncs.ts | 71 ++++++++++ .../routes/enterprise_search/connectors.ts | 17 +++ 18 files changed, 723 insertions(+), 67 deletions(-) create mode 100644 x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/connector/cancel_syncs_api_logic.test.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/connector/cancel_syncs_api_logic.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/header_actions.test.tsx delete mode 100644 x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/sync_button.tsx create mode 100644 x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/syncs_context_menu.test.tsx create mode 100644 x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/syncs_context_menu.tsx create mode 100644 x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/cancel_syncs_logic.test.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/cancel_syncs_logic.ts create mode 100644 x-pack/plugins/enterprise_search/server/lib/connectors/post_cancel_syncs.test.ts create mode 100644 x-pack/plugins/enterprise_search/server/lib/connectors/post_cancel_syncs.ts diff --git a/x-pack/plugins/enterprise_search/common/types/connectors.ts b/x-pack/plugins/enterprise_search/common/types/connectors.ts index 6b38e1269a9eb..378633ce52d6a 100644 --- a/x-pack/plugins/enterprise_search/common/types/connectors.ts +++ b/x-pack/plugins/enterprise_search/common/types/connectors.ts @@ -26,9 +26,13 @@ export enum ConnectorStatus { } export enum SyncStatus { - IN_PROGRESS = 'in_progress', + CANCELING = 'canceling', + CANCELED = 'canceled', COMPLETED = 'completed', ERROR = 'error', + IN_PROGRESS = 'in_progress', + PENDING = 'pending', + SUSPENDED = 'suspended', } export interface IngestPipelineParams { diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/connector/cancel_syncs_api_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/connector/cancel_syncs_api_logic.test.ts new file mode 100644 index 0000000000000..a19b09ff5ce5b --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/connector/cancel_syncs_api_logic.test.ts @@ -0,0 +1,31 @@ +/* + * 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 { mockHttpValues } from '../../../__mocks__/kea_logic'; + +import { nextTick } from '@kbn/test-jest-helpers'; + +import { cancelSyncs } from './cancel_syncs_api_logic'; + +describe('CancelSyncsLogic', () => { + const { http } = mockHttpValues; + beforeEach(() => { + jest.clearAllMocks(); + }); + describe('cancelSyncs', () => { + it('calls correct api', async () => { + const promise = Promise.resolve('result'); + http.post.mockReturnValue(promise); + const result = cancelSyncs({ connectorId: 'connectorId1' }); + await nextTick(); + expect(http.post).toHaveBeenCalledWith( + '/internal/enterprise_search/connectors/connectorId1/cancel_syncs' + ); + await expect(result).resolves.toEqual('result'); + }); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/connector/cancel_syncs_api_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/connector/cancel_syncs_api_logic.ts new file mode 100644 index 0000000000000..297e26f2c05ec --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/connector/cancel_syncs_api_logic.ts @@ -0,0 +1,20 @@ +/* + * 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 { createApiLogic } from '../../../shared/api_logic/create_api_logic'; +import { HttpLogic } from '../../../shared/http'; + +export interface CancelSyncsApiArgs { + connectorId: string; +} + +export const cancelSyncs = async ({ connectorId }: CancelSyncsApiArgs) => { + const route = `/internal/enterprise_search/connectors/${connectorId}/cancel_syncs`; + return await HttpLogic.values.http.post(route); +}; + +export const CancelSyncsApiLogic = createApiLogic(['cancel_syncs_api_logic'], cancelSyncs); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/header_actions.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/header_actions.test.tsx new file mode 100644 index 0000000000000..ec0dfd0de3ef7 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/header_actions.test.tsx @@ -0,0 +1,40 @@ +/* + * 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 { apiIndex, connectorIndex, crawlerIndex } from '../../../../__mocks__/view_index.mock'; + +import React from 'react'; + +import { CrawlerStatusIndicator } from '../../../shared/crawler_status_indicator/crawler_status_indicator'; + +import { getHeaderActions } from './header_actions'; +import { SearchEnginesPopover } from './search_engines_popover'; +import { SyncsContextMenu } from './syncs_context_menu'; + +describe('Header Actions', () => { + it('renders api index', () => { + expect(getHeaderActions(apiIndex)).toEqual([ + , + ]); + }); + it('renders connector index', () => { + expect(getHeaderActions(connectorIndex)).toEqual([ + , + , + ]); + }); + it('renders crawler index', () => { + expect(getHeaderActions(crawlerIndex)).toEqual([ + , + , + ]); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/header_actions.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/header_actions.tsx index 10d821b87b0ee..0bf12fa6e200d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/header_actions.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/header_actions.tsx @@ -12,14 +12,14 @@ import { isCrawlerIndex, isConnectorIndex, getIngestionMethod } from '../../../. import { CrawlerStatusIndicator } from '../../../shared/crawler_status_indicator/crawler_status_indicator'; import { SearchEnginesPopover } from './search_engines_popover'; -import { SyncButton } from './sync_button'; +import { SyncsContextMenu } from './syncs_context_menu'; // Used to populate rightSideItems of an EuiPageTemplate, which is rendered right-to-left export const getHeaderActions = (indexData?: ElasticsearchIndexWithIngestion) => { const ingestionMethod = getIngestionMethod(indexData); return [ ...(isCrawlerIndex(indexData) ? [] : []), - ...(isConnectorIndex(indexData) ? [] : []), + ...(isConnectorIndex(indexData) ? [] : []), { - const { ingestionMethod, ingestionStatus, isSyncing, isWaitingForSync } = - useValues(IndexViewLogic); - const { startSync } = useActions(IndexViewLogic); - - const getSyncButtonText = () => { - if (isWaitingForSync) { - return i18n.translate( - 'xpack.enterpriseSearch.content.index.syncButton.waitingForSync.label', - { - defaultMessage: 'Waiting for sync', - } - ); - } - if (isSyncing && ingestionStatus !== IngestionStatus.ERROR) { - return i18n.translate('xpack.enterpriseSearch.content.index.syncButton.syncing.label', { - defaultMessage: 'Syncing', - }); - } - return i18n.translate('xpack.enterpriseSearch.content.index.syncButton.label', { - defaultMessage: 'Sync', - }); - }; - return ( - - {getSyncButtonText()} - - ); -}; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/syncs_context_menu.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/syncs_context_menu.test.tsx new file mode 100644 index 0000000000000..e49077f040542 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/syncs_context_menu.test.tsx @@ -0,0 +1,106 @@ +/* + * 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 '../../../../../__mocks__/shallow_useeffect.mock'; +import { setMockValues, setMockActions } from '../../../../../__mocks__/kea_logic'; + +import React from 'react'; + +import { + EuiPopover, + EuiContextMenuItem, + EuiContextMenuPanel, + EuiButton, + EuiResizeObserver, +} from '@elastic/eui'; + +import { mountWithIntl } from '@kbn/test-jest-helpers'; + +import { Status } from '../../../../../../../common/types/api'; + +import { IngestionMethod, IngestionStatus } from '../../../../types'; + +import { SyncsContextMenu } from './syncs_context_menu'; + +describe('SyncsContextMenu', () => { + const startSync = jest.fn(); + const cancelSyncs = jest.fn(); + + const mockValues = { + ingestionMethod: IngestionMethod.CONNECTOR, + ingestionStatus: IngestionStatus.CONNECTED, + isCanceling: false, + isSyncing: false, + isWaitingForSync: false, + status: Status.SUCCESS, + }; + + beforeEach(() => { + setMockValues(mockValues); + setMockActions({ + cancelSyncs, + startSync, + }); + }); + + it('renders', () => { + setMockValues({ ...mockValues, isWaitingForSync: true }); + const wrapper = mountWithIntl(); + const popover = wrapper.find(EuiPopover); + + expect(popover).toHaveLength(1); + expect(popover.props().isOpen).toEqual(false); + }); + + it('Can cancel syncs', () => { + setMockValues({ ...mockValues, isSyncing: true }); + const wrapper = mountWithIntl(); + const button = wrapper.find(EuiButton); + button.simulate('click'); + + const menuItems = wrapper + .find(EuiContextMenuPanel) + .find(EuiResizeObserver) + .find(EuiContextMenuItem); + expect(menuItems).toHaveLength(1); + + const firstButton = menuItems.get(0); + + expect(firstButton.props).toEqual( + expect.objectContaining({ + children: 'Cancel Syncs', + disabled: false, + }) + ); + menuItems.first().simulate('click'); + expect(cancelSyncs).toHaveBeenCalled(); + }); + + it('Can start a sync', () => { + setMockValues({ ...mockValues, ingestionStatus: IngestionStatus.ERROR }); + const wrapper = mountWithIntl(); + const button = wrapper.find(EuiButton); + button.simulate('click'); + + const menuItems = wrapper + .find(EuiContextMenuPanel) + .find(EuiResizeObserver) + .find(EuiContextMenuItem); + expect(menuItems).toHaveLength(2); + + const firstButton = menuItems.get(0); + + expect(firstButton.props).toEqual( + expect.objectContaining({ + children: 'Sync', + disabled: false, + }) + ); + menuItems.first().simulate('click'); + expect(startSync).toHaveBeenCalled(); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/syncs_context_menu.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/syncs_context_menu.tsx new file mode 100644 index 0000000000000..5ffda5726bdbd --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/syncs_context_menu.tsx @@ -0,0 +1,126 @@ +/* + * 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, { useState } from 'react'; + +import { useActions, useValues } from 'kea'; + +import { + EuiButton, + EuiContextMenuItem, + EuiContextMenuPanel, + EuiFlexGroup, + EuiFlexItem, + EuiLoadingSpinner, + EuiPopover, +} from '@elastic/eui'; + +import { i18n } from '@kbn/i18n'; + +import { Status } from '../../../../../../../common/types/api'; +import { CancelSyncsApiLogic } from '../../../../api/connector/cancel_syncs_api_logic'; +import { IngestionStatus } from '../../../../types'; +import { CancelSyncsLogic } from '../../connector/cancel_syncs_logic'; +import { IndexViewLogic } from '../../index_view_logic'; + +export const SyncsContextMenu: React.FC = () => { + const { ingestionMethod, ingestionStatus, isCanceling, isSyncing, isWaitingForSync } = + useValues(IndexViewLogic); + const { cancelSyncs } = useActions(CancelSyncsLogic); + const { status } = useValues(CancelSyncsApiLogic); + const { startSync } = useActions(IndexViewLogic); + + const [isPopoverOpen, setPopover] = useState(false); + + const togglePopover = () => setPopover(!isPopoverOpen); + const closePopover = () => setPopover(false); + + const getSyncButtonText = () => { + if (isWaitingForSync) { + return i18n.translate( + 'xpack.enterpriseSearch.content.index.syncButton.waitingForSync.label', + { + defaultMessage: 'Waiting for sync', + } + ); + } + if (isSyncing && ingestionStatus !== IngestionStatus.ERROR) { + return i18n.translate('xpack.enterpriseSearch.content.index.syncButton.syncing.label', { + defaultMessage: 'Syncing', + }); + } + return i18n.translate('xpack.enterpriseSearch.content.index.syncButton.label', { + defaultMessage: 'Sync', + }); + }; + + const syncLoading = (isSyncing || isWaitingForSync) && ingestionStatus !== IngestionStatus.ERROR; + + return ( + + + {syncLoading && ( + + + + )} + {getSyncButtonText()} + + + } + isOpen={isPopoverOpen} + closePopover={closePopover} + panelPaddingSize="none" + anchorPosition="downLeft" + > + { + closePopover(); + startSync(); + }} + icon="play" + > + {getSyncButtonText()} + , + ]), + { + closePopover(); + cancelSyncs(); + }} + icon="trash" + > + {i18n.translate('xpack.enterpriseSearch.index.header.cancelSyncsTitle', { + defaultMessage: 'Cancel Syncs', + })} + , + ]} + /> + + ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/cancel_syncs_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/cancel_syncs_logic.test.ts new file mode 100644 index 0000000000000..a63dac6806cc8 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/cancel_syncs_logic.test.ts @@ -0,0 +1,72 @@ +/* + * 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 { LogicMounter, mockFlashMessageHelpers } from '../../../../__mocks__/kea_logic'; + +import { indices } from '../../../__mocks__/search_indices.mock'; + +import { FetchIndexApiLogic } from '../../../api/index/fetch_index_api_logic'; +import { IndexViewLogic } from '../index_view_logic'; + +import { CancelSyncsLogic } from './cancel_syncs_logic'; + +describe('CancelSyncsLogic', () => { + const { mount } = new LogicMounter(CancelSyncsLogic); + const { mount: IndexViewLogicMount } = new LogicMounter(IndexViewLogic); + const { mount: FetchIndexApiLogicMount } = new LogicMounter(FetchIndexApiLogic); + const { clearFlashMessages, flashAPIErrors, flashSuccessToast } = mockFlashMessageHelpers; + const DEFAULT_VALUES = { + connectorId: null, + isConnectorIndex: false, + }; + + beforeEach(() => { + jest.clearAllMocks(); + IndexViewLogicMount(); + FetchIndexApiLogicMount(); + mount(); + }); + it('has expected default values', () => { + expect(CancelSyncsLogic.values).toEqual(DEFAULT_VALUES); + }); + + describe('actions', () => { + describe('cancelSyncs', () => { + it('should not call makeCancelSyncRequest if index is not a connector', () => { + CancelSyncsLogic.actions.makeCancelSyncsRequest = jest.fn(); + CancelSyncsLogic.actions.cancelSyncs(); + expect(CancelSyncsLogic.actions.makeCancelSyncsRequest).not.toHaveBeenCalled(); + }); + it('should call clearFlashMessages and request if index is a connector', () => { + CancelSyncsLogic.actions.makeCancelSyncsRequest = jest.fn(); + FetchIndexApiLogic.actions.apiSuccess(indices[1]); + CancelSyncsLogic.actions.cancelSyncs(); + expect(CancelSyncsLogic.actions.makeCancelSyncsRequest).toHaveBeenCalled(); + }); + }); + describe('makeRequest', () => { + it('should call clearFlashMessages', () => { + CancelSyncsLogic.actions.makeCancelSyncsRequest({ + connectorId: 'id', + }); + expect(clearFlashMessages).toHaveBeenCalled(); + }); + }); + describe('apiError', () => { + it('should call flashAPIError', () => { + CancelSyncsLogic.actions.cancelSyncsApiError('error' as any); + expect(flashAPIErrors).toHaveBeenCalledWith('error'); + }); + }); + describe('apiSuccess', () => { + it('should call flashAPIError', () => { + CancelSyncsLogic.actions.cancelSyncsApiSuccess('success' as any); + expect(flashSuccessToast).toHaveBeenCalledWith('Successfully canceled syncs'); + }); + }); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/cancel_syncs_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/cancel_syncs_logic.ts new file mode 100644 index 0000000000000..73fa34d69c83d --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/cancel_syncs_logic.ts @@ -0,0 +1,74 @@ +/* + * 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 { kea, MakeLogicType } from 'kea'; + +import { i18n } from '@kbn/i18n'; + +import { Actions } from '../../../../shared/api_logic/create_api_logic'; +import { + clearFlashMessages, + flashAPIErrors, + flashSuccessToast, +} from '../../../../shared/flash_messages'; + +import { + CancelSyncsApiArgs, + CancelSyncsApiLogic, +} from '../../../api/connector/cancel_syncs_api_logic'; +import { IndexViewLogic } from '../index_view_logic'; + +type CancelSyncsApiActions = Actions; + +interface CancelSyncsLogicValues { + connectorId?: string; + isConnectorIndex: boolean; +} + +interface CancelSyncsLogicActions { + cancelSyncs: () => void; + cancelSyncsApiError: CancelSyncsApiActions['apiError']; + cancelSyncsApiSuccess: CancelSyncsApiActions['apiSuccess']; + makeCancelSyncsRequest: CancelSyncsApiActions['makeRequest']; +} + +export const CancelSyncsLogic = kea>( + { + actions: { + cancelSyncs: true, + }, + connect: { + actions: [ + CancelSyncsApiLogic, + [ + 'apiError as cancelSyncsApiError', + 'apiSuccess as cancelSyncsApiSuccess', + 'makeRequest as makeCancelSyncsRequest', + ], + ], + values: [IndexViewLogic, ['connectorId', 'isConnectorIndex']], + }, + listeners: ({ actions, values }) => ({ + cancelSyncs: () => { + if (values.isConnectorIndex && values.connectorId) { + actions.makeCancelSyncsRequest({ connectorId: values.connectorId }); + } + }, + cancelSyncsApiError: (e) => flashAPIErrors(e), + cancelSyncsApiSuccess: () => { + flashSuccessToast( + i18n.translate('xpack.enterpriseSearch.content.searchIndex.cancelSyncs.successMessage', { + defaultMessage: 'Successfully canceled syncs', + }) + ); + }, + makeCancelSyncsRequest: () => { + clearFlashMessages(); + }, + }), + } +); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_view_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_view_logic.test.ts index 1b0a11d17f546..2bce9072d169d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_view_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_view_logic.test.ts @@ -32,6 +32,8 @@ const DEFAULT_VALUES = { indexName: '', ingestionMethod: IngestionMethod.API, ingestionStatus: IngestionStatus.CONNECTED, + isCanceling: false, + isConnectorIndex: false, isSyncing: false, isWaitingForSync: false, lastUpdated: null, @@ -93,8 +95,11 @@ describe('IndexViewLogic', () => { ...CONNECTOR_VALUES.index, connector: { ...CONNECTOR_VALUES.index.connector, sync_now: true }, }, + isCanceling: false, + isConnectorIndex: true, isWaitingForSync: true, localSyncNowValue: true, + pipelineData: undefined, syncStatus: SyncStatus.COMPLETED, }) ); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_view_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_view_logic.ts index 454bc5f9a0be0..a31b4f4b491f6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_view_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_view_logic.ts @@ -14,6 +14,7 @@ import { IngestPipelineParams, SyncStatus, } from '../../../../../common/types/connectors'; +import { ElasticsearchIndexWithIngestion } from '../../../../../common/types/indices'; import { Actions } from '../../../shared/api_logic/create_api_logic'; import { flashAPIErrors, @@ -43,25 +44,26 @@ import { IndexNameLogic } from './index_name_logic'; const FETCH_INDEX_POLLING_DURATION = 5000; // 1 seconds const FETCH_INDEX_POLLING_DURATION_ON_FAILURE = 30000; // 30 seconds -type FetchIndexApiValues = Actions; -type StartSyncApiValues = Actions; +type FetchIndexApiActions = Actions; +type StartSyncApiActions = Actions; export interface IndexViewActions { + cancelSyncs(): void; clearFetchIndexTimeout(): void; createNewFetchIndexTimeout(duration: number): { duration: number }; fetchCrawlerData: () => void; fetchIndex: () => void; - fetchIndexApiSuccess: FetchIndexApiValues['apiSuccess']; - makeFetchIndexRequest: FetchIndexApiValues['makeRequest']; - makeStartSyncRequest: StartSyncApiValues['makeRequest']; + fetchIndexApiSuccess: FetchIndexApiActions['apiSuccess']; + makeFetchIndexRequest: FetchIndexApiActions['makeRequest']; + makeStartSyncRequest: StartSyncApiActions['makeRequest']; recheckIndex: () => void; - resetFetchIndexApi: FetchIndexApiValues['apiReset']; + resetFetchIndexApi: FetchIndexApiActions['apiReset']; resetRecheckIndexLoading: () => void; setFetchIndexTimeoutId(timeoutId: NodeJS.Timeout): { timeoutId: NodeJS.Timeout }; startFetchIndexPoll(): void; startSync(): void; - startSyncApiError: StartSyncApiValues['apiError']; - startSyncApiSuccess: StartSyncApiValues['apiSuccess']; + startSyncApiError: StartSyncApiActions['apiError']; + startSyncApiSuccess: StartSyncApiActions['apiSuccess']; stopFetchIndexPoll(): void; } @@ -74,6 +76,7 @@ export interface IndexViewValues { indexName: string; ingestionMethod: IngestionMethod; ingestionStatus: IngestionStatus; + isCanceling: boolean; isSyncing: boolean; isWaitingForSync: boolean; lastUpdated: string | null; @@ -237,6 +240,14 @@ export const IndexViewLogic = kea [selectors.data], (data) => (data ? indexToViewIndex(data) : undefined)], ingestionMethod: [() => [selectors.data], (data) => getIngestionMethod(data)], ingestionStatus: [() => [selectors.data], (data) => getIngestionStatus(data)], + isCanceling: [ + () => [selectors.syncStatus], + (syncStatus: SyncStatus) => syncStatus === SyncStatus.CANCELING, + ], + isConnectorIndex: [ + () => [selectors.data], + (data: ElasticsearchIndexWithIngestion | undefined) => isConnectorIndex(data), + ], isSyncing: [ () => [selectors.syncStatus], (syncStatus: SyncStatus) => syncStatus === SyncStatus.IN_PROGRESS, diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/shared/crawler_status_indicator/stop_crawl_popover_context_menu.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/shared/crawler_status_indicator/stop_crawl_popover_context_menu.tsx index 2c9024b5b771b..d893369eace3e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/shared/crawler_status_indicator/stop_crawl_popover_context_menu.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/shared/crawler_status_indicator/stop_crawl_popover_context_menu.tsx @@ -73,7 +73,7 @@ export const StopCrawlPopoverContextMenu: React.FC = () => { {i18n.translate( 'xpack.enterpriseSearch.crawler.crawlerStatusIndicator.cancelCrawlMenuItemLabel', { - defaultMessage: 'Cancel Crawl', + defaultMessage: 'Cancel Crawls', } )} , diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/utils/sync_status_to_text.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/utils/sync_status_to_text.test.ts index d9ecdf6ebc556..4272eaf11641e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/utils/sync_status_to_text.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/utils/sync_status_to_text.test.ts @@ -19,6 +19,18 @@ describe('syncStatusToText', () => { it('should return correct value for in progress', () => { expect(syncStatusToText(SyncStatus.IN_PROGRESS)).toEqual('Sync in progress'); }); + it('should return correct value for canceling', () => { + expect(syncStatusToText(SyncStatus.CANCELING)).toEqual('Canceling sync'); + }); + it('should return correct value for canceled', () => { + expect(syncStatusToText(SyncStatus.CANCELED)).toEqual('Sync canceled'); + }); + it('should return correct value for pending', () => { + expect(syncStatusToText(SyncStatus.PENDING)).toEqual('Sync pending'); + }); + it('should return correct value for suspended', () => { + expect(syncStatusToText(SyncStatus.SUSPENDED)).toEqual('Sync suspended'); + }); }); describe('syncStatusToColor', () => { @@ -31,4 +43,16 @@ describe('syncStatusToColor', () => { it('should return correct value for in progress', () => { expect(syncStatusToColor(SyncStatus.IN_PROGRESS)).toEqual('warning'); }); + it('should return correct value for canceling', () => { + expect(syncStatusToColor(SyncStatus.CANCELING)).toEqual('warning'); + }); + it('should return correct value for canceled', () => { + expect(syncStatusToColor(SyncStatus.CANCELED)).toEqual('danger'); + }); + it('should return correct value for pending', () => { + expect(syncStatusToColor(SyncStatus.PENDING)).toEqual('warning'); + }); + it('should return correct value for suspended', () => { + expect(syncStatusToColor(SyncStatus.SUSPENDED)).toEqual('warning'); + }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/utils/sync_status_to_text.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/utils/sync_status_to_text.ts index 51d69f2e53ad7..5d79f92565a34 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/utils/sync_status_to_text.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/utils/sync_status_to_text.ts @@ -23,6 +23,22 @@ export function syncStatusToText(status: SyncStatus): string { return i18n.translate('xpack.enterpriseSearch.content.syncStatus.inProgress', { defaultMessage: 'Sync in progress', }); + case SyncStatus.CANCELED: + return i18n.translate('xpack.enterpriseSearch.content.syncStatus.canceling', { + defaultMessage: 'Sync canceled', + }); + case SyncStatus.CANCELING: + return i18n.translate('xpack.enterpriseSearch.content.syncStatus.canceled', { + defaultMessage: 'Canceling sync', + }); + case SyncStatus.PENDING: + return i18n.translate('xpack.enterpriseSearch.content.syncStatus.pending', { + defaultMessage: 'Sync pending', + }); + case SyncStatus.SUSPENDED: + return i18n.translate('xpack.enterpriseSearch.content.syncStatus.suspended', { + defaultMessage: 'Sync suspended', + }); } } @@ -31,8 +47,12 @@ export function syncStatusToColor(status: SyncStatus): string { case SyncStatus.COMPLETED: return 'success'; case SyncStatus.ERROR: + case SyncStatus.CANCELED: return 'danger'; case SyncStatus.IN_PROGRESS: + case SyncStatus.PENDING: + case SyncStatus.SUSPENDED: + case SyncStatus.CANCELING: return 'warning'; } } diff --git a/x-pack/plugins/enterprise_search/server/lib/connectors/post_cancel_syncs.test.ts b/x-pack/plugins/enterprise_search/server/lib/connectors/post_cancel_syncs.test.ts new file mode 100644 index 0000000000000..ed4544cdeb2eb --- /dev/null +++ b/x-pack/plugins/enterprise_search/server/lib/connectors/post_cancel_syncs.test.ts @@ -0,0 +1,90 @@ +/* + * 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 { IScopedClusterClient } from '@kbn/core/server'; + +import { CONNECTORS_INDEX, CONNECTORS_JOBS_INDEX } from '../..'; +import { SyncStatus } from '../../../common/types/connectors'; + +import { cancelSyncs } from './post_cancel_syncs'; + +describe('addConnector lib function', () => { + const mockClient = { + asCurrentUser: { + update: jest.fn(), + updateByQuery: jest.fn(), + }, + asInternalUser: {}, + }; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should call updateByQuery to cancel syncs', async () => { + mockClient.asCurrentUser.updateByQuery.mockImplementation(() => ({ _id: 'fakeId' })); + + await expect( + cancelSyncs(mockClient as unknown as IScopedClusterClient, 'connectorId') + ).resolves.toEqual(undefined); + expect(mockClient.asCurrentUser.updateByQuery).toHaveBeenCalledTimes(2); + expect(mockClient.asCurrentUser.updateByQuery).toHaveBeenCalledWith({ + index: CONNECTORS_JOBS_INDEX, + query: { + bool: { + must: [ + { + term: { + connector_id: 'connectorId', + }, + }, + { + terms: { + status: [SyncStatus.IN_PROGRESS], + }, + }, + ], + }, + }, + refresh: true, + script: { + lang: 'painless', + source: `ctx._source['status'] = '${SyncStatus.CANCELING}'`, + }, + }); + expect(mockClient.asCurrentUser.updateByQuery).toHaveBeenCalledWith({ + index: CONNECTORS_JOBS_INDEX, + query: { + bool: { + must: [ + { + term: { + connector_id: 'connectorId', + }, + }, + { + terms: { + status: [SyncStatus.PENDING, SyncStatus.SUSPENDED], + }, + }, + ], + }, + }, + refresh: true, + script: { + lang: 'painless', + source: `ctx._source['status'] = '${SyncStatus.CANCELED}'`, + }, + }); + await expect(mockClient.asCurrentUser.update).toHaveBeenCalledWith({ + doc: { last_sync_status: SyncStatus.CANCELED, sync_now: false }, + id: 'connectorId', + index: CONNECTORS_INDEX, + refresh: true, + }); + }); +}); diff --git a/x-pack/plugins/enterprise_search/server/lib/connectors/post_cancel_syncs.ts b/x-pack/plugins/enterprise_search/server/lib/connectors/post_cancel_syncs.ts new file mode 100644 index 0000000000000..91b439f072d94 --- /dev/null +++ b/x-pack/plugins/enterprise_search/server/lib/connectors/post_cancel_syncs.ts @@ -0,0 +1,71 @@ +/* + * 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 { IScopedClusterClient } from '@kbn/core-elasticsearch-server'; + +import { CONNECTORS_INDEX, CONNECTORS_JOBS_INDEX } from '../..'; +import { SyncStatus } from '../../../common/types/connectors'; + +export const cancelSyncs = async ( + client: IScopedClusterClient, + connectorId: string +): Promise => { + await client.asCurrentUser.updateByQuery({ + index: CONNECTORS_JOBS_INDEX, + query: { + bool: { + must: [ + { + term: { + connector_id: connectorId, + }, + }, + { + terms: { + status: [SyncStatus.PENDING, SyncStatus.SUSPENDED], + }, + }, + ], + }, + }, + refresh: true, + script: { + lang: 'painless', + source: `ctx._source['status'] = '${SyncStatus.CANCELED}'`, + }, + }); + await client.asCurrentUser.updateByQuery({ + index: CONNECTORS_JOBS_INDEX, + query: { + bool: { + must: [ + { + term: { + connector_id: connectorId, + }, + }, + { + terms: { + status: [SyncStatus.IN_PROGRESS], + }, + }, + ], + }, + }, + refresh: true, + script: { + lang: 'painless', + source: `ctx._source['status'] = '${SyncStatus.CANCELING}'`, + }, + }); + await client.asCurrentUser.update({ + doc: { last_sync_status: SyncStatus.CANCELED, sync_now: false }, + id: connectorId, + index: CONNECTORS_INDEX, + refresh: true, + }); +}; diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/connectors.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/connectors.ts index 9663b216ec91c..81207f19d1261 100644 --- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/connectors.ts +++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/connectors.ts @@ -14,6 +14,7 @@ import { ConnectorStatus } from '../../../common/types/connectors'; import { ErrorCode } from '../../../common/types/error_codes'; import { addConnector } from '../../lib/connectors/add_connector'; import { fetchSyncJobsByConnectorId } from '../../lib/connectors/fetch_sync_jobs'; +import { cancelSyncs } from '../../lib/connectors/post_cancel_syncs'; import { startConnectorSync } from '../../lib/connectors/start_sync'; import { updateConnectorConfiguration } from '../../lib/connectors/update_connector_configuration'; import { updateConnectorNameAndDescription } from '../../lib/connectors/update_connector_name_and_description'; @@ -69,6 +70,22 @@ export function registerConnectorRoutes({ router, log }: RouteDependencies) { }) ); + router.post( + { + path: '/internal/enterprise_search/connectors/{connectorId}/cancel_syncs', + validate: { + params: schema.object({ + connectorId: schema.string(), + }), + }, + }, + elasticsearchErrorHandler(log, async (context, request, response) => { + const { client } = (await context.core).elasticsearch; + await cancelSyncs(client, request.params.connectorId); + return response.ok(); + }) + ); + router.post( { path: '/internal/enterprise_search/connectors/{connectorId}/configuration', From 9e6ee2a58cf54fa902708b94a47c8bd00e364b3a Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Fri, 4 Nov 2022 09:39:26 +0000 Subject: [PATCH 07/31] support dotted notation in elasticsearch settings and mappings (#144570) (cherry picked from commit 4de8993fe96824ae125622bff264a4b15b42516e) --- .../server/services/epm/archive/parse.test.ts | 14 +++++++++++++ .../server/services/epm/archive/parse.ts | 20 ++++++++++--------- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/x-pack/plugins/fleet/server/services/epm/archive/parse.test.ts b/x-pack/plugins/fleet/server/services/epm/archive/parse.test.ts index a6c59f6dea616..38a070e7eca8f 100644 --- a/x-pack/plugins/fleet/server/services/epm/archive/parse.test.ts +++ b/x-pack/plugins/fleet/server/services/epm/archive/parse.test.ts @@ -54,6 +54,9 @@ describe('parseDefaultIngestPipeline', () => { }); describe('parseDataStreamElasticsearchEntry', () => { + it('Should handle undefined elasticsearch', () => { + expect(parseDataStreamElasticsearchEntry()).toEqual({}); + }); it('Should handle empty elasticsearch', () => { expect(parseDataStreamElasticsearchEntry({})).toEqual({}); }); @@ -108,4 +111,15 @@ describe('parseDataStreamElasticsearchEntry', () => { }, }); }); + it('Should handle dotted values for mappings and settings', () => { + expect( + parseDataStreamElasticsearchEntry({ + 'index_template.mappings': { dynamic: false }, + 'index_template.settings': { 'index.lifecycle.name': 'reference' }, + }) + ).toEqual({ + 'index_template.mappings': { dynamic: false }, + 'index_template.settings': { 'index.lifecycle.name': 'reference' }, + }); + }); }); diff --git a/x-pack/plugins/fleet/server/services/epm/archive/parse.ts b/x-pack/plugins/fleet/server/services/epm/archive/parse.ts index a6107d81355c4..06a92e84c0af6 100644 --- a/x-pack/plugins/fleet/server/services/epm/archive/parse.ts +++ b/x-pack/plugins/fleet/server/services/epm/archive/parse.ts @@ -503,7 +503,7 @@ export function parseAndVerifyInputs(manifestInputs: any, location: string): Reg } export function parseDataStreamElasticsearchEntry( - elasticsearch: Record, + elasticsearch?: Record, ingestPipeline?: string ) { const parsedElasticsearchEntry: Record = {}; @@ -520,16 +520,18 @@ export function parseDataStreamElasticsearchEntry( parsedElasticsearchEntry.source_mode = elasticsearch.source_mode; } - if (elasticsearch?.index_template?.mappings) { - parsedElasticsearchEntry['index_template.mappings'] = expandDottedEntries( - elasticsearch.index_template.mappings - ); + const indexTemplateMappings = + elasticsearch?.index_template?.mappings || elasticsearch?.['index_template.mappings']; + if (indexTemplateMappings) { + parsedElasticsearchEntry['index_template.mappings'] = + expandDottedEntries(indexTemplateMappings); } - if (elasticsearch?.index_template?.settings) { - parsedElasticsearchEntry['index_template.settings'] = expandDottedEntries( - elasticsearch.index_template.settings - ); + const indexTemplateSettings = + elasticsearch?.index_template?.settings || elasticsearch?.['index_template.settings']; + if (indexTemplateSettings) { + parsedElasticsearchEntry['index_template.settings'] = + expandDottedEntries(indexTemplateSettings); } return parsedElasticsearchEntry; From d4064c888a65bf1c170905a3a24a2f2f3adac179 Mon Sep 17 00:00:00 2001 From: Tre Date: Fri, 4 Nov 2022 10:06:25 +0000 Subject: [PATCH 08/31] [Archive Migrations] security_solution-timelines (#142363) * [Archive Migrations] security_solution-timelines Add new kbn archive with an index pattern taken from the es archive. Change the test to use both es and kbn archives. Since all these objects are loaded into a space, just delete the space afterwards instead of unloading with es archiver. Helps with: #102552 * Drop exclusive * Drop unneeded fn. * Lint in my pocket. * Thanks to J. Buttner, "re-drop" non needed objects from the original archive. Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- scripts/archive_migration_functions.sh | 29 ++++++++++++++---- .../security_solution/timeline_migrations.ts | 12 +++++--- .../timelines/7.15.0_space/data.json.gz | Bin 3247 -> 2832 bytes .../security_solution/timelines/7.15.0_space | 20 ++++++++++++ 4 files changed, 50 insertions(+), 11 deletions(-) create mode 100644 x-pack/test/functional/fixtures/kbn_archiver/security_solution/timelines/7.15.0_space diff --git a/scripts/archive_migration_functions.sh b/scripts/archive_migration_functions.sh index 7dcba01175731..36c7f61abdba1 100755 --- a/scripts/archive_migration_functions.sh +++ b/scripts/archive_migration_functions.sh @@ -1,13 +1,30 @@ -standard_list="url,index-pattern,query,graph-workspace,tag,visualization,canvas-element,canvas-workpad,dashboard,search,lens,map,cases,uptime-dynamic-settings,osquery-saved-query,osquery-pack,infrastructure-ui-source,metrics-explorer-view,inventory-view,infrastructure-monitoring-log-view,apm-indices" +#!/bin/bash + +# ??? Should we migrate +# x-pack/test/functional/es_archives/security_solution/timelines/7.15.0_space +# ### Yes, it needs migration +# ### Saved Object type(s) that we care about: +# index-pattern +# ### Test file(s) that use it: +# x-pack/test/api_integration/apis/security_solution/timeline_migrations.ts +# ### Config(s) that govern the test file(s): +# x-pack/test/api_integration/config.ts +# The other types it contains: +# config +# index-pattern +# siem-ui-timeline +# siem-ui-timeline-note +# siem-ui-timeline-pinned-event +# space -orig_archive="x-pack/test/functional/es_archives/banners/multispace" -new_archive="x-pack/test/functional/fixtures/kbn_archiver/banners/multi_space" +standard_list="url,index-pattern,query,graph-workspace,tag,visualization,canvas-element,canvas-workpad,dashboard,search,lens,map,cases,uptime-dynamic-settings,osquery-saved-query,osquery-pack,infrastructure-ui-source,metrics-explorer-view,inventory-view,infrastructure-monitoring-log-view,apm-indices" -# newArchives=("x-pack/test/functional/fixtures/kbn_archiver/dashboard/session_in_space") +orig_archive="x-pack/test/functional/es_archives/security_solution/timelines/7.15.0_space" +new_archive="x-pack/test/functional/fixtures/kbn_archiver/security_solution/timelines/7.15.0_space" -# testFiles=("x-pack/test/functional/apps/discover/preserve_url.ts") +testFiles=("x-pack/test/api_integration/apis/security_solution/timeline_migrations.ts") -test_config="x-pack/test/banners_functional/config.ts" +test_config="x-pack/test/api_integration/config.ts" list_stragglers() { diff --git a/x-pack/test/api_integration/apis/security_solution/timeline_migrations.ts b/x-pack/test/api_integration/apis/security_solution/timeline_migrations.ts index 47c6e28d9bab7..fe47677040d73 100644 --- a/x-pack/test/api_integration/apis/security_solution/timeline_migrations.ts +++ b/x-pack/test/api_integration/apis/security_solution/timeline_migrations.ts @@ -36,6 +36,8 @@ export default function ({ getService }: FtrProviderContext) { describe('Timeline migrations', () => { const esArchiver = getService('esArchiver'); const es = getService('es'); + const kibanaServer = getService('kibanaServer'); + const spacesService = getService('spaces'); describe('8.0 id migration', () => { const resolveWithSpaceApi = '/s/awesome-space/api/timeline/resolve'; @@ -44,14 +46,14 @@ export default function ({ getService }: FtrProviderContext) { await esArchiver.load( 'x-pack/test/functional/es_archives/security_solution/timelines/7.15.0_space' ); - }); - - after(async () => { - await esArchiver.unload( - 'x-pack/test/functional/es_archives/security_solution/timelines/7.15.0_space' + await kibanaServer.importExport.load( + 'x-pack/test/functional/fixtures/kbn_archiver/security_solution/timelines/7.15.0_space', + { space: 'awesome-space' } ); }); + after(async () => await spacesService.delete('awesome-space')); + describe('resolve', () => { it('should return an aliasMatch outcome', async () => { const resp = await supertest diff --git a/x-pack/test/functional/es_archives/security_solution/timelines/7.15.0_space/data.json.gz b/x-pack/test/functional/es_archives/security_solution/timelines/7.15.0_space/data.json.gz index 9036d465e3fcee3694ac527d169d6d84d14f002d..863d72c8f64d17bd6bcb4269b9dead1f2d065ebc 100644 GIT binary patch literal 2832 zcmV+r3-9zFiwFP!000026YX4EbKAHTe)q57@TuJ~6oPl^so8eh`XSpiadz5985<-( zi4%%cc=2UD{_i~iNtvXmt0h_XGVzRQ;s7`|92|TH(!-e~$=Usk$wNt|u_vGN7dIr# z`I`s$1O5ysZzZ=Zji(HyGvcvf8n7wK1C#|*76uU;VijXo*A%20zKt+u9wLs7k!xAD zZh0p2HARfh2aG7Y<6{oK2QG=o6|P#+I8VH%so{+mC+tHoPDmES(QhnC;TP{}4X`n& zMg+QuOqpP9f!8ORg!wFCk;hUX`dYsIHg9grRAWOh66VvW-jn}(s6Ee#{>cbs$z`e5 zD9(@{gc(dt=e(5kg=+u8XG}9Poh`I;O$m0RJPccnT;%SSl##@n5I3yaYt4`6`({54 z#t{hzNglERWvQ10Gj6O`DGR${Q8pmns}*3D#NglQK=AXj0+8`IVPle&J+mZdt&u&F zv2mQ-*BEc}ysZ}M4hW=|6DHlp$@d@{OEgHBm%(&W>`NImRJv-9!R}xw3ZCV66Nn@4 zNEmo*wZ6+quI7^*O8Kq!DtM<^0@KT{$TaVhga}iV!%HL?=TlgI>A3{KFv+;hZi8$h zY(?A@rpv%+gujVL5q}FB^>QJ_U=)p_4=|w1q>2F`Pld0HG zR$2b*NPd^6$vZcQ-lgeeB%hCD6pCMY$`bK_l>z^c&5`_VwR?bU=}CLU^Pn(TyBlZNy4|Pr(yemvva^XMDTci%qT5<@}c7tZ2Pe^X+T$*MOSro zBb^^Go-I*%luuoj97g5b_x7ys&yzUGBrdiTCsG)XgQ&`?_-w0;Ktd2S>o$Yvd&t!F z1sr}7r`evh|Eth@p>96Bh+h|(QS1Nb$2U_b(wy zv%sqfBU5k{2v9emm}CurKqA^AXfRW(rHBhhyFHKHd0|dPt53p|b*j8VI1omfXmI*WrSTcq?i87`i&gusD~(+wA!Zx*I$P&_ViF3Nn8 zhuM1X0^eYtNHk_Gweb1)K&ql*gcYP1m)IO)XK1Jc@V@^wIF-eDsX?x{$j>@BZikh+ z&k7)<3QZ&o8*QbJeTr{CiB->%3)*z-x`;(kTiy=t^dY8VqJmUzHdemYP)|YG)x zz80L%64>S!<*hmfh1QD!R$3YYUjX6qcSfJqLZ`Ls3Qx&RNq<2XqLZA)!iWtyi=E

%u8L(G!0clKK4wcd)P;| zrD0@x%wW`EhJ~$FqddX3YMrWVt(>gt)fg$rilpHmECPLd(l6yIl&Z1o)cK6AiPR-U zGg6Ug&KV?@PZ?o>p!0M1x`m1KI*4EgMJK~PC_4MYD@947byo=Ml^B+h4uPK#M$AwFJ(S>+FXi&Pr$K()n^%={-PO4)7vLkp|Lp2dqm$uR&UU>jC0>55f*_lDYBo4G`-!(RMix5ZfJLYS#X z?z)k?V@Aj)C}}5D$Fi;Cp*qsSp>z$jvjM!*4e=0$ZRYDP@=ZrUIvfxXQFV$K)?CxZ zw(k;K?igqV%+rK=vI$q!fJJaHn-m3=DaUpg6_*|#yE?B#fHp;eHbsJ(XwVvV<<8!# zL82B=v{oSt-5)ztv~k!KvRvKsRf{3hvTdYOn;{3olV#eLuP~P=zIrH!5>|Xg z9#zmB)TK(5?8m2$hdf)k4`t1)8KcmN31A~ z*IB?^u_7#9wiWWY%(3c06 zmj~9upBHOx7q2N7EL-q9l@4^rAk-oj(y+;pZs!qT-(BpBDE&qF6A72EspNBDH~GU= zl3wwR=2u*xIvFqCQ{C$|MZ5kY{3+~}2fy&WWAV>^i^V^tS@7c-h?vYmx~AEPzzH7d zmg~Eo<|z!bXVq$&(QZGLnbje*8*<--lR5~$$rM{vXxh`iwt5WnEX(#4jIgb!NLPFX zIn;L%qc&yOHx1KscdEzC6T0WsU6v+>UB0k%&bkY%7;xiyOKqZ)sH@o9)m7~N0|EU9 z0(M9B9c*i`a~epsO^S5pGUVE}jxbRbn_`TKr5p*>|CMF@I~cYA^z9b{^pE|40H!j> z?!TF5zkvR3r`+AR02Wd*X7Ulf`DT7vI^MVJyugjX{Z~%rnZ(f!--n*-=>)p{amvP; zg0*GGDGOs$#ky&3cA(lRCo(S;ZD>Hibq0>(tj&pxOGO_l3j7QdMcE-Idc!wE!WX$0 z62{{c{nQktc~_*lm7G@ocok4-DE+kWH1c62yKx+jec`$8YB&c^X8)G@o7-y{^QaFrdMYkEe1QrJ%ZO?yLL0vBLM9oArrpOT^`A zYn!l@xmNd?x)Rs-kyN^{lx>o;+N$E%&a#~KDX8u_YgHBafgpO^tQElq#fBBP329w zbX~x8uB}>F(GTU?`}Wl~v(NU`hNdHh(o9)c0&aR31R$AAa` literal 3247 zcmV;g3{dkQiwFo^eOzGx17u-zVJ>QOZ*BnXU0HM6I1+x(uRv*EcBc%5;7vWPvy<8N zgR|MhncAHwWrGALu|kmw4(s+&?I>I+J4rdgKPePgt1ccslnc;WO#sR)WMM)f{ zk@L_Ld*g%=J@+ONPP{PqoklVH#j6@aqz$FK9+R83Wr{XHJ{Vq2AL^`DUa%-@N7SVe z4ICOXp|APdZ)I^&z0#r+`eDRd{L8PW<~vm@N5aa87h~I}Bs%CZn419tj8DK;0B}>iOhDI%98D zRZ^v@C8KRGLUP+iR+x+y_fa}|gXbs)A(1Z~4GRm0J#t8}1aGZ-v~&g&^%DCE{H zk=nI#RwK1AO5WLerq@QAGE^*OtELxLhI5=GGzvy*8Dfj>qBfekom`LlCOB`o1)YBAHD}A! zfwqjmdY|h8Q8kAWvbGAu*rPL;dXSsM_X0XXGD5bh2rQZ}fW-|cy*a1WUX{**`ZfeA z0u`ZuQA}ubk*hTb6X<$AvmhlEG*(pmciv;1;Mu%Y&NU^58>GJ9D9rbTL4*7Tisa#?n=E#)`L%P2L8SoebiGRxT!M zTT6d?g^1^Qo4MB(`1zd8X#=BGCsT!LpTDU&-Mo3>zs?fi-~c#bkYHwwn<-Af z6))xLxdIVQ(kO^Q7=SN0rkXqOBV~cE>rpZeNI2t-@Tw==!Z@>a zJg1J30QTL3u>p^=nU7?X0fY&#(X#G6X9@(9z(Tc<3${R!*<4IuKWtt;SNUZpqMU4D zRgkVIswNqhtXrrp@lKfgy^rI>b81vJg9>v{*Gw_d3IYKKq#;lnjF6#$AjZ3qM{gZJ zC8E^De%vh1R9-L~5J6QpHG*XoDw@MSDXs!dOC}JxY?j1!HBC30hWY-(|4&LYbT`X_ zHZ>>S|KJtQapFvCv`V2NFP{7OPLO-TM@+aE7M40$BKvzzQZaRqdFTbrHC7OftC|bv zG{Q-ih8VSruUp;JBo<4+m2>8+(Zz|pPdJ#+hFW-kO>$2kA#0?`Lx#RTY9k$p^HNP* zZHSlBi)!a}w^GHdAVLb)gnhqOmSgNwc=JiDdK#UPc9G}PB<)4&1tc6Z%R}~)P>s$ zc#o&fCF-8~O+!r&J4BNZE+v)|@WrAtG=0|uyyRL)I}-3m0{%$Azu*Lp1pJYJKMd0x z3HW_N#F2pC0HTis{9c>qNWi~Z+a3w{9+e*n_#**-B;ePudHKAOfH(BE#6c49rY_48 zk}%YfYeUtN2(*zdLz`m9augk#n(`C^{=Rw;T{NX0MaQ>o2wF6Jr%Xw}_Z*7B`V@R) zN;SDn0P~f6ccagM<%`)`H_i#JQHu|RFh>@gNBAIsLC3G7Q!}^b=kEM zMuu!UeXVSei7x`awTbwe$KD|kuN%82;$=z0$D8oaB;wZ$1vkr>ZzcW|4txu=YDSW? zm~+m*AXi3&8H3IP(u=7VgRG*>B0^qRIX<)JiacP^E0dlvkQG6u!-`ovdzA?kGrD3; zzt0X6`~XkE)g%hjImCoqoq(%+i-uw!q~aBu5`}q)c9q4dVqLNR#zDY`!((4UU52!B z79Q__a|8Wn86N(^IgaC-Fd~peoqYf9G*E=(RGV9NWFh|0YTkdRn|1**#RF+oDEWP?@=w_~&`Ng^TgKoqT1 zNUQpyLq&ZYQfHlA0m`sd$CV8Vb;C5FN=ynZ#GVY@G+c?=SaO?b7SYfq041z=K#0m@ zwhF0SC7Z!i?ekWdXM@-VVLlgPQ^HU+H3eD*!qAdb1z8UB$cE8$^J_8BJ*r~ro_Wqo z)6pvj_zaGEjmg(4zYKBBcG|}f*FwCM?jf!P%#2g9)b)`PR-4 z`)2|19Ija)?9al{B%@COXJ=}6!v^$+|8LP%+?pys-TxyG+{&*J)R~L=e1CMpco2Jk zay=qRs=ZD;YBRfjr%~DXpdpYGS7mt@msQnVgV(PIcAIAQ1<}Z}md!wEFcf58Mu^3* z^}U5-dSH2aU?u(8n=Ak;(*?^G{F71#s-hr%=^Y6`CwgfR-a!Cc%^%dT%Qm zOdVVZ7n!g3b@K=Hv%wDY2bQ+`{DFzoWB%ZHk$*of@*lGuuPfVez*o7BNtEM7_|>_Y zLvojgl=9g!On$md(gELSKHvn^-k^9xd9OqAcCR3v_6qjOtzY=Aj=p?eo%}P~5{IAs zql&?P91UWf8ca0KZ?~DuOuq}Q*D3!H%NipA6%u}( zE*_PkX?EX|-t&A6bqvFFB?OTv$xxMC30lOpAtffE$kjF7v7eNWDFeFae-t6MCts?wX#80{{v0<-(YwIp>MV&c0%ay`U?S6rj~j9%RHMU^q+RhecCA45Mn%` z+wG*0tlmLiIX%3iv&L4td59#o+D#*7-D+PCC(y?qr%a?sNLhBAG7!>br0V*52dXE< zMEZrKj5OwOt)XRED`O(l(;!L6ILRm3~2${Qua;8}*G&_=YOSN_BRYAHs!BxPwSBofs{A>M4lm hB=vDr_||QrvpLM&dQw#%>gGD0^#89V>XLAH002`|HD~|; diff --git a/x-pack/test/functional/fixtures/kbn_archiver/security_solution/timelines/7.15.0_space b/x-pack/test/functional/fixtures/kbn_archiver/security_solution/timelines/7.15.0_space new file mode 100644 index 0000000000000..53acfb24cb301 --- /dev/null +++ b/x-pack/test/functional/fixtures/kbn_archiver/security_solution/timelines/7.15.0_space @@ -0,0 +1,20 @@ +{ + "attributes": { + "fieldAttrs": "{}", + "fields": "[]", + "runtimeFieldMap": "{}", + "timeFieldName": "", + "title": ".kibana_7.15.0", + "typeMeta": "{}" + }, + "coreMigrationVersion": "8.6.0", + "id": "cf0a7895-d367-5eff-9d71-8d6b58b0b5d9", + "migrationVersion": { + "index-pattern": "8.0.0" + }, + "originId": "4f57d680-25f3-11ec-a981-b77847c6ef30", + "references": [], + "type": "index-pattern", + "updated_at": "2021-10-05T15:45:48.019Z", + "version": "WzIyLDJd" +} \ No newline at end of file From b78f785b3c25792e1803f7c77512bc38d1a10afa Mon Sep 17 00:00:00 2001 From: Shahzad Date: Fri, 4 Nov 2022 11:44:01 +0100 Subject: [PATCH 09/31] [Synthetics] User experience and monitor details, load when in view (#144385) Co-authored-by: Abdul Zahid --- .../public/components/shared/index.tsx | 11 ++++ .../load_when_in_view/load_when_in_view.tsx | 52 +++++++++++++++++++ x-pack/plugins/observability/public/index.ts | 1 + .../e2e/page_objects/monitor_management.tsx | 4 +- .../monitor_summary/monitor_summary.tsx | 7 ++- .../monitor_summary/test_runs_table.tsx | 2 +- .../ux/e2e/journeys/ux_js_errors.journey.ts | 3 +- .../journeys/ux_long_task_metric_journey.ts | 4 +- .../journeys/ux_visitor_breakdown.journey.ts | 2 + .../app/rum_dashboard/rum_dashboard.tsx | 16 +++++- 10 files changed, 92 insertions(+), 10 deletions(-) create mode 100644 x-pack/plugins/observability/public/components/shared/load_when_in_view/load_when_in_view.tsx diff --git a/x-pack/plugins/observability/public/components/shared/index.tsx b/x-pack/plugins/observability/public/components/shared/index.tsx index c8d6771cc4892..fab875ebaf078 100644 --- a/x-pack/plugins/observability/public/components/shared/index.tsx +++ b/x-pack/plugins/observability/public/components/shared/index.tsx @@ -7,6 +7,7 @@ import React, { lazy, Suspense } from 'react'; import { EuiLoadingSpinner } from '@elastic/eui'; +import { LoadWhenInViewProps } from './load_when_in_view/load_when_in_view'; import type { CoreVitalProps, HeaderMenuPortalProps } from './types'; import type { FieldValueSuggestionsProps, @@ -102,3 +103,13 @@ export function DatePicker(props: DatePickerProps) { ); } + +const LoadWhenInViewLazy = lazy(() => import('./load_when_in_view/load_when_in_view')); + +export function LoadWhenInView(props: LoadWhenInViewProps) { + return ( + }> + + + ); +} diff --git a/x-pack/plugins/observability/public/components/shared/load_when_in_view/load_when_in_view.tsx b/x-pack/plugins/observability/public/components/shared/load_when_in_view/load_when_in_view.tsx new file mode 100644 index 0000000000000..16cb8c35b34a6 --- /dev/null +++ b/x-pack/plugins/observability/public/components/shared/load_when_in_view/load_when_in_view.tsx @@ -0,0 +1,52 @@ +/* + * 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, { useEffect, useState } from 'react'; +import { EuiLoadingContent } from '@elastic/eui'; +import useIntersection from 'react-use/lib/useIntersection'; + +export interface LoadWhenInViewProps { + children: JSX.Element; + initialHeight?: string | number; + placeholderTitle: string; +} + +// eslint-disable-next-line import/no-default-export +export default function LoadWhenInView({ + children, + placeholderTitle, + initialHeight = 100, +}: LoadWhenInViewProps) { + const intersectionRef = React.useRef(null); + const intersection = useIntersection(intersectionRef, { + root: null, + rootMargin: '0px', + threshold: 0.25, + }); + + const [isVisible, setIsVisible] = useState(false); + + useEffect(() => { + if (intersection && intersection.intersectionRatio > 0.25) { + setIsVisible(true); + } + }, [intersection, intersection?.intersectionRatio]); + + return isVisible ? ( + children + ) : ( +

+ +
+ ); +} diff --git a/x-pack/plugins/observability/public/index.ts b/x-pack/plugins/observability/public/index.ts index 8c083012448e6..dcd7a1cd08c93 100644 --- a/x-pack/plugins/observability/public/index.ts +++ b/x-pack/plugins/observability/public/index.ts @@ -55,6 +55,7 @@ export { SelectableUrlList, ExploratoryView, DatePicker, + LoadWhenInView, } from './components/shared'; export type { LazyObservabilityPageTemplateProps } from './components/shared'; diff --git a/x-pack/plugins/synthetics/e2e/page_objects/monitor_management.tsx b/x-pack/plugins/synthetics/e2e/page_objects/monitor_management.tsx index 0046326bad612..3791aa8068176 100644 --- a/x-pack/plugins/synthetics/e2e/page_objects/monitor_management.tsx +++ b/x-pack/plugins/synthetics/e2e/page_objects/monitor_management.tsx @@ -5,7 +5,7 @@ * 2.0. */ import { expect, Page } from '@elastic/synthetics'; -import { getQuerystring } from '@kbn/observability-plugin/e2e/utils'; +import { getQuerystring, TIMEOUT_60_SEC } from '@kbn/observability-plugin/e2e/utils'; import { DataStream } from '../../common/runtime_types/monitor_management'; import { loginPageProvider } from './login'; import { utilsPageProvider } from './utils'; @@ -162,7 +162,7 @@ export function monitorManagementPageProvider({ async selectLocations({ locations }: { locations: string[] }) { for (let i = 0; i < locations.length; i++) { - await page.check(`text=${locations[i]}`); + await page.check(`text=${locations[i]}`, TIMEOUT_60_SEC); } }, diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/monitor_summary.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/monitor_summary.tsx index 11ff2313c706f..03ccc403d0b30 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/monitor_summary.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/monitor_summary.tsx @@ -16,6 +16,7 @@ import { EuiLoadingSpinner, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { LoadWhenInView } from '@kbn/observability-plugin/public'; import { useEarliestStartDate } from '../hooks/use_earliest_start_data'; import { MonitorErrorSparklines } from './monitor_error_sparklines'; @@ -27,7 +28,7 @@ import { DurationPanel } from './duration_panel'; import { MonitorDetailsPanel } from './monitor_details_panel'; import { AvailabilitySparklines } from './availability_sparklines'; import { LastTestRun } from './last_test_run'; -import { TestRunsTable } from './test_runs_table'; +import { LAST_10_TEST_RUNS, TestRunsTable } from './test_runs_table'; import { MonitorErrorsCount } from './monitor_errors_count'; export const MonitorSummary = () => { @@ -121,7 +122,9 @@ export const MonitorSummary = () => { - + + + ); }; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/test_runs_table.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/test_runs_table.tsx index d9b1beb45088a..f49d116f48798 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/test_runs_table.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/test_runs_table.tsx @@ -230,7 +230,7 @@ const TEST_RUNS = i18n.translate('xpack.synthetics.monitorDetails.summary.testRu defaultMessage: 'Test Runs', }); -const LAST_10_TEST_RUNS = i18n.translate( +export const LAST_10_TEST_RUNS = i18n.translate( 'xpack.synthetics.monitorDetails.summary.lastTenTestRuns', { defaultMessage: 'Last 10 Test Runs', diff --git a/x-pack/plugins/ux/e2e/journeys/ux_js_errors.journey.ts b/x-pack/plugins/ux/e2e/journeys/ux_js_errors.journey.ts index 8e124d8a5e4b7..e29807a3edd5d 100644 --- a/x-pack/plugins/ux/e2e/journeys/ux_js_errors.journey.ts +++ b/x-pack/plugins/ux/e2e/journeys/ux_js_errors.journey.ts @@ -45,7 +45,8 @@ journey('UX JsErrors', async ({ page, params }) => { step('Confirm error count', async () => { // Wait until chart data is loaded - page.waitForLoadState('networkidle'); + await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight)); + await page.waitForLoadState('networkidle'); await page.waitForSelector(`text=${jsErrorCount}`); const jsErrors = await ( diff --git a/x-pack/plugins/ux/e2e/journeys/ux_long_task_metric_journey.ts b/x-pack/plugins/ux/e2e/journeys/ux_long_task_metric_journey.ts index ba4cb014379e1..803a18e379e5e 100644 --- a/x-pack/plugins/ux/e2e/journeys/ux_long_task_metric_journey.ts +++ b/x-pack/plugins/ux/e2e/journeys/ux_long_task_metric_journey.ts @@ -54,9 +54,9 @@ journey('UX LongTaskMetrics', async ({ page, params }) => { step('Confirm metrics values', async () => { // Wait until chart data is loaded - page.waitForLoadState('networkidle'); + await page.waitForLoadState('networkidle'); // wait for first metric to be shown - page.waitForSelector(`text="237 ms"`); + await page.waitForSelector(`text="237 ms"`); let metric = await ( await page.waitForSelector(byTestId(longestMetric)) diff --git a/x-pack/plugins/ux/e2e/journeys/ux_visitor_breakdown.journey.ts b/x-pack/plugins/ux/e2e/journeys/ux_visitor_breakdown.journey.ts index 88e0b90120ec7..be655789b2596 100644 --- a/x-pack/plugins/ux/e2e/journeys/ux_visitor_breakdown.journey.ts +++ b/x-pack/plugins/ux/e2e/journeys/ux_visitor_breakdown.journey.ts @@ -45,7 +45,9 @@ journey('UX Visitor Breakdown', async ({ page, params }) => { step('Confirm charts are visible', async () => { // Wait until chart data is loaded + await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight)); await page.waitForLoadState('networkidle'); + await waitForLoadingToFinish({ page }); await Promise.all( chartIds.map( diff --git a/x-pack/plugins/ux/public/components/app/rum_dashboard/rum_dashboard.tsx b/x-pack/plugins/ux/public/components/app/rum_dashboard/rum_dashboard.tsx index d6b454bd948f7..a05915dc816b6 100644 --- a/x-pack/plugins/ux/public/components/app/rum_dashboard/rum_dashboard.tsx +++ b/x-pack/plugins/ux/public/components/app/rum_dashboard/rum_dashboard.tsx @@ -7,6 +7,8 @@ import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import React from 'react'; +import { LoadWhenInView } from '@kbn/observability-plugin/public'; +import { I18LABELS } from './translations'; import { UXMetrics } from './ux_metrics'; import { ImpactfulMetrics } from './impactful_metrics'; import { PageLoadAndViews } from './panels/page_load_and_views'; @@ -29,10 +31,20 @@ export function RumDashboard() { - + + + - + + + ); From 92251b2567965d795940bfe2c7e30a2d6218efb9 Mon Sep 17 00:00:00 2001 From: Michael Dokolin Date: Fri, 4 Nov 2022 13:20:46 +0100 Subject: [PATCH 10/31] [Expressions] Add a flag to opt out of the partial results in the expressions (#144241) * Add a flag to opt out of the partial results in the expressions * Align the partial results flag with the expression loader * Move the partial results throttling to the execution service --- .../public/app/app.tsx | 2 +- .../common/execution/execution.test.ts | 121 +++++++++- .../expressions/common/execution/execution.ts | 223 +++++++++++------- .../execution/execution_contract.test.ts | 2 +- .../common/service/expressions_services.ts | 12 + src/plugins/expressions/public/loader.ts | 68 +----- 6 files changed, 275 insertions(+), 153 deletions(-) diff --git a/examples/partial_results_example/public/app/app.tsx b/examples/partial_results_example/public/app/app.tsx index 8988b631a8e94..5f72fb356195a 100644 --- a/examples/partial_results_example/public/app/app.tsx +++ b/examples/partial_results_example/public/app/app.tsx @@ -37,7 +37,7 @@ export function App() { useEffect(() => { const subscription = expressions - ?.execute(expression, null) + ?.execute(expression, null, { partial: true }) .getData() .pipe(pluck('result')) .subscribe((value) => setDatatable(value as Datatable)); diff --git a/src/plugins/expressions/common/execution/execution.test.ts b/src/plugins/expressions/common/execution/execution.test.ts index 3575552401914..b3c3cf8ec92f0 100644 --- a/src/plugins/expressions/common/execution/execution.test.ts +++ b/src/plugins/expressions/common/execution/execution.test.ts @@ -404,7 +404,7 @@ describe('Execution', () => { jest.useRealTimers(); }); - test('handles functions returning observables', () => { + test('handles partial results when functions return observables', () => { testScheduler.run(({ cold, expectObservable }) => { const arg = cold(' -a-b-c|', { a: 1, b: 2, c: 3 }); const expected = ' -a-b-c|'; @@ -417,7 +417,7 @@ describe('Execution', () => { const executor = createUnitTestExecutor(); executor.registerFunction(observable); - const result = executor.run('observable', null, {}); + const result = executor.run('observable', null, { partial: true }); expectObservable(result).toBe(expected, { a: { result: 1, partial: true }, @@ -426,6 +426,68 @@ describe('Execution', () => { }); }); }); + + test('ignores partial results by default', () => { + testScheduler.run(({ cold, expectObservable, flush }) => { + const a = 1; + const b = 2; + const c = 3; + const arg = cold(' -a-b-c|', { a, b, c }); + const expected = ' ------(c|)'; + const spyFn = jest.fn((value) => value); + const executor = createUnitTestExecutor(); + executor.registerFunction({ + name: 'observable', + args: {}, + help: '', + fn: () => arg, + }); + executor.registerFunction({ + name: 'spy', + args: {}, + help: '', + fn: (input) => spyFn(input), + }); + + const result = executor.run('observable | spy', null); + + expectObservable(result).toBe(expected, { + c: { result: c, partial: false }, + }); + + flush(); + + expect(spyFn).toHaveBeenCalledTimes(1); + expect(spyFn).toHaveBeenCalledWith(c); + }); + }); + + it('throttles partial results', async () => { + testScheduler.run(({ cold, expectObservable }) => { + const a = 1; + const b = 2; + const c = 3; + const d = 4; + const observable = cold('a 5ms b 5ms c 10ms (d|)', { a, b, c, d }); + const expected = ' a 19ms c 2ms (d|)'; + + const executor = createUnitTestExecutor(); + executor.registerFunction({ + name: 'observable', + args: {}, + help: '', + fn: () => observable, + }); + + const result = executor.run('observable', null, { partial: true, throttle: 20 }); + + expectObservable(result).toBe(expected, { + a: expect.objectContaining({ result: a }), + c: expect.objectContaining({ result: c }), + d: expect.objectContaining({ result: d }), + }); + }); + }); }); describe('when function throws', () => { @@ -525,7 +587,7 @@ describe('Execution', () => { fn: (value) => spyFn(value), }); - const result = executor.run('observable | flaky | spy', null, {}); + const result = executor.run('observable | flaky | spy', null, { partial: true }); expectObservable(result).toBe('abc|', { a: { partial: true, result: a }, @@ -659,7 +721,7 @@ describe('Execution', () => { const executor = createUnitTestExecutor(); executor.registerFunction(observable); - const result = executor.run('add val={observable}', 1, {}); + const result = executor.run('add val={observable}', 1, { partial: true }); expectObservable(result).toBe(expected, { a: { partial: true, result: { type: 'num', value: 2 } }, @@ -705,7 +767,11 @@ describe('Execution', () => { executor.registerFunction(observable2); executor.registerFunction(max); - const result = executor.run('max val1={observable1} val2={observable2}', {}); + const result = executor.run( + 'max val1={observable1} val2={observable2}', + {}, + { partial: true } + ); expectObservable(result).toBe(expected, { a: { partial: true, result: { type: 'num', value: 1 } }, @@ -730,7 +796,7 @@ describe('Execution', () => { const executor = createUnitTestExecutor(); executor.registerFunction(observable); - const result = executor.run('add val={observable}', 1, {}); + const result = executor.run('add val={observable}', 1, { partial: true }); expectObservable(result).toBe(expected, { a: expect.objectContaining({ result: { type: 'num', value: 2 } }), @@ -788,7 +854,7 @@ describe('Execution', () => { fn: (input, args) => spyFn(input, args), }); - const result = executor.run('spy arg={observable | flaky}', null, {}); + const result = executor.run('spy arg={observable | flaky}', null, { partial: true }); expectObservable(result).toBe('abcd|', { a: { partial: true, result: a }, @@ -818,6 +884,47 @@ describe('Execution', () => { expect(spyFn).toHaveBeenNthCalledWith(2, null, { arg: d }); }); }); + + test('supports opting out of partial results in sub-expression', async () => { + testScheduler.run(({ cold, expectObservable, flush }) => { + const a = 1; + const b = 2; + const c = 3; + const observable$ = cold('abc|', { a, b, c }); + const expected = ' ---(c|)'; + const spyFn = jest.fn((input, { arg }) => arg); + + const executor = createUnitTestExecutor(); + executor.registerFunction({ + name: 'observable', + args: {}, + help: '', + fn: () => observable$, + }); + executor.registerFunction({ + name: 'spy', + args: { + arg: { + help: '', + types: ['number'], + }, + }, + help: '', + fn: (input, args) => spyFn(input, args), + }); + + const result = executor.run('spy arg={observable}', null); + + expectObservable(result).toBe(expected, { + c: { partial: false, result: c }, + }); + + flush(); + + expect(spyFn).toHaveBeenCalledTimes(1); + expect(spyFn).toHaveBeenCalledWith(null, { arg: c }); + }); + }); }); describe('when arguments are missing', () => { diff --git a/src/plugins/expressions/common/execution/execution.ts b/src/plugins/expressions/common/execution/execution.ts index 8edf6d3227c02..d8932f234e39a 100644 --- a/src/plugins/expressions/common/execution/execution.ts +++ b/src/plugins/expressions/common/execution/execution.ts @@ -10,16 +10,21 @@ import { i18n } from '@kbn/i18n'; import type { Logger } from '@kbn/logging'; import { isPromise } from '@kbn/std'; import { ObservableLike, UnwrapObservable } from '@kbn/utility-types'; -import { keys, last, mapValues, reduce, zipObject } from 'lodash'; +import { keys, last as lastOf, mapValues, reduce, zipObject } from 'lodash'; import { combineLatest, defer, from, + identity, isObservable, + last, of, + takeWhile, throwError, + timer, Observable, ReplaySubject, + Subscription, } from 'rxjs'; import { catchError, finalize, map, pluck, shareReplay, switchMap, tap } from 'rxjs/operators'; import { now, AbortError } from '@kbn/kibana-utils-plugin/common'; @@ -99,6 +104,61 @@ function markPartial() { }); } +/** + * RxJS' `throttle` operator does not emit the last value immediately when the source observable is completed. + * Instead, it waits for the next throttle period to emit that. + * It might cause delays until we get the final value, even though it is already there. + * @see https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/throttle.ts#L121 + */ +function throttle(timeout: number) { + return (source: Observable): Observable => + new Observable((subscriber) => { + let latest: T | undefined; + let hasValue = false; + + const emit = () => { + if (hasValue) { + subscriber.next(latest); + hasValue = false; + latest = undefined; + } + }; + + let throttled: Subscription | undefined; + const timer$ = timer(0, timeout).pipe( + takeWhile(() => hasValue), + finalize(() => { + subscriber.remove(throttled!); + throttled = undefined; + }) + ); + + subscriber.add( + source.subscribe({ + next: (value) => { + latest = value; + hasValue = true; + + if (!throttled) { + throttled = timer$.subscribe(emit); + subscriber.add(throttled); + } + }, + error: (error) => subscriber.error(error), + complete: () => { + emit(); + subscriber.complete(); + }, + }) + ); + + subscriber.add(() => { + hasValue = false; + latest = undefined; + }); + }); +} + function takeUntilAborted(signal: AbortSignal) { return (source: Observable) => new Observable((subscriber) => { @@ -235,7 +295,10 @@ export class Execution< switchMap((input) => this.invokeChain(this.state.get().ast.chain, input).pipe( takeUntilAborted(this.abortController.signal), - markPartial() + markPartial(), + this.execution.params.partial && this.execution.params.throttle + ? throttle(this.execution.params.throttle) + : identity ) ), catchError((error) => { @@ -303,89 +366,85 @@ export class Execution< return of(input as ChainOutput); } - return of(input).pipe( - switchMap((currentInput) => { - const { function: fnName, arguments: fnArgs } = head; - const fn = getByAlias(this.state.get().functions, fnName, this.execution.params.namespace); - - if (!fn) { - throw createError({ - name: 'fn not found', - message: i18n.translate('expressions.execution.functionNotFound', { - defaultMessage: `Function {fnName} could not be found.`, - values: { - fnName, - }, - }), - }); - } + return defer(() => { + const { function: fnName, arguments: fnArgs } = head; + const fn = getByAlias(this.state.get().functions, fnName, this.execution.params.namespace); - if (fn.disabled) { - throw createError({ - name: 'fn is disabled', - message: i18n.translate('expressions.execution.functionDisabled', { - defaultMessage: `Function {fnName} is disabled.`, - values: { - fnName, - }, - }), - }); - } + if (!fn) { + throw createError({ + name: 'fn not found', + message: i18n.translate('expressions.execution.functionNotFound', { + defaultMessage: `Function {fnName} could not be found.`, + values: { + fnName, + }, + }), + }); + } - if (fn.deprecated) { - this.logger?.warn(`Function '${fnName}' is deprecated`); - } + if (fn.disabled) { + throw createError({ + name: 'fn is disabled', + message: i18n.translate('expressions.execution.functionDisabled', { + defaultMessage: `Function {fnName} is disabled.`, + values: { + fnName, + }, + }), + }); + } - if (this.execution.params.debug) { - head.debug = { - args: {}, - duration: 0, - fn: fn.name, - input: currentInput, - success: true, - }; - } + if (fn.deprecated) { + this.logger?.warn(`Function '${fnName}' is deprecated`); + } - const timeStart = this.execution.params.debug ? now() : 0; - - // `resolveArgs` returns an object because the arguments themselves might - // actually have `then` or `subscribe` methods which would be treated as a `Promise` - // or an `Observable` accordingly. - return this.resolveArgs(fn, currentInput, fnArgs).pipe( - switchMap((resolvedArgs) => { - const args$ = isExpressionValueError(resolvedArgs) - ? throwError(resolvedArgs.error) - : of(resolvedArgs); - - return args$.pipe( - tap((args) => this.execution.params.debug && Object.assign(head.debug, { args })), - switchMap((args) => this.invokeFunction(fn, currentInput, args)), - switchMap((output) => - getType(output) === 'error' ? throwError(output) : of(output) - ), - tap((output) => this.execution.params.debug && Object.assign(head.debug, { output })), - switchMap((output) => this.invokeChain(tail, output)), - catchError((rawError) => { - const error = createError(rawError); - error.error.message = `[${fnName}] > ${error.error.message}`; - - if (this.execution.params.debug) { - Object.assign(head.debug, { error, rawError, success: false }); - } - - return of(error); - }) - ); - }), - finalize(() => { - if (this.execution.params.debug) { - Object.assign(head.debug, { duration: now() - timeStart }); - } - }) - ); - }), - catchError((error) => of(error)) - ); + if (this.execution.params.debug) { + head.debug = { + input, + args: {}, + duration: 0, + fn: fn.name, + success: true, + }; + } + + const timeStart = this.execution.params.debug ? now() : 0; + + // `resolveArgs` returns an object because the arguments themselves might + // actually have `then` or `subscribe` methods which would be treated as a `Promise` + // or an `Observable` accordingly. + return this.resolveArgs(fn, input, fnArgs).pipe( + switchMap((resolvedArgs) => { + const args$ = isExpressionValueError(resolvedArgs) + ? throwError(resolvedArgs.error) + : of(resolvedArgs); + + return args$.pipe( + tap((args) => this.execution.params.debug && Object.assign(head.debug, { args })), + switchMap((args) => this.invokeFunction(fn, input, args)), + this.execution.params.partial ? identity : last(), + switchMap((output) => (getType(output) === 'error' ? throwError(output) : of(output))), + tap((output) => this.execution.params.debug && Object.assign(head.debug, { output })), + switchMap((output) => this.invokeChain(tail, output)), + catchError((rawError) => { + const error = createError(rawError); + error.error.message = `[${fnName}] > ${error.error.message}`; + + if (this.execution.params.debug) { + Object.assign(head.debug, { error, rawError, success: false }); + } + + return of(error); + }) + ); + }), + finalize(() => { + if (this.execution.params.debug) { + Object.assign(head.debug, { duration: now() - timeStart }); + } + }) + ); + }).pipe(catchError((error) => of(error))); } invokeFunction( @@ -581,7 +640,7 @@ export class Execution< // function which would be treated as a promise zipObject(argNames, values as unknown[][]), // Just return the last unless the argument definition allows multiple - (argValues, argName) => (argDefs[argName].multi ? argValues : last(argValues)) + (argValues, argName) => (argDefs[argName].multi ? argValues : lastOf(argValues)) ) ) ); diff --git a/src/plugins/expressions/common/execution/execution_contract.test.ts b/src/plugins/expressions/common/execution/execution_contract.test.ts index 6b0fa0d0db592..6934720d2d70c 100644 --- a/src/plugins/expressions/common/execution/execution_contract.test.ts +++ b/src/plugins/expressions/common/execution/execution_contract.test.ts @@ -141,7 +141,7 @@ describe('ExecutionContract', () => { const executor = createUnitTestExecutor(); executor.registerFunction(observable); - const execution = executor.createExecution('observable'); + const execution = executor.createExecution('observable', { partial: true }); execution.start(null); await execution.result.pipe(first()).toPromise(); diff --git a/src/plugins/expressions/common/service/expressions_services.ts b/src/plugins/expressions/common/service/expressions_services.ts index 097b0823a98f0..0480e4966c01f 100644 --- a/src/plugins/expressions/common/service/expressions_services.ts +++ b/src/plugins/expressions/common/service/expressions_services.ts @@ -161,6 +161,18 @@ export interface ExpressionExecutionParams { executionContext?: KibanaExecutionContext; namespace?: string; + + /** + * Toggles the partial results support. + * @default false + */ + partial?: boolean; + + /** + * Throttling of partial results in milliseconds. 0 is disabling the throttling. + * @deafult 0 + */ + throttle?: number; } /** diff --git a/src/plugins/expressions/public/loader.ts b/src/plugins/expressions/public/loader.ts index 5b1ae822e1a2c..e2b9d8ab22fb7 100644 --- a/src/plugins/expressions/public/loader.ts +++ b/src/plugins/expressions/public/loader.ts @@ -6,8 +6,8 @@ * Side Public License, v 1. */ -import { BehaviorSubject, Observable, Subject, Subscription, identity, timer } from 'rxjs'; -import { delay, filter, finalize, map, shareReplay, takeWhile } from 'rxjs/operators'; +import { BehaviorSubject, Observable, Subject, Subscription } from 'rxjs'; +import { delay, filter, map, shareReplay } from 'rxjs/operators'; import { defaults } from 'lodash'; import { SerializableRecord, UnwrapObservable } from '@kbn/utility-types'; import { Adapters } from '@kbn/inspector-plugin/public'; @@ -20,61 +20,6 @@ import { getExpressionsService } from './services'; type Data = unknown; -/** - * RxJS' `throttle` operator does not emit the last value immediately when the source observable is completed. - * Instead, it waits for the next throttle period to emit that. - * It might cause delays until we get the final value, even though it is already there. - * @see https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/throttle.ts#L121 - */ -function throttle(timeout: number) { - return (source: Observable): Observable => - new Observable((subscriber) => { - let latest: T | undefined; - let hasValue = false; - - const emit = () => { - if (hasValue) { - subscriber.next(latest); - hasValue = false; - latest = undefined; - } - }; - - let throttled: Subscription | undefined; - const timer$ = timer(0, timeout).pipe( - takeWhile(() => hasValue), - finalize(() => { - subscriber.remove(throttled!); - throttled = undefined; - }) - ); - - subscriber.add( - source.subscribe({ - next: (value) => { - latest = value; - hasValue = true; - - if (!throttled) { - throttled = timer$.subscribe(emit); - subscriber.add(throttled); - } - }, - error: (error) => subscriber.error(error), - complete: () => { - emit(); - subscriber.complete(); - }, - }) - ); - - subscriber.add(() => { - hasValue = false; - latest = undefined; - }); - }); -} - export class ExpressionLoader { data$: ReturnType; update$: ExpressionRenderHandler['update$']; @@ -203,14 +148,13 @@ export class ExpressionLoader { syncCursor: params?.syncCursor, syncTooltips: params.syncTooltips, executionContext: params.executionContext, + partial: params.partial, + throttle: params.throttle, }); this.subscription = this.execution .getData() - .pipe( - delay(0), // delaying until the next tick since we execute the expression in the constructor - filter(({ partial }) => params.partial || !partial), - params.partial && params.throttle ? throttle(params.throttle) : identity - ) + // delaying until the next tick since we execute the expression in the constructor + .pipe(delay(0)) .subscribe((value) => this.dataSubject.next(value)); }; From d2c5ce8274fd6fa0e42e95d52584b4e80a45beb3 Mon Sep 17 00:00:00 2001 From: Wafaa Nasr Date: Fri, 4 Nov 2022 13:24:44 +0100 Subject: [PATCH 11/31] [Security Solution][Exceptions] Complete List-Header's use-cases (#144383) * kbn add more tests + enable user to export even when readonly is true * fix test * fix onblur one another field removes required of another * add tests * fix test Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../__snapshots__/comments.test.tsx.snap | 61 + .../comments/comments.test.tsx | 9 + .../exception_item_card/comments/index.tsx | 1 + .../exception_item_card/meta/meta.test.tsx | 4 +- .../__snapshots__/header_menu.test.tsx.snap | 196 +++ .../src/header_menu/header_menu.test.tsx | 12 +- .../src/header_menu/index.tsx | 2 + .../__snapshots__/list_header.test.tsx.snap | 1225 +++++++++++------ .../__snapshots__/edit_modal.test.tsx.snap | 33 +- .../edit_modal/edit_modal.test.tsx | 90 +- .../src/list_header/edit_modal/index.tsx | 42 +- .../edit_modal/use_edit_modal.test.ts | 43 + .../list_header/edit_modal/use_edit_modal.ts | 54 + .../src/list_header/index.tsx | 15 +- .../src/list_header/list_header.styles.ts | 14 +- .../src/list_header/list_header.test.tsx | 29 +- .../__snapshots__/menu_items.test.tsx.snap | 790 +++++++++++ .../src/list_header/menu_items/index.tsx | 35 +- .../menu_items/menu_items.test.tsx | 47 + .../src/list_header/use_list_header.ts | 4 +- .../src/mocks/header.mock.ts | 15 + .../src/mocks/rule_references.mock.ts | 2 +- .../mocks/security_link_component.mock.tsx | 2 +- .../text_with_edit.test.tsx.snap | 100 +- .../src/text_with_edit/index.tsx | 35 +- .../text_with_edit/text_with_edit.styles.ts | 25 + .../src/translations.ts | 7 + .../src/types/index.ts | 2 +- 28 files changed, 2378 insertions(+), 516 deletions(-) create mode 100644 packages/kbn-securitysolution-exception-list-components/src/list_header/edit_modal/use_edit_modal.test.ts create mode 100644 packages/kbn-securitysolution-exception-list-components/src/list_header/edit_modal/use_edit_modal.ts create mode 100644 packages/kbn-securitysolution-exception-list-components/src/text_with_edit/text_with_edit.styles.ts diff --git a/packages/kbn-securitysolution-exception-list-components/src/exception_item_card/comments/__snapshots__/comments.test.tsx.snap b/packages/kbn-securitysolution-exception-list-components/src/exception_item_card/comments/__snapshots__/comments.test.tsx.snap index 5c0dba4573e06..27df7b34bf313 100644 --- a/packages/kbn-securitysolution-exception-list-components/src/exception_item_card/comments/__snapshots__/comments.test.tsx.snap +++ b/packages/kbn-securitysolution-exception-list-components/src/exception_item_card/comments/__snapshots__/comments.test.tsx.snap @@ -1,5 +1,66 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`ExceptionItemCardComments should not render comments when the length is falsy 1`] = ` +Object { + "asFragment": [Function], + "baseElement": +
+ , + "container":
, + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; + exports[`ExceptionItemCardComments should render comments panel closed 1`] = ` Object { "asFragment": [Function], diff --git a/packages/kbn-securitysolution-exception-list-components/src/exception_item_card/comments/comments.test.tsx b/packages/kbn-securitysolution-exception-list-components/src/exception_item_card/comments/comments.test.tsx index 64b2d1c9e3a83..9f81c19349f93 100644 --- a/packages/kbn-securitysolution-exception-list-components/src/exception_item_card/comments/comments.test.tsx +++ b/packages/kbn-securitysolution-exception-list-components/src/exception_item_card/comments/comments.test.tsx @@ -13,6 +13,15 @@ import * as i18n from '../translations'; const comments = mockGetFormattedComments(); describe('ExceptionItemCardComments', () => { + it('should not render comments when the length is falsy', () => { + const wrapper = render( + + ); + expect(wrapper).toMatchSnapshot(); + + expect(wrapper.queryByTestId('ExceptionItemCardCommentsContainer')).not.toBeInTheDocument(); + }); + it('should render comments panel closed', () => { const wrapper = render( ( ({ comments, dataTestSubj }) => { + if (!comments.length) return null; return ( { item={getExceptionListItemSchemaMock()} rules={[ { - exception_lists: [ + exception_list: [ { id: '123', list_id: 'i_exist', @@ -98,7 +98,7 @@ describe('ExceptionItemCardMetaInfo', () => { rule_id: 'rule-2', }, { - exception_lists: [ + exception_list: [ { id: '123', list_id: 'i_exist', diff --git a/packages/kbn-securitysolution-exception-list-components/src/header_menu/__snapshots__/header_menu.test.tsx.snap b/packages/kbn-securitysolution-exception-list-components/src/header_menu/__snapshots__/header_menu.test.tsx.snap index dd808cfd1889c..2e8afcea7cc3e 100644 --- a/packages/kbn-securitysolution-exception-list-components/src/header_menu/__snapshots__/header_menu.test.tsx.snap +++ b/packages/kbn-securitysolution-exception-list-components/src/header_menu/__snapshots__/header_menu.test.tsx.snap @@ -1,5 +1,201 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`HeaderMenu should render button icon disabled 1`] = ` +Object { + "asFragment": [Function], + "baseElement": +
+
+
+
+ +
+
+
+
+
+
+ +
+ , + "container":
+
+
+
+ +
+
+
+
, + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; + exports[`HeaderMenu should render button icon with default settings 1`] = ` Object { "asFragment": [Function], diff --git a/packages/kbn-securitysolution-exception-list-components/src/header_menu/header_menu.test.tsx b/packages/kbn-securitysolution-exception-list-components/src/header_menu/header_menu.test.tsx index b07079c721ff7..8b5775264e230 100644 --- a/packages/kbn-securitysolution-exception-list-components/src/header_menu/header_menu.test.tsx +++ b/packages/kbn-securitysolution-exception-list-components/src/header_menu/header_menu.test.tsx @@ -8,7 +8,7 @@ import { fireEvent, render } from '@testing-library/react'; import React from 'react'; import { HeaderMenu } from '.'; -import { actions } from '../mocks/header.mock'; +import { actions, actionsWithDisabledDelete } from '../mocks/header.mock'; import { getSecurityLinkAction } from '../mocks/security_link_component.mock'; describe('HeaderMenu', () => { @@ -21,6 +21,16 @@ describe('HeaderMenu', () => { expect(wrapper.queryByTestId('EmptyButton')).not.toBeInTheDocument(); expect(wrapper.queryByTestId('MenuPanel')).not.toBeInTheDocument(); }); + it('should render button icon disabled', () => { + const wrapper = render( + + ); + + fireEvent.click(wrapper.getByTestId('ButtonIcon')); + expect(wrapper).toMatchSnapshot(); + expect(wrapper.getByTestId('ActionItemdelete')).toBeDisabled(); + expect(wrapper.getByTestId('ActionItemedit')).toBeEnabled(); + }); it('should render empty button icon with different icon settings', () => { const wrapper = render( diff --git a/packages/kbn-securitysolution-exception-list-components/src/header_menu/index.tsx b/packages/kbn-securitysolution-exception-list-components/src/header_menu/index.tsx index 43154a865a436..ba6f3c7beff5d 100644 --- a/packages/kbn-securitysolution-exception-list-components/src/header_menu/index.tsx +++ b/packages/kbn-securitysolution-exception-list-components/src/header_menu/index.tsx @@ -24,6 +24,7 @@ interface Action { key: string; icon: string; label: string | boolean; + disabled?: boolean; onClick: () => void; } interface HeaderMenuComponentProps { @@ -63,6 +64,7 @@ const HeaderMenuComponent: FC = ({ data-test-subj={`${dataTestSubj || ''}ActionItem${action.key}`} key={action.key} icon={action.icon} + disabled={action.disabled} layoutAlign="center" onClick={() => { onClosePopover(); diff --git a/packages/kbn-securitysolution-exception-list-components/src/list_header/__snapshots__/list_header.test.tsx.snap b/packages/kbn-securitysolution-exception-list-components/src/list_header/__snapshots__/list_header.test.tsx.snap index 98f026e4ce947..c3146235b9ab3 100644 --- a/packages/kbn-securitysolution-exception-list-components/src/list_header/__snapshots__/list_header.test.tsx.snap +++ b/packages/kbn-securitysolution-exception-list-components/src/list_header/__snapshots__/list_header.test.tsx.snap @@ -58,26 +58,34 @@ Object { class="euiTitle emotion-euiTitle-l" >
- - List Name - - + data-test-subj="TitleText" + > + List Name + +
+
+ +
- - List description - - + css="You have tried to stringify object returned from \`css\` function. It isn't supposed to be used directly (e.g. as value of the \`className\` prop), but rather handed to emotion so it can handle it (e.g. as value of \`css\` prop)." + data-test-subj="DescriptionText" + > + List description + +
+
+ +
-
-
-
- -
-
-
+ Linked to 0 rules +
+
+ +
+
+ , + "container":
+
+
+
+ +
+
+
+

+
+
+ + List Name + +
+
+ +
+
+

+
+
+

+

+
+
+ + Add a description + +
+
+ +
+
+
+
+ List ID + : +
+
+ List_Id +
+
+
+

+
+
+
+
+
+
+
+ + Linked to 0 rules + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
, + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; + +exports[`ExceptionListHeader should render the List Header with name, default description and disabled actions because of the ReadOnly mode 1`] = ` +Object { + "asFragment": [Function], + "baseElement": +
+
+
+
+ +
+
+
+

+
+
+ + List Name + +
+

- - Add a description - - + css="You have tried to stringify object returned from \`css\` function. It isn't supposed to be used directly (e.g. as value of the \`className\` prop), but rather handed to emotion so it can handle it (e.g. as value of \`css\` prop)." + data-test-subj="DescriptionText" + > + Add a description + +
+
-
-
-
- -
-
-
+ Linked to 0 rules +
+ data-test-subj="TitleText" + > + List Name + +
+
- - Add a description - - + css="You have tried to stringify object returned from \`css\` function. It isn't supposed to be used directly (e.g. as value of the \`className\` prop), but rather handed to emotion so it can handle it (e.g. as value of \`css\` prop)." + data-test-subj="DescriptionText" + > + Add a description + +
+
-
-
-
- -
-
-
+ Linked to 0 rules +
-
-
-
+ Linked to 0 rules +
+
+
+ +
, "container":
- - List Name - + + List Name + +
+
- - Add a description - + + Add a description + +
+
-
-
-
- -
-
-
+ Linked to 0 rules +
+
+
+
+
+
+ +
+
+
+
+
+
+ , + "container":
+
+
+ + Linked to 0 rules + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+
, + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; + +exports[`MenuItems should render all menu actions enabled 1`] = ` +Object { + "asFragment": [Function], + "baseElement": +
+
+
+ + Linked to 0 rules + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+
+ +
+ , + "container":
+
+
+ + Linked to 0 rules + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+
, + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; + +exports[`MenuItems should render delete action disabled 1`] = ` +Object { + "asFragment": [Function], + "baseElement": +
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+
+ +
+ , + "container":
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+
, + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; + exports[`MenuItems should render linkedRules, manageRules and menuActions 1`] = ` Object { "asFragment": [Function], diff --git a/packages/kbn-securitysolution-exception-list-components/src/list_header/menu_items/index.tsx b/packages/kbn-securitysolution-exception-list-components/src/list_header/menu_items/index.tsx index 1e13a8ac3d0f2..bd043af4b1550 100644 --- a/packages/kbn-securitysolution-exception-list-components/src/list_header/menu_items/index.tsx +++ b/packages/kbn-securitysolution-exception-list-components/src/list_header/menu_items/index.tsx @@ -5,10 +5,10 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import { EuiButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiTextColor } from '@elastic/eui'; import React, { FC, useMemo } from 'react'; import { HeaderMenu } from '../../header_menu'; -import { headerMenuCss } from '../list_header.styles'; +import { headerMenuCss, noLinkedRulesCss } from '../list_header.styles'; import * as i18n from '../../translations'; import { Rule } from '../../types'; import { generateLinkedRulesMenuItems } from '../../generate_linked_rules_menu_item'; @@ -16,6 +16,7 @@ interface MenuItemsProps { isReadonly: boolean; dataTestSubj?: string; linkedRules: Rule[]; + canUserEditList?: boolean; securityLinkAnchorComponent: React.ElementType; // This property needs to be removed to avoid the Prop Drilling, once we move all the common components from x-pack/security-solution/common onExportList: () => void; onDeleteList: () => void; @@ -27,6 +28,7 @@ const MenuItemsComponent: FC = ({ linkedRules, securityLinkAnchorComponent, isReadonly, + canUserEditList = true, onExportList, onDeleteList, onManageRules, @@ -51,17 +53,23 @@ const MenuItemsComponent: FC = ({ gutterSize="l" > - + {linkedRules.length ? ( + + ) : ( + + {i18n.EXCEPTION_LIST_HEADER_LINKED_RULES(linkedRules.length)} + + )} @@ -95,6 +103,7 @@ const MenuItemsComponent: FC = ({ onClick: () => { if (typeof onDeleteList === 'function') onDeleteList(); }, + disabled: !canUserEditList, }, ]} disableActions={isReadonly} diff --git a/packages/kbn-securitysolution-exception-list-components/src/list_header/menu_items/menu_items.test.tsx b/packages/kbn-securitysolution-exception-list-components/src/list_header/menu_items/menu_items.test.tsx index 95d03a5b4678e..470b2402550b6 100644 --- a/packages/kbn-securitysolution-exception-list-components/src/list_header/menu_items/menu_items.test.tsx +++ b/packages/kbn-securitysolution-exception-list-components/src/list_header/menu_items/menu_items.test.tsx @@ -32,6 +32,53 @@ describe('MenuItems', () => { expect(wrapper.getByTestId('ManageRulesButton')).toBeInTheDocument(); expect(wrapper.getByTestId('MenuActionsButtonIcon')).toBeInTheDocument(); }); + it('should not render linkedRules HeaderMenu component, instead should render a text', () => { + const wrapper = render( + + ); + expect(wrapper).toMatchSnapshot(); + expect(wrapper.queryByTestId('LinkedRulesMenuItems')).not.toBeInTheDocument(); + expect(wrapper.getByTestId('noLinkedRules')).toBeInTheDocument(); + }); + it('should render all menu actions enabled', () => { + const wrapper = render( + + ); + fireEvent.click(wrapper.getByTestId('MenuActionsButtonIcon')); + expect(wrapper).toMatchSnapshot(); + expect(wrapper.getByTestId('MenuActionsActionItem1')).toBeEnabled(); + expect(wrapper.getByTestId('MenuActionsActionItem2')).toBeEnabled(); + }); + it('should render delete action disabled', () => { + const wrapper = render( + + ); + fireEvent.click(wrapper.getByTestId('MenuActionsButtonIcon')); + expect(wrapper).toMatchSnapshot(); + expect(wrapper.getByTestId('MenuActionsActionItem2')).toBeDisabled(); + }); it('should call onManageRules', () => { const wrapper = render( { - setIsModalVisible(false); setListDetails(newListDetails); if (typeof onEditListDetails === 'function') onEditListDetails(newListDetails); + setTimeout(() => { + setIsModalVisible(false); + }, 200); }; const onCancel = () => { setIsModalVisible(false); diff --git a/packages/kbn-securitysolution-exception-list-components/src/mocks/header.mock.ts b/packages/kbn-securitysolution-exception-list-components/src/mocks/header.mock.ts index 55e3199e0a99e..addd022a27b2e 100644 --- a/packages/kbn-securitysolution-exception-list-components/src/mocks/header.mock.ts +++ b/packages/kbn-securitysolution-exception-list-components/src/mocks/header.mock.ts @@ -21,3 +21,18 @@ export const actions = [ onClick: handleDelete, }, ]; +export const actionsWithDisabledDelete = [ + { + key: 'edit', + icon: 'pencil', + label: 'Edit detection exception', + onClick: handleEdit, + }, + { + key: 'delete', + icon: 'trash', + disabled: true, + label: 'Delete detection exception', + onClick: handleDelete, + }, +]; diff --git a/packages/kbn-securitysolution-exception-list-components/src/mocks/rule_references.mock.ts b/packages/kbn-securitysolution-exception-list-components/src/mocks/rule_references.mock.ts index d2a5e0ab0a756..8c2921debf246 100644 --- a/packages/kbn-securitysolution-exception-list-components/src/mocks/rule_references.mock.ts +++ b/packages/kbn-securitysolution-exception-list-components/src/mocks/rule_references.mock.ts @@ -10,7 +10,7 @@ import { Rule, RuleReference } from '../types'; export const rules: Rule[] = [ { - exception_lists: [ + exception_list: [ { id: '123', list_id: 'i_exist', diff --git a/packages/kbn-securitysolution-exception-list-components/src/mocks/security_link_component.mock.tsx b/packages/kbn-securitysolution-exception-list-components/src/mocks/security_link_component.mock.tsx index db0a64affc182..27334c636fdff 100644 --- a/packages/kbn-securitysolution-exception-list-components/src/mocks/security_link_component.mock.tsx +++ b/packages/kbn-securitysolution-exception-list-components/src/mocks/security_link_component.mock.tsx @@ -26,7 +26,7 @@ export const getSecurityLinkAction = (dataTestSubj: string) => linkedRules: [ ...rules, { - exception_lists: [], + exception_list: [], id: '2a2b3c', name: 'Simple Rule Query 2', rule_id: 'rule-2', diff --git a/packages/kbn-securitysolution-exception-list-components/src/text_with_edit/__snapshots__/text_with_edit.test.tsx.snap b/packages/kbn-securitysolution-exception-list-components/src/text_with_edit/__snapshots__/text_with_edit.test.tsx.snap index 4543f84553ae6..6d67ff422ae7f 100644 --- a/packages/kbn-securitysolution-exception-list-components/src/text_with_edit/__snapshots__/text_with_edit.test.tsx.snap +++ b/packages/kbn-securitysolution-exception-list-components/src/text_with_edit/__snapshots__/text_with_edit.test.tsx.snap @@ -6,25 +6,39 @@ Object { "baseElement":
- - Test - + + Test + +
+
, "container":
- - Test - + + Test + +
+
, "debug": [Function], @@ -87,13 +101,53 @@ Object { "baseElement":
+
+ + Test + +
+
+ +
+
+
+ , + "container":
+
+
Test +
+
- , - "container":
-
- - Test - - -
, "debug": [Function], "findAllByAltText": [Function], diff --git a/packages/kbn-securitysolution-exception-list-components/src/text_with_edit/index.tsx b/packages/kbn-securitysolution-exception-list-components/src/text_with_edit/index.tsx index 5b56b27053396..8d0da29b2ea4e 100644 --- a/packages/kbn-securitysolution-exception-list-components/src/text_with_edit/index.tsx +++ b/packages/kbn-securitysolution-exception-list-components/src/text_with_edit/index.tsx @@ -7,10 +7,9 @@ */ import React, { FC } from 'react'; -import { EuiButtonIcon } from '@elastic/eui'; +import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { Interpolation, Theme } from '@emotion/react'; -import { textWithEditContainerCss } from '../list_header/list_header.styles'; - +import { textWithEditContainerCss, editIconCss } from './text_with_edit.styles'; interface TextWithEditProps { isReadonly: boolean; dataTestSubj?: string; @@ -27,19 +26,23 @@ const TextWithEditComponent: FC = ({ textCss, }) => { return ( -
- - {text} - - {isReadonly ? null : ( - (typeof onEdit === 'function' ? onEdit() : null)} - /> - )} -
+ + + + {text} + + + + {isReadonly ? null : ( + (typeof onEdit === 'function' ? onEdit() : null)} + /> + )} + + ); }; TextWithEditComponent.displayName = 'TextWithEditComponent'; diff --git a/packages/kbn-securitysolution-exception-list-components/src/text_with_edit/text_with_edit.styles.ts b/packages/kbn-securitysolution-exception-list-components/src/text_with_edit/text_with_edit.styles.ts new file mode 100644 index 0000000000000..1aed7932695d9 --- /dev/null +++ b/packages/kbn-securitysolution-exception-list-components/src/text_with_edit/text_with_edit.styles.ts @@ -0,0 +1,25 @@ +/* + * 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 { css } from '@emotion/react'; +import { euiThemeVars } from '@kbn/ui-theme'; + +export const textWithEditContainerCss = css` + display: flex; + width: fit-content; + align-items: baseline; + padding-bottom: ${euiThemeVars.euiSizeS}; + h1 { + margin-bottom: 0; + } +`; +export const editIconCss = css` + button { + margin-left: -${euiThemeVars.euiSizeM}; + } +`; diff --git a/packages/kbn-securitysolution-exception-list-components/src/translations.ts b/packages/kbn-securitysolution-exception-list-components/src/translations.ts index c5740958abcf4..38cb15f4b742e 100644 --- a/packages/kbn-securitysolution-exception-list-components/src/translations.ts +++ b/packages/kbn-securitysolution-exception-list-components/src/translations.ts @@ -140,3 +140,10 @@ export const EXCEPTION_LIST_HEADER_DESCRIPTION_TEXTBOX = i18n.translate( defaultMessage: 'Description', } ); + +export const LIST_NAME_REQUIRED_ERROR = i18n.translate( + 'exceptionList-components.exception_list_header_description_textboxexceptionList-components.exception_list_header_name_required_eror', + { + defaultMessage: 'List name cannot be empty', + } +); diff --git a/packages/kbn-securitysolution-exception-list-components/src/types/index.ts b/packages/kbn-securitysolution-exception-list-components/src/types/index.ts index d799879916dee..ba35f0753cc68 100644 --- a/packages/kbn-securitysolution-exception-list-components/src/types/index.ts +++ b/packages/kbn-securitysolution-exception-list-components/src/types/index.ts @@ -60,7 +60,7 @@ export interface Rule { name: string; id: string; rule_id: string; - exception_lists: ListArray; + exception_list?: ListArray; } export interface RuleReference { From 1816f58f1d55c6a62db2194492a743f478b6efe7 Mon Sep 17 00:00:00 2001 From: Dario Gieselaar Date: Fri, 4 Nov 2022 13:38:22 +0100 Subject: [PATCH 12/31] Change CODEOWNERS for @kbn/rule-data-utils (#144608) --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index caf16d1050725..01f4bd562a9e0 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -950,7 +950,7 @@ packages/kbn-plugin-helpers @elastic/kibana-operations packages/kbn-react-field @elastic/kibana-app-services packages/kbn-repo-source-classifier @elastic/kibana-operations packages/kbn-repo-source-classifier-cli @elastic/kibana-operations -packages/kbn-rule-data-utils @elastic/apm-ui +packages/kbn-rule-data-utils @elastic/security-detections-response @elastic/actionable-observability @elastic/response-ops packages/kbn-safer-lodash-set @elastic/kibana-security packages/kbn-securitysolution-autocomplete @elastic/security-solution-platform packages/kbn-securitysolution-es-utils @elastic/security-solution-platform From caffde0fe91e763f459f67ff76604458d7b61cfa Mon Sep 17 00:00:00 2001 From: Angela Chuang <6295984+angorayc@users.noreply.github.com> Date: Fri, 4 Nov 2022 12:53:50 +0000 Subject: [PATCH 13/31] [SecuritySolution] Risk Score api clean up and update documentation (#144325) * rm unused restart transform * [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' * rm unused params * update readme Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../security_solution/common/constants.ts | 1 - .../containers/onboarding/api/index.ts | 1 - .../containers/onboarding/api/indices.test.ts | 80 --- .../containers/onboarding/api/indices.ts | 75 --- .../containers/onboarding/api/transforms.ts | 50 -- .../containers/onboarding/api/translations.ts | 19 - .../containers/onboarding/api/types.ts | 19 - .../server/lib/risk_score/readme.md | 490 +++++++++++++++++- .../server/lib/risk_score/routes/index.ts | 1 - .../transform/helpers/transforms.ts | 59 --- .../risk_score/transform/restart_transform.ts | 77 --- .../security_solution/server/routes/index.ts | 2 - 12 files changed, 473 insertions(+), 401 deletions(-) delete mode 100644 x-pack/plugins/security_solution/public/risk_score/containers/onboarding/api/indices.test.ts delete mode 100644 x-pack/plugins/security_solution/public/risk_score/containers/onboarding/api/indices.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/transform/restart_transform.ts diff --git a/x-pack/plugins/security_solution/common/constants.ts b/x-pack/plugins/security_solution/common/constants.ts index 65c5757a1b1bb..1847be23dbe9b 100644 --- a/x-pack/plugins/security_solution/common/constants.ts +++ b/x-pack/plugins/security_solution/common/constants.ts @@ -277,7 +277,6 @@ export const DETECTION_ENGINE_RULES_BULK_UPDATE = `${DETECTION_ENGINE_RULES_URL}/_bulk_update` as const; export const INTERNAL_RISK_SCORE_URL = '/internal/risk_score' as const; -export const RISK_SCORE_RESTART_TRANSFORMS = `${INTERNAL_RISK_SCORE_URL}/transforms/restart`; export const DEV_TOOL_PREBUILT_CONTENT = `${INTERNAL_RISK_SCORE_URL}/prebuilt_content/dev_tool/{console_id}` as const; export const devToolPrebuiltContentUrl = (spaceId: string, consoleId: string) => diff --git a/x-pack/plugins/security_solution/public/risk_score/containers/onboarding/api/index.ts b/x-pack/plugins/security_solution/public/risk_score/containers/onboarding/api/index.ts index cc25b1c874a89..3223e9c7c3726 100644 --- a/x-pack/plugins/security_solution/public/risk_score/containers/onboarding/api/index.ts +++ b/x-pack/plugins/security_solution/public/risk_score/containers/onboarding/api/index.ts @@ -4,7 +4,6 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -export * from './indices'; export * from './ingest_pipelines'; export * from './transforms'; export * from './stored_scripts'; diff --git a/x-pack/plugins/security_solution/public/risk_score/containers/onboarding/api/indices.test.ts b/x-pack/plugins/security_solution/public/risk_score/containers/onboarding/api/indices.test.ts deleted file mode 100644 index a5846027a7fe3..0000000000000 --- a/x-pack/plugins/security_solution/public/risk_score/containers/onboarding/api/indices.test.ts +++ /dev/null @@ -1,80 +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 { HttpSetup } from '@kbn/core-http-browser'; -import type { NotificationsStart } from '@kbn/core-notifications-browser'; -import { createIndices, deleteIndices } from './indices'; - -const mockRequest = jest.fn(); -const mockHttp = { - put: mockRequest, - post: mockRequest, -} as unknown as HttpSetup; - -const mockAddDanger = jest.fn(); -const mockAddError = jest.fn(); -const mockNotification = { - toasts: { - addDanger: mockAddDanger, - addError: mockAddError, - }, -} as unknown as NotificationsStart; - -const mockRenderDocLink = jest.fn(); - -describe('createIndices', () => { - const mockOptions = { index: 'test', mappings: {} }; - - beforeAll(async () => { - mockRequest.mockRejectedValue({ body: { message: 'test error' } }); - await createIndices({ - http: mockHttp, - notifications: mockNotification, - options: mockOptions, - renderDocLink: mockRenderDocLink, - }); - }); - - afterAll(() => { - jest.clearAllMocks(); - }); - it('create index', () => { - expect(mockRequest.mock.calls[0][0]).toEqual(`/internal/risk_score/indices/create`); - }); - - it('handles error', () => { - expect(mockAddDanger.mock.calls[0][0].title).toEqual('Failed to create index'); - expect(mockRenderDocLink.mock.calls[0][0]).toEqual('test error'); - }); -}); - -describe('deleteIndices', () => { - const mockOptions = { indices: ['test', 'abc'] }; - - beforeAll(async () => { - mockRequest.mockRejectedValue({ body: { message: 'test error' } }); - await deleteIndices({ - http: mockHttp, - notifications: mockNotification, - options: mockOptions, - renderDocLink: mockRenderDocLink, - }); - }); - - afterAll(() => { - jest.clearAllMocks(); - }); - - it('delete index', () => { - expect(mockRequest.mock.calls[0][0]).toEqual(`/internal/risk_score/indices/delete`); - }); - - it('handles error', () => { - expect(mockAddDanger.mock.calls[0][0].title).toEqual('Failed to delete indices'); - expect(mockRenderDocLink.mock.calls[0][0]).toEqual('test error'); - }); -}); diff --git a/x-pack/plugins/security_solution/public/risk_score/containers/onboarding/api/indices.ts b/x-pack/plugins/security_solution/public/risk_score/containers/onboarding/api/indices.ts deleted file mode 100644 index d5a7b6145e2ce..0000000000000 --- a/x-pack/plugins/security_solution/public/risk_score/containers/onboarding/api/indices.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. - */ - -import { toMountPoint } from '@kbn/kibana-react-plugin/public'; -import { INDICES_CREATION_ERROR_MESSAGE, INDICES_DELETION_ERROR_MESSAGE } from './translations'; -import type { CreateIndices, DeleteIndices } from './types'; -import { - RISK_SCORE_CREATE_INDEX, - RISK_SCORE_DELETE_INDICES, -} from '../../../../../common/constants'; - -export async function createIndices({ - errorMessage, - http, - notifications, - options, - renderDocLink, - signal, - theme, -}: CreateIndices) { - const res = await http - .put(RISK_SCORE_CREATE_INDEX, { - body: JSON.stringify(options), - signal, - }) - .catch((e) => { - notifications?.toasts?.addDanger({ - title: errorMessage ?? INDICES_CREATION_ERROR_MESSAGE, - text: toMountPoint( - renderDocLink && e?.body?.message != null - ? renderDocLink(e?.body?.message) - : e?.body?.message, - { - theme$: theme?.theme$, - } - ), - }); - }); - - return res; -} - -export async function deleteIndices({ - errorMessage, - http, - notifications, - options, - renderDocLink, - signal, - theme, -}: DeleteIndices) { - const count = options.indices.length; - const res = await http - .post(RISK_SCORE_DELETE_INDICES, { - body: JSON.stringify(options), - signal, - }) - .catch((e) => { - notifications?.toasts?.addDanger({ - title: errorMessage ?? INDICES_DELETION_ERROR_MESSAGE(count), - text: toMountPoint( - renderDocLink && e?.body?.message ? renderDocLink(e?.body?.message) : e?.body?.message, - { - theme$: theme?.theme$, - } - ), - }); - }); - - return res; -} diff --git a/x-pack/plugins/security_solution/public/risk_score/containers/onboarding/api/transforms.ts b/x-pack/plugins/security_solution/public/risk_score/containers/onboarding/api/transforms.ts index f237ee82af87d..da6dd0d7ddf6c 100644 --- a/x-pack/plugins/security_solution/public/risk_score/containers/onboarding/api/transforms.ts +++ b/x-pack/plugins/security_solution/public/risk_score/containers/onboarding/api/transforms.ts @@ -5,11 +5,9 @@ * 2.0. */ -import { RISK_SCORE_RESTART_TRANSFORMS } from '../../../../../common/constants'; import { GET_TRANSFORM_STATE_ERROR_MESSAGE, GET_TRANSFORM_STATE_NOT_FOUND_MESSAGE, - RESTART_TRANSFORMS_ERROR_MESSAGE, START_TRANSFORMS_ERROR_MESSAGE, STOP_TRANSFORMS_ERROR_MESSAGE, TRANSFORM_CREATION_ERROR_MESSAGE, @@ -22,8 +20,6 @@ import type { DeleteTransformsResult, GetTransformsState, GetTransformState, - RestartTransforms, - RestartTransformResult, StartTransforms, StartTransformsResult, StopTransforms, @@ -322,49 +318,3 @@ export async function deleteTransforms({ return res; } - -export async function restartTransforms({ - http, - notifications, - renderDocLink, - signal, - errorMessage, - riskScoreEntity, -}: RestartTransforms) { - const res = await http - .post(`${RISK_SCORE_RESTART_TRANSFORMS}`, { - body: JSON.stringify({ riskScoreEntity }), - signal, - }) - .then((result) => { - const failedIds = result.reduce((acc, curr) => { - const [[key, val]] = Object.entries(curr); - return !val.success - ? [...acc, val?.error?.message ? `${key}: ${val?.error?.message}` : key] - : acc; - }, []); - const errorMessageTitle = errorMessage ?? RESTART_TRANSFORMS_ERROR_MESSAGE(failedIds.length); - - if (failedIds.length > 0) { - notifications?.toasts?.addError(new Error(errorMessageTitle), { - title: errorMessageTitle, - toastMessage: getErrorToastMessage({ - messageBody: failedIds.join(', '), - renderDocLink, - }), - toastLifeTimeMs, - }); - } - - return result; - }) - .catch((e) => { - notifications?.toasts?.addError(e, { - title: errorMessage ?? RESTART_TRANSFORMS_ERROR_MESSAGE(), - toastMessage: getErrorToastMessage({ messageBody: e?.body?.message, renderDocLink }), - toastLifeTimeMs, - }); - }); - - return res; -} diff --git a/x-pack/plugins/security_solution/public/risk_score/containers/onboarding/api/translations.ts b/x-pack/plugins/security_solution/public/risk_score/containers/onboarding/api/translations.ts index 830614f25e466..4af4a3f373ef1 100644 --- a/x-pack/plugins/security_solution/public/risk_score/containers/onboarding/api/translations.ts +++ b/x-pack/plugins/security_solution/public/risk_score/containers/onboarding/api/translations.ts @@ -20,19 +20,6 @@ export const INGEST_PIPELINE_DELETION_ERROR_MESSAGE = (totalCount: number) => defaultMessage: `Failed to delete Ingest {totalCount, plural, =1 {pipeline} other {pipelines}}`, }); -export const INDICES_CREATION_ERROR_MESSAGE = i18n.translate( - 'xpack.securitySolution.riskScore.api.indices.create.errorMessageTitle', - { - defaultMessage: 'Failed to create index', - } -); - -export const INDICES_DELETION_ERROR_MESSAGE = (totalCount: number) => - i18n.translate('xpack.securitySolution.riskScore.api.indices.delete.errorMessageTitle', { - values: { totalCount }, - defaultMessage: `Failed to delete {totalCount, plural, =1 {index} other {indices}}`, - }); - export const STORED_SCRIPT_CREATION_ERROR_MESSAGE = i18n.translate( 'xpack.securitySolution.riskScore.api.storedScript.create.errorMessageTitle', { @@ -80,12 +67,6 @@ export const START_TRANSFORMS_ERROR_MESSAGE = (totalCount: number) => defaultMessage: `Failed to start {totalCount, plural, =1 {Transform} other {Transforms}}`, }); -export const RESTART_TRANSFORMS_ERROR_MESSAGE = (totalCount?: number) => - i18n.translate('xpack.securitySolution.riskScore.api.transforms.start.errorMessageTitle', { - values: { totalCount }, - defaultMessage: `Failed to start {totalCount, plural, =1 {Transform} other {Transforms}}`, - }); - export const STOP_TRANSFORMS_ERROR_MESSAGE = (totalCount: number) => i18n.translate('xpack.securitySolution.riskScore.api.transforms.stop.errorMessageTitle', { values: { totalCount }, diff --git a/x-pack/plugins/security_solution/public/risk_score/containers/onboarding/api/types.ts b/x-pack/plugins/security_solution/public/risk_score/containers/onboarding/api/types.ts index 1f95545258260..e2888772e7b57 100644 --- a/x-pack/plugins/security_solution/public/risk_score/containers/onboarding/api/types.ts +++ b/x-pack/plugins/security_solution/public/risk_score/containers/onboarding/api/types.ts @@ -5,8 +5,6 @@ * 2.0. */ import type { HttpSetup, NotificationsStart, ThemeServiceStart } from '@kbn/core/public'; -import type { OutputError } from '@kbn/securitysolution-es-utils'; -import type { RiskScoreEntity } from '../../../../../common/search_strategy/security_solution/risk_score/common'; interface RiskyScoreApiBase { errorMessage?: string; @@ -27,14 +25,6 @@ export interface DeleteIngestPipeline extends RiskyScoreApiBase { names: string; } -export interface CreateIndices extends RiskyScoreApiBase { - options: { index: string; mappings: string | Record }; -} - -export interface DeleteIndices extends RiskyScoreApiBase { - options: { indices: string[] }; -} - export interface CreateStoredScript extends RiskyScoreApiBase { options: { id: string; @@ -73,10 +63,6 @@ export interface StartTransforms extends RiskyScoreApiBase { transformIds: string[]; } -export interface RestartTransforms extends RiskyScoreApiBase { - riskScoreEntity: RiskScoreEntity; -} - interface TransformResult { success: boolean; error?: { root_cause?: unknown; type?: string; reason?: string }; @@ -84,11 +70,6 @@ interface TransformResult { export type StartTransformsResult = Record; -export type RestartTransformResult = Record< - string, - { success: boolean; error: OutputError | null } ->; - export interface StopTransforms extends RiskyScoreApiBase { transformIds: string[]; } diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/readme.md b/x-pack/plugins/security_solution/server/lib/risk_score/readme.md index e6f452cefdc95..e2bc1c280affc 100644 --- a/x-pack/plugins/security_solution/server/lib/risk_score/readme.md +++ b/x-pack/plugins/security_solution/server/lib/risk_score/readme.md @@ -2,21 +2,477 @@ ### API usage -The risk score API has one route with one method - -1. GET - `getRiskScoreIndexStatusRoute` -2. REQUEST: - ```typescript - GET /internal/risk_score/index_status - { - indexName: 'ml_host_risk_score_latest' +#### 1. GET /internal/risk_score/index_status - `getRiskScoreIndexStatusRoute` +##### REQUEST: +```typescript + GET /internal/risk_score/index_status + { + indexName: 'ml_host_risk_score_latest' + } +``` +##### RESPONSE: +```typescript + { + isDeprecated: boolean; + isEnabled: boolean; + } +``` +##### This route is called from `useRiskScore` hook. + +#### 2. PUT - /internal/risk_score/indices/create + +example: +##### REQUEST: + +``` +PUT /internal/risk_score/indices/create +{ + "index": "ml_host_risk_score_latest_default-test", + "mappings": { + "properties": { + "host.name": { + "type": "keyword" + }, + "@timestamp": { + "type": "date" + }, + "ingest_timestamp": { + "type": "date" + }, + "risk": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword" + } + } + }, + "risk_stats": { + "properties": { + "risk_score": { + "type": "float" + } + } + } } - ``` -3. RESPONSE: - ```typescript - { - isDeprecated: boolean; - isEnabled: boolean; - } - ``` -4. This route is called from `useRiskScore` hook. \ No newline at end of file + } +} +``` + + +##### RESPONSE: +``` +{ + "index": "ml_host_risk_score_latest_default-test", + "mappings": { + "properties": { + "host.name": { + "type": "keyword" + }, + "@timestamp": { + "type": "date" + }, + "ingest_timestamp": { + "type": "date" + }, + "risk": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword" + } + } + }, + "risk_stats": { + "properties": { + "risk_score": { + "type": "float" + } + } + } + } + } +} +``` + +#### 3. POST - /internal/risk_score/indices/delete + +example: + +##### REQUEST: +``` + POST /internal/risk_score/indices/delete + { + "indices": ["ml_host_risk_score_latest_default-test"] + } +``` + +##### RESPONSE: +``` + { + "deleted": [ + "ml_host_risk_score_latest_default-test" + ] + } +``` + +#### 4. POST - /internal/risk_score + +Onboard host or user risk score. +##### Option: + +|Body|description| +|--|--| +|riskScoreEntity|value: `host` or `user`| + +example: + +##### REQUEST: +``` + POST /internal/risk_score + { + "riskScoreEntity": host + } +``` +##### RESPONSE: + +``` +[ + { + "ml_hostriskscore_levels_script_default": { + "success": true, + "error": null + } + }, + { + "ml_hostriskscore_ingest_pipeline_default": { + "success": true, + "error": null + } + }, + { + "ml_hostriskscore_init_script_default": { + "success": true, + "error": null + } + }, + { + "ml_hostriskscore_map_script_default": { + "success": true, + "error": null + } + }, + { + "ml_hostriskscore_reduce_script_default": { + "success": true, + "error": null + } + }, + { + "ml_host_risk_score_default": { + "success": true, + "error": null + } + }, + { + "ml_host_risk_score_latest_default": { + "success": true, + "error": null + } + }, + { + "ml_hostriskscore_pivot_transform_default": { + "success": true, + "error": null + } + }, + { + "ml_hostriskscore_latest_transform_default": { + "success": true, + "error": null + } + } +] +``` + +#### 5. GET - /internal/risk_score/prebuilt_content/dev_tool/{console_id} + +Get scripts for onboarding host or user risk score + +##### Option: + +|Param|description| +|--|--| +|console_id|value: `enable_host_risk_score` or `enable_user_risk_score`| + +example: + +##### REQUEST: + +``` +GET /internal/risk_score/prebuilt_content/dev_tool/enable_host_risk_score +``` + +##### RESPONSE: + +``` +# Click the run button of each step to enable the module +# Upload scripts +# 1. Script to assign risk level based on risk score +PUT _scripts/ml_hostriskscore_levels_script_default +{ +"script": { +"lang": "painless", +"source": "double risk_score = (def)ctx.getByPath(params.risk_score);\nif (risk_score < 20) {\n + ctx['host']['risk']['calculated_level']='Unknown' \n}\nelse if (risk_score>= 20 && risk_score < 40) {\n + ctx['host']['risk']['calculated_level']='Low' \n}\nelse if (risk_score>= 40 && risk_score < 70) {\n + ctx['host']['risk']['calculated_level']='Moderate' \n}\nelse if (risk_score>= 70 && risk_score < 90) {\n + ctx['host']['risk']['calculated_level']='High' \n}\nelse if (risk_score>= 90) {\n + ctx['host']['risk']['calculated_level'] = 'Critical'\n}" + } + } + + # 2. Script to setup initial state for the Host Risk Score scripted metric aggregation + PUT _scripts/ml_hostriskscore_init_script_default + { + "script": { + "lang": "painless", + "source": "state.rule_risk_stats = new HashMap();\nstate.host_variant_set = false;\nstate.host_variant = + new String();\nstate.tactic_ids = new HashSet();" + } + } + + # 3. Map script for the Host Risk Score transform + PUT _scripts/ml_hostriskscore_map_script_default + { + "script": { + "lang": "painless", + "source": "// Get the host variant\nif (state.host_variant_set == false) {\n if + (doc.containsKey(\"host.os.full\") && doc[\"host.os.full\"].size() != 0) {\n state.host_variant = + doc[\"host.os.full\"].value;\n state.host_variant_set = true;\n }\n}\n// Aggregate all the tactics seen + on the host\nif (doc.containsKey(\"signal.rule.threat.tactic.id\") && + doc[\"signal.rule.threat.tactic.id\"].size() != 0) {\n + state.tactic_ids.add(doc[\"signal.rule.threat.tactic.id\"].value);\n}\n// Get running sum of + time-decayed risk score per rule name per shard\nString rule_name = + doc[\"signal.rule.name\"].value;\ndef stats = state.rule_risk_stats.getOrDefault(rule_name, + [0.0,\"\",false]);\nint time_diff = (int)((System.currentTimeMillis() - + doc[\"@timestamp\"].value.toInstant().toEpochMilli()) / (1000.0 * 60.0 * 60.0));\ndouble risk_derate = + Math.min(1, Math.exp((params.lookback_time - time_diff) / params.time_decay_constant));\nstats[0] = + Math.max(stats[0], doc[\"signal.rule.risk_score\"].value * risk_derate);\nif (stats[2] == false) {\n + stats[1] = doc[\"kibana.alert.rule.uuid\"].value;\n stats[2] = + true;\n}\nstate.rule_risk_stats.put(rule_name, stats);" + } + } + + # 4. Reduce script for the Host Risk Score transform + PUT _scripts/ml_hostriskscore_reduce_script_default + { + "script": { + "lang": "painless", + "source": "// Consolidating time decayed risks and tactics from across all shards\nMap total_risk_stats + = new HashMap();\nString host_variant = new String();\ndef tactic_ids = new HashSet();\nfor (state in + states) {\n for (key in state.rule_risk_stats.keySet()) {\n def rule_stats = + state.rule_risk_stats.get(key);\n def stats = total_risk_stats.getOrDefault(key, [0.0,\"\",false]);\n + stats[0] = Math.max(stats[0], rule_stats[0]);\n if (stats[2] == false) {\n stats[1] = rule_stats[1];\n + stats[2] = true;\n } \n total_risk_stats.put(key, stats);\n }\n if (host_variant.length() == 0) {\n + host_variant = state.host_variant;\n }\n tactic_ids.addAll(state.tactic_ids);\n}\n// Consolidating + individual rule risks and arranging them in decreasing order\nList risks = new ArrayList();\nfor (key in + total_risk_stats.keySet()) {\n risks.add(total_risk_stats[key][0])\n}\nCollections.sort(risks, + Collections.reverseOrder());\n// Calculating total host risk score\ndouble total_risk = 0.0;\ndouble + risk_cap = params.max_risk * params.zeta_constant;\nfor (int i=0;i= 40 && total_norm_risk < 50) {\n total_norm_risk=85 + + (total_norm_risk - 40);\n}\nelse {\n total_norm_risk=95 + (total_norm_risk - 50) / 10;\n}\n// + Calculating multipliers to the host risk score\ndouble risk_multiplier=1.0;\nList + multipliers=new ArrayList();\n// Add a multiplier if host is a server\nif + (host_variant.toLowerCase().contains(\"server\")) {\n risk_multiplier + *=params.server_multiplier;\n multipliers.add(\"Host is a server\");\n}\n// Add multipliers + based on number and diversity of tactics seen on the host\nfor (String tactic : tactic_ids) {\n + multipliers.add(\"Tactic \"+tactic);\n risk_multiplier *=1 + params.tactic_base_multiplier * + params.tactic_weights.getOrDefault(tactic, 0);\n}\n// Calculating final risk\ndouble + final_risk=total_norm_risk;\nif (risk_multiplier> 1.0) {\n double prior_odds = (total_norm_risk) + / (100 - total_norm_risk);\n double updated_odds = prior_odds * risk_multiplier; \n final_risk = + 100 * updated_odds / (1 + updated_odds);\n}\n// Adding additional metadata\nList rule_stats = + new ArrayList();\nfor (key in total_risk_stats.keySet()) {\n Map temp = new HashMap();\n + temp[\"rule_name\"] = key;\n temp[\"rule_risk\"] = total_risk_stats[key][0];\n temp[\"rule_id\"] + = total_risk_stats[key][1];\n rule_stats.add(temp);\n}\n\nreturn [\"calculated_score_norm\": + final_risk, \"rule_risks\": rule_stats, \"multipliers\": multipliers];" + } + } + + # 5. Upload the ingest pipeline + # Ingest pipeline to add ingest timestamp and risk level to documents + PUT _ingest/pipeline/ml_hostriskscore_ingest_pipeline_default + { + "processors": + [{"set":{"field":"ingest_timestamp","value":"{{_ingest.timestamp}}"}},{"fingerprint":{"fields":["@timestamp","_id"],"method":"SHA-256","target_field":"_id"}},{"script":{"id":"ml_hostriskscore_levels_script_default","params":{"risk_score":"host.risk.calculated_score_norm"}}}] + } + + # 6. Create mappings for the destination index of the Host Risk Score pivot transform + PUT ml_host_risk_score_default + { + "mappings": + {"properties":{"host":{"properties":{"name":{"type":"keyword"},"risk":{"properties":{"calculated_score_norm":{"type":"float"},"calculated_level":{"type":"keyword"},"multipliers":{"type":"keyword"},"rule_risks":{"properties":{"rule_name":{"type":"text","fields":{"keyword":{"type":"keyword"}}},"rule_risk":{"type":"float"},"rule_id":{"type":"keyword"}}}}}}},"ingest_timestamp":{"type":"date"},"@timestamp":{"type":"date"}}} + } + + # 7. Upload the Host Risk Score pivot transform + # This transform runs hourly and calculates a risk score and risk level for hosts in a Kibana + space + PUT _transform/ml_hostriskscore_pivot_transform_default + {"dest":{"index":"ml_host_risk_score_default","pipeline":"ml_hostriskscore_ingest_pipeline_default"},"frequency":"1h","pivot":{"aggregations":{"@timestamp":{"max":{"field":"@timestamp"}},"host.risk":{"scripted_metric":{"combine_script":"return + state","init_script":{"id":"ml_hostriskscore_init_script_default"},"map_script":{"id":"ml_hostriskscore_map_script_default"},"params":{"lookback_time":72,"max_risk":100,"p":1.5,"server_multiplier":1.5,"tactic_base_multiplier":0.25,"tactic_weights":{"TA0001":1,"TA0002":2,"TA0003":3,"TA0004":4,"TA0005":4,"TA0006":4,"TA0007":4,"TA0008":5,"TA0009":6,"TA0010":7,"TA0011":6,"TA0040":8,"TA0042":1,"TA0043":1},"time_decay_constant":6,"zeta_constant":2.612},"reduce_script":{"id":"ml_hostriskscore_reduce_script_default"}}}},"group_by":{"host.name":{"terms":{"field":"host.name"}}}},"source":{"index":[".alerts-security.alerts-default"],"query":{"bool":{"filter":[{"range":{"@timestamp":{"gte":"now-5d"}}}]}}},"sync":{"time":{"delay":"120s","field":"@timestamp"}}} + + + # 8. Start the pivot transform + POST _transform/ml_hostriskscore_pivot_transform_default/_start + + # 9. Create mappings for the destination index of the Host Risk Score latest transform + PUT ml_host_risk_score_latest_default + { + "mappings": + {"properties":{"host":{"properties":{"name":{"type":"keyword"},"risk":{"properties":{"calculated_score_norm":{"type":"float"},"calculated_level":{"type":"keyword"},"multipliers":{"type":"keyword"},"rule_risks":{"properties":{"rule_name":{"type":"text","fields":{"keyword":{"type":"keyword"}}},"rule_risk":{"type":"float"},"rule_id":{"type":"keyword"}}}}}}},"ingest_timestamp":{"type":"date"},"@timestamp":{"type":"date"}}} + } + + # 10. Upload the latest transform + # This transform gets the latest risk information about hosts in a Kibana space + PUT _transform/ml_hostriskscore_latest_transform_default + {"dest":{"index":"ml_host_risk_score_latest_default"},"frequency":"1h","latest":{"sort":"@timestamp","unique_key":["host.name"]},"source":{"index":["ml_host_risk_score_default"]},"sync":{"time":{"delay":"2s","field":"ingest_timestamp"}}} + + # 11. Start the latest transform + POST _transform/ml_hostriskscore_latest_transform_default/_start + + # Hint: If you don't see data after running any of the transforms, stop and restart the + transforms + # Stop the pivot transform + POST _transform/ml_hostriskscore_pivot_transform_default/_stop + + # Start the pivot transform + POST _transform/ml_hostriskscore_pivot_transform_default/_start + + # Stop the latest transform + POST _transform/ml_hostriskscore_latest_transform_default/_stop + + # Start the latest transform + POST _transform/ml_hostriskscore_latest_transform_default/_start +``` + +#### 6. POST - /internal/risk_score/prebuilt_content/saved_objects/_bulk_create/{template_name} + +Import saved objects for host or user risk score +##### Option: + +|Param|description| +|--|--| +|template_name|value: `hostRiskScoreDashboards` or `userRiskScoreDashboards`| + +example: + +##### REQUEST: + +``` +POST /internal/risk_score/prebuilt_content/saved_objects/_bulk_create/hostRiskScoreDashboards +``` + +##### RESPONSE: + +``` +{ + "hostRiskScoreDashboards": { + "success": true, + "error": null, + "body": [ + { + "id": "259ef77a-0ea2-4ba2-bb77-f33fae4ec8aa", + "type": "index-pattern", + "title": "ml_host_risk_score_default" + }, + { + "id": "0adfc3b7-efa0-470e-ac31-27b1d8e01c48", + "type": "lens", + "title": "Host Risk Score (Max Risk Score Histogram)" + }, + { + "id": "e1a4d5f1-e59f-4ee6-918b-a1a1b48bf8de", + "type": "index-pattern", + "title": ".alerts-security.alerts-default" + }, + { + "id": "7799bfdf-9318-4f85-b840-678ccfbd9f79", + "type": "visualization", + "title": "Host Risk Score (Rule Breakdown)" + }, + { + "id": "acbc71e9-de52-47cd-ade6-33be0efdb1dc", + "type": "visualization", + "title": "Associated Users (Rule Breakdown)" + }, + { + "id": "0fb7224d-5e32-4f3d-b408-ee6acfd3f0c6", + "type": "visualization", + "title": "Host Risk Score (Tactic Breakdown)- Verbose" + }, + { + "id": "53e4c2cd-9f34-48dd-ab87-f48b8c5dec22", + "type": "tag", + "name": "experimental" + }, + { + "id": "2175ffc6-c53c-46ac-b15d-be9b849881ac", + "type": "dashboard", + "title": "Drilldown of Host Risk Score" + }, + { + "id": "d9d560b4-beed-4c27-9989-95187e64d79b", + "type": "index-pattern", + "title": "ml_host_risk_score_latest_default" + }, + { + "id": "927a8467-ccc6-4374-85a4-0aab6c1c0613", + "type": "lens", + "title": "Current Risk Score for Hosts" + }, + { + "id": "aa7acd4e-b4e1-4730-acac-f73992034b0d", + "type": "dashboard", + "title": "Current Risk Score for Hosts" + } + ] + } +} +``` + +#### 7. POST - /internal/risk_score/prebuilt_content/saved_objects/_bulk_delete/{template_name} + +Import saved objects for host or user risk score +##### Option: + +|Param|description| +|--|--| +|template_name|value: `hostRiskScoreDashboards` or `userRiskScoreDashboards`| + +example: + +##### REQUEST: + +``` +POST /internal/risk_score/prebuilt_content/saved_objects/_bulk_delete/hostRiskScoreDashboards +``` + +##### RESPONSE: + +``` +[ + "Saved object [index-pattern/ml-host-risk-score-default-index-pattern] not found", + "Saved object [lens/d3f72670-d3a0-11eb-bd37-7bb50422e346] not found", + "Saved object [index-pattern/alerts-default-index-pattern] not found", + "Saved object [visualization/42371d00-cf7a-11eb-9a96-05d89f94ad96] not found", + "Saved object [visualization/a62d3ed0-cf92-11eb-a0ff-1763d16cbda7] not found", + "Saved object [visualization/b2dbc9b0-cf94-11eb-bd37-7bb50422e346] not found", + "Saved object [tag/1d00ebe0-f3b2-11eb-beb2-b91666445a94] not found", + "Saved object [dashboard/6f05c8c0-cf77-11eb-9a96-05d89f94ad96] not found", + "Saved object [index-pattern/ml-host-risk-score-latest-default-index-pattern] not found", + "Saved object [lens/dc289c10-d4ff-11eb-a0ff-1763d16cbda7] not found", + "Saved object [dashboard/27b483b0-d500-11eb-a0ff-1763d16cbda7] not found" +] +``` \ No newline at end of file diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/routes/index.ts b/x-pack/plugins/security_solution/server/lib/risk_score/routes/index.ts index c55c9086bb447..886e1fddeed2e 100644 --- a/x-pack/plugins/security_solution/server/lib/risk_score/routes/index.ts +++ b/x-pack/plugins/security_solution/server/lib/risk_score/routes/index.ts @@ -18,4 +18,3 @@ export { deleteStoredScriptRoute } from '../stored_scripts/delete_script_route'; export { getRiskScoreIndexStatusRoute } from '../index_status'; export { installRiskScoresRoute } from '../onboarding/routes/install_risk_scores'; -export { restartTransformRoute } from '../transform/restart_transform'; diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/transform/helpers/transforms.ts b/x-pack/plugins/security_solution/server/lib/risk_score/transform/helpers/transforms.ts index eddd6e52251e9..c79bff0206ea2 100644 --- a/x-pack/plugins/security_solution/server/lib/risk_score/transform/helpers/transforms.ts +++ b/x-pack/plugins/security_solution/server/lib/risk_score/transform/helpers/transforms.ts @@ -180,62 +180,3 @@ export const startTransformIfNotStarted = async ( }; } }; - -const stopTransform = async ( - esClient: ElasticsearchClient, - transformId: string, - logger: Logger -) => { - const fetchedTransformStats = await checkTransformState(esClient, transformId, logger); - if (fetchedTransformStats.state) { - try { - await esClient.transform.stopTransform({ - transform_id: transformId, - force: fetchedTransformStats.state === TRANSFORM_STATE.FAILED, - wait_for_completion: true, - }); - return { [transformId]: { success: true, error: null } }; - } catch (startErr) { - const startError = transformError(startErr); - - logger.error(`Failed stopping transform ${transformId}: ${startError.message}`); - return { - [transformId]: { - success: false, - error: startError, - }, - }; - } - } else { - logger.error( - `Not stopping transform ${transformId} since it's state is: ${fetchedTransformStats.state}` - ); - return { - [transformId]: { - success: false, - error: transformError( - new Error( - i18n.translate('xpack.securitySolution.riskScore.transform.stop.stateConflictTitle', { - values: { transformId, state: fetchedTransformStats.state }, - defaultMessage: `Not stopping transform {transformId} since it's state is: {state}`, - }) - ) - ), - }, - }; - } -}; - -export const restartTransform = ( - esClient: ElasticsearchClient, - transformId: string, - logger: Logger -) => { - return stopTransform(esClient, transformId, logger).then((result) => { - if (result[transformId].success) { - return startTransformIfNotStarted(esClient, transformId, logger); - } else { - return result; - } - }); -}; diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/transform/restart_transform.ts b/x-pack/plugins/security_solution/server/lib/risk_score/transform/restart_transform.ts deleted file mode 100644 index 9b08ea40da9bc..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/transform/restart_transform.ts +++ /dev/null @@ -1,77 +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 { transformError } from '@kbn/securitysolution-es-utils'; -import type { Logger } from '@kbn/core/server'; -import { schema } from '@kbn/config-schema'; - -import { RISK_SCORE_RESTART_TRANSFORMS } from '../../../../common/constants'; -import type { SecuritySolutionPluginRouter } from '../../../types'; - -import { buildSiemResponse } from '../../detection_engine/routes/utils'; - -import { RiskScoreEntity } from '../../../../common/search_strategy'; -import { restartTransform } from './helpers/transforms'; -import { - getRiskScoreLatestTransformId, - getRiskScorePivotTransformId, -} from '../../../../common/utils/risk_score_modules'; - -const restartRiskScoreTransformsSchema = { - body: schema.object({ - riskScoreEntity: schema.oneOf([ - schema.literal(RiskScoreEntity.host), - schema.literal(RiskScoreEntity.user), - ]), - }), -}; - -export const restartTransformRoute = (router: SecuritySolutionPluginRouter, logger: Logger) => { - router.post( - { - path: RISK_SCORE_RESTART_TRANSFORMS, - validate: restartRiskScoreTransformsSchema, - options: { - tags: ['access:securitySolution'], - }, - }, - async (context, request, response) => { - const siemResponse = buildSiemResponse(response); - const { riskScoreEntity } = request.body; - - try { - const securitySolution = await context.securitySolution; - - const spaceId = securitySolution?.getSpaceId(); - - const { client } = (await context.core).elasticsearch; - const esClient = client.asCurrentUser; - const restartPivotTransformResult = await restartTransform( - esClient, - getRiskScorePivotTransformId(riskScoreEntity, spaceId), - logger - ); - - const restartLatestTransformResult = await restartTransform( - esClient, - getRiskScoreLatestTransformId(riskScoreEntity, spaceId), - logger - ); - - return response.ok({ - body: [restartPivotTransformResult, restartLatestTransformResult], - }); - } catch (err) { - const error = transformError(err); - return siemResponse.error({ - body: error.message, - statusCode: error.statusCode, - }); - } - } - ); -}; diff --git a/x-pack/plugins/security_solution/server/routes/index.ts b/x-pack/plugins/security_solution/server/routes/index.ts index df67c6ddce423..001bdfb59ead5 100644 --- a/x-pack/plugins/security_solution/server/routes/index.ts +++ b/x-pack/plugins/security_solution/server/routes/index.ts @@ -70,7 +70,6 @@ import { getRiskScoreIndexStatusRoute, installRiskScoresRoute, readPrebuiltDevToolContentRoute, - restartTransformRoute, } from '../lib/risk_score/routes'; export const initRoutes = ( @@ -161,7 +160,6 @@ export const initRoutes = ( deletePrebuiltSavedObjectsRoute(router, security); getRiskScoreIndexStatusRoute(router); installRiskScoresRoute(router, logger, security); - restartTransformRoute(router, logger); const { previewTelemetryUrlEnabled } = config.experimentalFeatures; if (previewTelemetryUrlEnabled) { // telemetry preview endpoint for e2e integration tests only at the moment. From 0c0079f221258cc3f5fda952dc8de82fdad8098c Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Fri, 4 Nov 2022 13:02:28 +0000 Subject: [PATCH 14/31] [ML] Correcting the size of the free ML node on cloud (#144512) --- x-pack/plugins/ml/common/constants/cloud.ts | 1 + x-pack/plugins/ml/common/license/ml_license.ts | 11 +++++++++++ .../node_available_warning.tsx | 12 ++++++++++-- .../ml/public/application/license/check_license.tsx | 10 ++++++++++ 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/ml/common/constants/cloud.ts b/x-pack/plugins/ml/common/constants/cloud.ts index 0fc6c0234c467..331721712b2e7 100644 --- a/x-pack/plugins/ml/common/constants/cloud.ts +++ b/x-pack/plugins/ml/common/constants/cloud.ts @@ -5,4 +5,5 @@ * 2.0. */ +export const PLATINUM_MAX_RAM_FOR_ML_NODES = '1GB'; export const TRIAL_MAX_RAM_FOR_ML_NODES = '2GB'; diff --git a/x-pack/plugins/ml/common/license/ml_license.ts b/x-pack/plugins/ml/common/license/ml_license.ts index a698b8801ef69..43e61cf7da6b0 100644 --- a/x-pack/plugins/ml/common/license/ml_license.ts +++ b/x-pack/plugins/ml/common/license/ml_license.ts @@ -11,6 +11,7 @@ import { PLUGIN_ID } from '../constants/app'; export const MINIMUM_LICENSE = 'basic'; export const MINIMUM_FULL_LICENSE = 'platinum'; +export const TRIAL_LICENSE = 'trial'; export interface LicenseStatus { isValid: boolean; @@ -26,6 +27,7 @@ export class MlLicense { private _isMlEnabled: boolean = false; private _isMinimumLicense: boolean = false; private _isFullLicense: boolean = false; + private _isTrialLicense: boolean = false; private _initialized: boolean = false; public setup( @@ -41,6 +43,7 @@ export class MlLicense { this._isMlEnabled = this._license.getFeature(PLUGIN_ID).isEnabled; this._isMinimumLicense = isMinimumLicense(this._license); this._isFullLicense = isFullLicense(this._license); + this._isTrialLicense = isTrialLicense(this._license); if (this._initialized === false && postInitFunctions !== undefined) { postInitFunctions.forEach((f) => f(this)); @@ -74,12 +77,20 @@ export class MlLicense { public isFullLicense() { return this._isFullLicense; } + + public isTrialLicense() { + return this._isTrialLicense; + } } export function isFullLicense(license: ILicense) { return license.check(PLUGIN_ID, MINIMUM_FULL_LICENSE).state === 'valid'; } +export function isTrialLicense(license: ILicense) { + return license.check(PLUGIN_ID, TRIAL_LICENSE).state === 'valid'; +} + export function isMinimumLicense(license: ILicense) { return license.check(PLUGIN_ID, MINIMUM_LICENSE).state === 'valid'; } diff --git a/x-pack/plugins/ml/public/application/components/node_available_warning/node_available_warning.tsx b/x-pack/plugins/ml/public/application/components/node_available_warning/node_available_warning.tsx index 5aa3d8aad83c5..c474c20a890fe 100644 --- a/x-pack/plugins/ml/public/application/components/node_available_warning/node_available_warning.tsx +++ b/x-pack/plugins/ml/public/application/components/node_available_warning/node_available_warning.tsx @@ -11,13 +11,21 @@ import { EuiCallOut, EuiLink, EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { mlNodesAvailable, permissionToViewMlNodeCount } from '../../ml_nodes_check'; import { getCloudDeploymentId, isCloud } from '../../services/ml_server_info'; -import { TRIAL_MAX_RAM_FOR_ML_NODES } from '../../../../common/constants/cloud'; +import { + TRIAL_MAX_RAM_FOR_ML_NODES, + PLATINUM_MAX_RAM_FOR_ML_NODES, +} from '../../../../common/constants/cloud'; +import { isTrialLicense } from '../../license/check_license'; export const NodeAvailableWarning: FC = () => { if (mlNodesAvailable() === true || permissionToViewMlNodeCount() === false) { return null; } + const maxRamForMLNodes = isTrialLicense() + ? TRIAL_MAX_RAM_FOR_ML_NODES + : PLATINUM_MAX_RAM_FOR_ML_NODES; + const id = getCloudDeploymentId(); return ( @@ -57,7 +65,7 @@ export const NodeAvailableWarning: FC = () => { /> ), - maxRamForMLNodes: TRIAL_MAX_RAM_FOR_ML_NODES, + maxRamForMLNodes, }} />
diff --git a/x-pack/plugins/ml/public/application/license/check_license.tsx b/x-pack/plugins/ml/public/application/license/check_license.tsx index ddf59ac1d7e5d..1cab46595007c 100644 --- a/x-pack/plugins/ml/public/application/license/check_license.tsx +++ b/x-pack/plugins/ml/public/application/license/check_license.tsx @@ -84,3 +84,13 @@ export function hasLicenseExpired() { export function isFullLicense() { return mlLicense !== null && mlLicense.isFullLicense(); } + +/** + * Check to see if the current license is trial. + * + * @export + * @returns {boolean} + */ +export function isTrialLicense() { + return mlLicense !== null && mlLicense.isTrialLicense(); +} From 3d7a5bb021748a4ea7eaff8f7b0f1b02175d03ee Mon Sep 17 00:00:00 2001 From: Nicolas Chaulet Date: Fri, 4 Nov 2022 09:05:21 -0400 Subject: [PATCH 15/31] [Fleet] Fix fleet server instructions with existing fleet server hosts (#144470) --- .../types/rest_spec/fleet_server_hosts.ts | 4 + .../fleet/cypress/e2e/a11y/home_page.cy.ts | 6 +- .../fleet/cypress/e2e/fleet_settings.cy.ts | 2 + .../fleet/cypress/e2e/fleet_startup.cy.ts | 8 + x-pack/plugins/fleet/cypress/screens/fleet.ts | 1 + .../fleet/cypress/tasks/fleet_server.ts | 8 + .../advanced_tab.tsx | 2 +- .../hooks/use_fleet_server_host.ts | 64 ++++--- .../hooks/use_quick_start_form.ts | 19 +- .../quick_start_tab.tsx | 16 +- .../steps/add_fleet_server_host.tsx | 168 +++++++++++++----- .../steps/get_started.tsx | 161 +++++++++++------ .../use_fleet_server_hosts_for_policy.ts | 9 +- .../hooks/use_request/fleet_server_hosts.ts | 3 +- 14 files changed, 331 insertions(+), 140 deletions(-) diff --git a/x-pack/plugins/fleet/common/types/rest_spec/fleet_server_hosts.ts b/x-pack/plugins/fleet/common/types/rest_spec/fleet_server_hosts.ts index 178e7679947a8..ebd2b42b6c689 100644 --- a/x-pack/plugins/fleet/common/types/rest_spec/fleet_server_hosts.ts +++ b/x-pack/plugins/fleet/common/types/rest_spec/fleet_server_hosts.ts @@ -30,3 +30,7 @@ export interface PostFleetServerHostsRequest { is_default?: boolean; }; } + +export interface PostFleetServerHostsResponse { + item: FleetServerHost; +} diff --git a/x-pack/plugins/fleet/cypress/e2e/a11y/home_page.cy.ts b/x-pack/plugins/fleet/cypress/e2e/a11y/home_page.cy.ts index 12a362ec7581a..a0d65683ecf3e 100644 --- a/x-pack/plugins/fleet/cypress/e2e/a11y/home_page.cy.ts +++ b/x-pack/plugins/fleet/cypress/e2e/a11y/home_page.cy.ts @@ -29,8 +29,10 @@ import { } from '../../screens/fleet'; import { AGENT_POLICY_NAME_LINK } from '../../screens/integrations'; import { cleanupAgentPolicies, unenrollAgent } from '../../tasks/cleanup'; +import { setFleetServerHost } from '../../tasks/fleet_server'; describe('Home page', () => { before(() => { + setFleetServerHost('https://fleetserver:8220'); navigateTo(FLEET); cy.getBySel(LANDING_PAGE_ADD_FLEET_SERVER_BUTTON).click(); }); @@ -38,6 +40,7 @@ describe('Home page', () => { describe('Agents', () => { before(() => { cy.getBySel(AGENT_FLYOUT.QUICK_START_TAB_BUTTON, { timeout: 15000 }).should('be.visible'); + setFleetServerHost('https://fleetserver:8220'); }); const fleetServerHost = 'https://localhost:8220'; @@ -46,6 +49,7 @@ describe('Home page', () => { checkA11y({ skipFailures: false }); }); it('Install Fleet Server', () => { + cy.getBySel(FLEET_SERVER_SETUP.ADD_HOST_BTN).click(); cy.getBySel(FLEET_SERVER_SETUP.NAME_INPUT).type('Host edited'); cy.get('[placeholder="Specify host URL"', { timeout: 15000 }).should('be.visible'); cy.get('[placeholder="Specify host URL"').type(fleetServerHost); @@ -65,13 +69,13 @@ describe('Home page', () => { checkA11y({ skipFailures: false }); }); it('Add your fleet sever host', () => { + cy.getBySel(FLEET_SERVER_SETUP.ADD_HOST_BTN).click(); cy.getBySel(FLEET_SERVER_SETUP.NAME_INPUT).type('New host'); cy.get('[placeholder="Specify host URL"').type('https://localhost:8220'); cy.getBySel(ADVANCED_FLEET_SERVER_ADD_HOST_BUTTON).click(); checkA11y({ skipFailures: false }); }); it('Generate service token', () => { - cy.getBySel(ADVANCED_FLEET_SERVER_ADD_HOST_BUTTON, { timeout: 15000 }).should('be.visible'); cy.getBySel(ADVANCED_FLEET_SERVER_GENERATE_SERVICE_TOKEN_BUTTON).click(); cy.getBySel(PLATFORM_TYPE_LINUX_BUTTON, { timeout: 15000 }) .scrollIntoView() diff --git a/x-pack/plugins/fleet/cypress/e2e/fleet_settings.cy.ts b/x-pack/plugins/fleet/cypress/e2e/fleet_settings.cy.ts index 0c45603a4b2ae..6bdef072fc5f4 100644 --- a/x-pack/plugins/fleet/cypress/e2e/fleet_settings.cy.ts +++ b/x-pack/plugins/fleet/cypress/e2e/fleet_settings.cy.ts @@ -69,6 +69,8 @@ describe('Edit settings', () => { it('should allow to create new Fleet server hosts', () => { cy.getBySel(SETTINGS_FLEET_SERVER_HOSTS.ADD_BUTTON).click(); + cy.getBySel(FLEET_SERVER_SETUP.ADD_HOST_BTN).click(); + cy.getBySel(FLEET_SERVER_SETUP.NAME_INPUT).type('New Host'); cy.getBySel(FLEET_SERVER_SETUP.DEFAULT_SWITCH).click(); cy.get('[placeholder="Specify host URL"').type('https://localhost:8221'); diff --git a/x-pack/plugins/fleet/cypress/e2e/fleet_startup.cy.ts b/x-pack/plugins/fleet/cypress/e2e/fleet_startup.cy.ts index 3960ea060fcc1..d3f71e16b4d3b 100644 --- a/x-pack/plugins/fleet/cypress/e2e/fleet_startup.cy.ts +++ b/x-pack/plugins/fleet/cypress/e2e/fleet_startup.cy.ts @@ -18,6 +18,7 @@ import { } from '../screens/fleet'; import { cleanupAgentPolicies, unenrollAgent } from '../tasks/cleanup'; import { verifyPolicy, verifyAgentPackage, navigateToTab } from '../tasks/fleet'; +import { deleteFleetServer } from '../tasks/fleet_server'; import { FLEET, navigateTo } from '../tasks/navigation'; describe('Fleet startup', () => { @@ -37,6 +38,12 @@ describe('Fleet startup', () => { }); describe('Create policies', () => { + before(() => { + unenrollAgent(); + cleanupAgentPolicies(); + deleteFleetServer(); + }); + after(() => { cleanupAgentPolicies(); }); @@ -104,6 +111,7 @@ describe('Fleet startup', () => { cy.getBySel(AGENT_FLYOUT.POLICY_DROPDOWN); // verify fleet server enroll command contains created policy id + cy.getBySel(FLEET_SERVER_SETUP.ADD_HOST_BTN).click(); cy.getBySel(FLEET_SERVER_SETUP.NAME_INPUT).type('New host'); cy.get('[placeholder="Specify host URL"').type('https://localhost:8220'); diff --git a/x-pack/plugins/fleet/cypress/screens/fleet.ts b/x-pack/plugins/fleet/cypress/screens/fleet.ts index 1248a47778ccb..2b1ad9e8324b4 100644 --- a/x-pack/plugins/fleet/cypress/screens/fleet.ts +++ b/x-pack/plugins/fleet/cypress/screens/fleet.ts @@ -129,4 +129,5 @@ export const FLEET_SERVER_SETUP = { NAME_INPUT: 'fleetServerSetup.nameInput', HOST_INPUT: 'fleetServerSetup.multiRowInput', DEFAULT_SWITCH: 'fleetServerHostsFlyout.isDefaultSwitch', + ADD_HOST_BTN: 'fleetServerSetup.addNewHostBtn', }; diff --git a/x-pack/plugins/fleet/cypress/tasks/fleet_server.ts b/x-pack/plugins/fleet/cypress/tasks/fleet_server.ts index 4a75d535c12f2..8ec8e75c1d13f 100644 --- a/x-pack/plugins/fleet/cypress/tasks/fleet_server.ts +++ b/x-pack/plugins/fleet/cypress/tasks/fleet_server.ts @@ -49,6 +49,14 @@ export function setupFleetServer() { }); } +export function deleteFleetServer() { + cy.task('deleteDocsByQuery', { + index: '.fleet-servers', + query: { match_all: {} }, + ignoreUnavailable: true, + }); +} + export function setFleetServerHost(host = 'https://fleetserver:8220') { cy.request({ method: 'POST', diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/advanced_tab.tsx b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/advanced_tab.tsx index c0d0cec2fb5a2..a471e57e70bba 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/advanced_tab.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/advanced_tab.tsx @@ -58,7 +58,7 @@ export const AdvancedTab: React.FunctionComponent = ({ selecte serviceToken, generateServiceToken, isLoadingServiceToken, - disabled: !Boolean(fleetServerHostForm.isFleetServerHostSubmitted), + disabled: Boolean(!fleetServerHostForm.fleetServerHost), }), getInstallFleetServerStep({ isFleetServerReady, diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/hooks/use_fleet_server_host.ts b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/hooks/use_fleet_server_host.ts index 7dfd6bb1faf60..aa7992f03e16e 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/hooks/use_fleet_server_host.ts +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/hooks/use_fleet_server_host.ts @@ -4,9 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { useCallback, useState } from 'react'; - -import { intersection } from 'lodash'; +import { useCallback, useEffect, useState, useMemo } from 'react'; import { sendPostFleetServerHost, @@ -23,10 +21,11 @@ import { } from '../../../sections/settings/components/fleet_server_hosts_flyout/use_fleet_server_host_form'; export interface FleetServerHostForm { - saveFleetServerHost: (host: FleetServerHost) => Promise; - fleetServerHost?: FleetServerHost; + fleetServerHosts: FleetServerHost[]; + saveFleetServerHost: (host: Omit) => Promise; isFleetServerHostSubmitted: boolean; - setFleetServerHost: React.Dispatch>; + fleetServerHost?: FleetServerHost | null; + setFleetServerHost: React.Dispatch>; validate: () => boolean; error?: string; inputs: { @@ -37,7 +36,7 @@ export interface FleetServerHostForm { } export const useFleetServerHost = (): FleetServerHostForm => { - const [fleetServerHost, setFleetServerHost] = useState(); + const [fleetServerHost, setFleetServerHost] = useState(); const [isFleetServerHostSubmitted, setIsFleetServerHostSubmitted] = useState(false); const isPreconfigured = fleetServerHost?.is_preconfigured ?? false; @@ -59,39 +58,46 @@ export const useFleetServerHost = (): FleetServerHostForm => { [hostUrlsInput, nameInput] ); - const { data } = useGetFleetServerHosts(); + const { data, resendRequest: refreshGetFleetServerHosts } = useGetFleetServerHosts(); + + const fleetServerHosts = useMemo(() => data?.items ?? [], [data?.items]); + + useEffect(() => { + const defaultHost = fleetServerHosts.find((item) => item.is_default === true); + if (defaultHost) { + setFleetServerHost(defaultHost); + } else { + setFleetServerHost(null); + } + }, [fleetServerHosts]); const saveFleetServerHost = useCallback( - async (newFleetServerHost: FleetServerHost) => { + async (newFleetServerHost: Omit) => { setIsFleetServerHostSubmitted(false); - setFleetServerHost(newFleetServerHost); - const fleetServerHostExists = data?.items.reduce((acc, curr) => { - const hostsIntersection = intersection(curr.host_urls, newFleetServerHost?.host_urls); - return hostsIntersection.length > 0 || acc; - }, false); - - // If the Fleet Server host provided already exists in settings, don't submit it - if (fleetServerHostExists) { - setIsFleetServerHostSubmitted(true); - return; + const res = await sendPostFleetServerHost({ + name: newFleetServerHost?.name, + host_urls: newFleetServerHost?.host_urls, + is_default: newFleetServerHost?.is_default, + }); + if (res.error) { + throw res.error; } - if (newFleetServerHost) { - const res = await sendPostFleetServerHost({ - name: newFleetServerHost?.name, - host_urls: newFleetServerHost?.host_urls, - is_default: newFleetServerHost?.is_default, - }); - if (res.error) { - throw res.error; - } + if (!res.data) { + throw new Error('No data'); } + + await refreshGetFleetServerHosts(); setIsFleetServerHostSubmitted(true); + setFleetServerHost(res.data.item); + + return res.data.item; }, - [data?.items] + [refreshGetFleetServerHosts] ); return { + fleetServerHosts, saveFleetServerHost, fleetServerHost, isFleetServerHostSubmitted, diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/hooks/use_quick_start_form.ts b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/hooks/use_quick_start_form.ts index ed893e5d06d65..eb3404febfeec 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/hooks/use_quick_start_form.ts +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/hooks/use_quick_start_form.ts @@ -33,9 +33,11 @@ export type QuickStartCreateFormStatus = 'initial' | 'loading' | 'error' | 'succ export interface QuickStartCreateForm { status: QuickStartCreateFormStatus; + fleetServerHosts: FleetServerHost[]; error?: string; submit: () => void; - fleetServerHost?: FleetServerHost; + setFleetServerHost: React.Dispatch>; + fleetServerHost?: FleetServerHost | null; isFleetServerHostSubmitted: boolean; fleetServerPolicyId?: string; serviceToken?: string; @@ -57,6 +59,7 @@ export const useQuickStartCreateForm = (): QuickStartCreateForm => { const [error, setError] = useState(); const { + fleetServerHosts, fleetServerHost, isFleetServerHostSubmitted, saveFleetServerHost, @@ -79,18 +82,21 @@ export const useQuickStartCreateForm = (): QuickStartCreateForm => { const submit = useCallback(async () => { try { - if (validate()) { + if ((!fleetServerHost && validate()) || fleetServerHost) { setStatus('loading'); const newFleetServerHost = { name: inputs.nameInput.value, host_urls: inputs.hostUrlsInput.value, is_default: inputs.isDefaultInput.value, - id: 'fleet-server-host', is_preconfigured: false, }; - setFleetServerHost(newFleetServerHost); - await saveFleetServerHost(newFleetServerHost); + + if (!fleetServerHost) { + const res = await saveFleetServerHost(newFleetServerHost); + setFleetServerHost(res); + } + await generateServiceToken(); const existingPolicy = await sendGetOneAgentPolicy( @@ -124,6 +130,7 @@ export const useQuickStartCreateForm = (): QuickStartCreateForm => { } }, [ validate, + fleetServerHost, inputs.nameInput.value, inputs.hostUrlsInput.value, inputs.isDefaultInput.value, @@ -139,7 +146,9 @@ export const useQuickStartCreateForm = (): QuickStartCreateForm => { error, submit, fleetServerPolicyId, + fleetServerHosts, fleetServerHost, + setFleetServerHost, isFleetServerHostSubmitted, serviceToken, inputs, diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/quick_start_tab.tsx b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/quick_start_tab.tsx index d6e28a684f302..1ae9f22b304d0 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/quick_start_tab.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/quick_start_tab.tsx @@ -17,13 +17,25 @@ import { } from './steps'; export const QuickStartTab: React.FunctionComponent = () => { - const { fleetServerHost, fleetServerPolicyId, serviceToken, status, error, submit, inputs } = - useQuickStartCreateForm(); + const { + fleetServerHost, + setFleetServerHost, + fleetServerHosts, + fleetServerPolicyId, + serviceToken, + status, + error, + submit, + inputs, + } = useQuickStartCreateForm(); + const { isFleetServerReady } = useWaitForFleetServer(); const steps = [ getGettingStartedStep({ + fleetServerHosts, fleetServerHost, + setFleetServerHost, fleetServerPolicyId, serviceToken, status, diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/add_fleet_server_host.tsx b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/add_fleet_server_host.tsx index b4f4a6d9e0826..0b5369b2b769c 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/add_fleet_server_host.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/add_fleet_server_host.tsx @@ -5,8 +5,10 @@ * 2.0. */ -import React, { useState, useCallback } from 'react'; +import React, { useState, useCallback, useMemo } from 'react'; + import type { EuiStepProps } from '@elastic/eui'; +import { EuiSelect, EuiSwitch } from '@elastic/eui'; import { EuiButton, EuiCallOut, @@ -18,6 +20,7 @@ import { EuiText, EuiFormRow, EuiFieldText, + EuiButtonEmpty, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -51,13 +54,32 @@ export const AddFleetServerHostStepContent = ({ }: { fleetServerHostForm: FleetServerHostForm; }) => { - const { setFleetServerHost, saveFleetServerHost, error, validate, inputs } = fleetServerHostForm; + const { + setFleetServerHost, + fleetServerHost: selectedFleetServerHost, + saveFleetServerHost, + fleetServerHosts, + error, + validate, + inputs, + } = fleetServerHostForm; const [isLoading, setIsLoading] = useState(false); const [submittedFleetServerHost, setSubmittedFleetServerHost] = useState(); const { notifications } = useStartServices(); const { getHref } = useLink(); + const fleetServerHostsOptions = useMemo( + () => + fleetServerHosts.map((fleetServerHost) => { + return { + text: fleetServerHost.name, + value: fleetServerHost.id, + }; + }), + [fleetServerHosts] + ); + const onSubmit = useCallback(async () => { try { setSubmittedFleetServerHost(undefined); @@ -72,8 +94,8 @@ export const AddFleetServerHostStepContent = ({ }; setFleetServerHost(newFleetServerHost); if (validate()) { - await saveFleetServerHost(newFleetServerHost); setSubmittedFleetServerHost(newFleetServerHost); + setFleetServerHost(await saveFleetServerHost(newFleetServerHost)); } } catch (err) { notifications.toasts.addError(err, { @@ -103,52 +125,108 @@ export const AddFleetServerHostStepContent = ({ /> - 0 ? ( + <> + + + + } + append={ + setFleetServerHost(null)} + > + + + } + onChange={(e) => + setFleetServerHost( + fleetServerHosts.find((fleetServerHost) => fleetServerHost.id === e.target.value) + ) + } + options={fleetServerHostsOptions} /> - } - {...inputs.nameInput.formRowProps} - > - - - - } - > + + + ) : null} + {!selectedFleetServerHost ? ( <> - + } + {...inputs.nameInput.formRowProps} + > + + + + } + > + <> + + {error && {error}} + + + + } - )} - /> - {error && {error}} + /> + + + + - - - - - + ) : null} {submittedFleetServerHost && ( <> diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/get_started.tsx b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/get_started.tsx index 26b149bdfa2de..321de1da5b0a3 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/get_started.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/components/fleet_server_instructions/steps/get_started.tsx @@ -5,9 +5,10 @@ * 2.0. */ -import React from 'react'; +import React, { useMemo } from 'react'; import type { EuiStepProps } from '@elastic/eui'; +import { EuiSelect, EuiButtonEmpty } from '@elastic/eui'; import { EuiButton, EuiCallOut, @@ -41,7 +42,9 @@ export function getGettingStartedStep(props: QuickStartCreateForm): EuiStepProps } const GettingStartedStepContent: React.FunctionComponent = ({ - fleetServerHost, + fleetServerHosts, + fleetServerHost: selectedFleetServerHost, + setFleetServerHost, status, error, inputs, @@ -49,6 +52,17 @@ const GettingStartedStepContent: React.FunctionComponent = }) => { const { getHref } = useLink(); + const fleetServerHostsOptions = useMemo( + () => + fleetServerHosts.map((fleetServerHost) => { + return { + text: fleetServerHost.name, + value: fleetServerHost.id, + }; + }), + [fleetServerHosts] + ); + if (status === 'success') { return ( = id="xpack.fleet.fleetServerFlyout.generateFleetServerPolicySuccessInstructions" defaultMessage="Fleet server policy and service token have been generated. Host configured at {hostUrl}. You can edit your Fleet Server hosts in {fleetSettingsLink}." values={{ - hostUrl: {fleetServerHost?.host_urls[0]}, + hostUrl: {selectedFleetServerHost?.host_urls[0]}, fleetSettingsLink: ( = - - - - } - {...inputs.nameInput.formRowProps} - > - 0 ? ( + <> + + + + } + append={ + setFleetServerHost(null)} + > + + + } + onChange={(e) => + setFleetServerHost( + fleetServerHosts.find((fleetServerHost) => fleetServerHost.id === e.target.value) + ) + } + options={fleetServerHostsOptions} /> - - - } - > + + + ) : null} + + + {!selectedFleetServerHost ? ( <> - + } + {...inputs.nameInput.formRowProps} + > + + + + } + > + <> + + {status === 'error' && {error}} + + + + } - )} - /> - {status === 'error' && {error}} - - - - - } - /> - - - + + + + ) : null} fleetServerHostsRequest.data?.items ?? [], + [fleetServerHostsRequest] + ); + return useMemo( - () => ({ isLoadingInitialRequest, fleetServerHosts }), - [fleetServerHosts, isLoadingInitialRequest] + () => ({ isLoadingInitialRequest, fleetServerHosts, allFleetServerHosts }), + [fleetServerHosts, allFleetServerHosts, isLoadingInitialRequest] ); } diff --git a/x-pack/plugins/fleet/public/hooks/use_request/fleet_server_hosts.ts b/x-pack/plugins/fleet/public/hooks/use_request/fleet_server_hosts.ts index 662e0494e20e5..f066da66dba12 100644 --- a/x-pack/plugins/fleet/public/hooks/use_request/fleet_server_hosts.ts +++ b/x-pack/plugins/fleet/public/hooks/use_request/fleet_server_hosts.ts @@ -10,6 +10,7 @@ import type { GetFleetServerHostsResponse, PostFleetServerHostsRequest, PutFleetServerHostsRequest, + PostFleetServerHostsResponse, } from '../../../common/types/rest_spec/fleet_server_hosts'; import { sendRequest, useRequest } from './use_request'; @@ -37,7 +38,7 @@ export function sendPutFleetServerHost(itemId: string, body: PutFleetServerHosts } export function sendPostFleetServerHost(body: PostFleetServerHostsRequest['body']) { - return sendRequest({ + return sendRequest({ method: 'post', path: fleetServerHostsRoutesService.getCreatePath(), body, From cb2f4ba9d9b27c420b71c33aea96f9f6fd177597 Mon Sep 17 00:00:00 2001 From: Julia Bardi <90178898+juliaElastic@users.noreply.github.com> Date: Fri, 4 Nov 2022 14:17:30 +0100 Subject: [PATCH 16/31] fix issue with single agent schedule upgrade (#144604) --- .../components/agent_upgrade_modal/index.tsx | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_upgrade_modal/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_upgrade_modal/index.tsx index d7d376e83e316..7bb890dff81a8 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_upgrade_modal/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_upgrade_modal/index.tsx @@ -162,15 +162,16 @@ export const AgentUpgradeAgentModal: React.FunctionComponent agent.id) : agents, - ...rolloutOptions, - }); + const { error } = + isSingleAgent && !isScheduled + ? await sendPostAgentUpgrade((agents[0] as Agent).id, { + version, + }) + : await sendPostBulkAgentUpgrade({ + version, + agents: Array.isArray(agents) ? agents.map((agent) => agent.id) : agents, + ...rolloutOptions, + }); if (error) { if (error?.statusCode === 400) { setErrors(error?.message); From 3b59a90671b6738c81ccc2952970cc4db117630f Mon Sep 17 00:00:00 2001 From: Ying Mao Date: Fri, 4 Nov 2022 09:20:54 -0400 Subject: [PATCH 17/31] [Response Ops][Alerting] Removing top level rule fields passed into executors (#144270) * Removing top level fields passed into executors * Updating stack rules * Updating other rules * Fixing types * Fixing functional test Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- x-pack/plugins/alerting/README.md | 6 +---- x-pack/plugins/alerting/common/rule.ts | 1 + .../server/task_runner/task_runner.test.ts | 10 ++------ .../server/task_runner/task_runner.ts | 6 +---- x-pack/plugins/alerting/server/types.ts | 5 ---- .../inventory_metric_threshold_executor.ts | 7 ++++-- .../metric_threshold_executor.test.ts | 6 +---- .../metric_threshold_executor.ts | 15 ++++++++++-- .../register_anomaly_detection_alert_type.ts | 2 +- .../register_jobs_monitoring_rule_type.ts | 5 +++- .../server/utils/create_lifecycle_executor.ts | 8 +------ .../utils/create_lifecycle_rule_type.test.ts | 6 +---- .../server/utils/get_common_alert_fields.ts | 4 ++-- .../utils/rule_executor.test_helpers.ts | 8 ++----- ...gacy_rules_notification_alert_type.test.ts | 6 +---- .../legacy_rules_notification_alert_type.ts | 13 +++++++--- .../rule_preview/api/preview_rules/route.ts | 6 +---- .../rule_schema/model/rule_schemas.mock.ts | 1 + .../create_security_rule_type_wrapper.ts | 20 +++++++--------- .../es_query/action_context.test.ts | 6 ++--- .../alert_types/es_query/action_context.ts | 11 ++++----- .../server/alert_types/es_query/executor.ts | 13 +++++++--- .../alert_types/es_query/rule_type.test.ts | 6 +---- .../geo_containment/geo_containment.ts | 6 ++--- .../tests/geo_containment.test.ts | 22 +++++++++++++---- .../index_threshold/action_context.test.ts | 8 +++---- .../index_threshold/action_context.ts | 15 +++++------- .../index_threshold/rule_type.test.ts | 24 ++++--------------- .../alert_types/index_threshold/rule_type.ts | 11 ++++++--- .../plugins/alerts/server/alert_types.ts | 16 ++----------- .../group2/tests/alerting/alerts.ts | 6 ++--- .../spaces_only/tests/alerting/alerts_base.ts | 2 +- 32 files changed, 123 insertions(+), 158 deletions(-) diff --git a/x-pack/plugins/alerting/README.md b/x-pack/plugins/alerting/README.md index ffe17b91b8aeb..b0d1cb19b0ccb 100644 --- a/x-pack/plugins/alerting/README.md +++ b/x-pack/plugins/alerting/README.md @@ -120,13 +120,9 @@ This is the primary function for a rule type. Whenever the rule needs to execute |previousStartedAt|The previous date and time the rule type started a successful execution.| |params|Parameters for the execution. This is where the parameters you require will be passed in. (e.g. threshold). Use rule type validation to ensure values are set before execution.| |state|State returned from the previous execution. This is the rule level state. What the executor returns will be serialized and provided here at the next execution.| -|alertId|The id of this rule.| |spaceId|The id of the space of this rule.| |namespace|The namespace of the space of this rule. This is the same as `spaceId`, unless `spaceId === "default"`, in which case the namespace = `undefined`.| -|name|The name of this rule. This will eventually be removed in favor of `rule.name`.| -|tags|The tags associated with this rule. This will eventually be removed in favor of `rule.tags`.| -|createdBy|The user ID of the user that created this rule. This will eventually be removed in favor of `rule.createdBy`.| -|updatedBy|The user ID of the user that last updated this rule. This will eventually be removed in favor of `rule.updatedBy`.| +|rule.id|The id of this rule.| |rule.name|The name of this rule.| |rule.tags|The tags associated with this rule.| |rule.consumer|The consumer of this rule type.| diff --git a/x-pack/plugins/alerting/common/rule.ts b/x-pack/plugins/alerting/common/rule.ts index c6c598cf8aebc..56fcaa8832792 100644 --- a/x-pack/plugins/alerting/common/rule.ts +++ b/x-pack/plugins/alerting/common/rule.ts @@ -124,6 +124,7 @@ export type ResolvedSanitizedRule = Sanit export type SanitizedRuleConfig = Pick< SanitizedRule, + | 'id' | 'name' | 'tags' | 'consumer' diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts b/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts index 20310fdae01f7..3d3c82d91fe28 100644 --- a/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts +++ b/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts @@ -231,11 +231,8 @@ describe('Task Runner', () => { expect(call.startedAt).toStrictEqual(new Date(DATE_1970)); expect(call.previousStartedAt).toStrictEqual(new Date(DATE_1970_5_MIN)); expect(call.state).toEqual({}); - expect(call.name).toBe(RULE_NAME); - expect(call.tags).toEqual(['rule-', '-tags']); - expect(call.createdBy).toBe('rule-creator'); - expect(call.updatedBy).toBe('rule-updater'); expect(call.rule).not.toBe(null); + expect(call.rule.id).toBe('1'); expect(call.rule.name).toBe(RULE_NAME); expect(call.rule.tags).toEqual(['rule-', '-tags']); expect(call.rule.consumer).toBe('bar'); @@ -2059,11 +2056,8 @@ describe('Task Runner', () => { expect(call.startedAt).toEqual(new Date(DATE_1970)); expect(call.previousStartedAt).toEqual(new Date(DATE_1970_5_MIN)); expect(call.state).toEqual({}); - expect(call.name).toBe(RULE_NAME); - expect(call.tags).toEqual(['rule-', '-tags']); - expect(call.createdBy).toBe('rule-creator'); - expect(call.updatedBy).toBe('rule-updater'); expect(call.rule).not.toBe(null); + expect(call.rule.id).toBe('1'); expect(call.rule.name).toBe(RULE_NAME); expect(call.rule.tags).toEqual(['rule-', '-tags']); expect(call.rule.consumer).toBe('bar'); diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner.ts b/x-pack/plugins/alerting/server/task_runner/task_runner.ts index 0c6bbfbbd9866..fe8fcbb73152a 100644 --- a/x-pack/plugins/alerting/server/task_runner/task_runner.ts +++ b/x-pack/plugins/alerting/server/task_runner/task_runner.ts @@ -355,7 +355,6 @@ export class TaskRunner< updatedState = await this.context.executionContext.withContext(ctx, () => this.ruleType.executor({ - alertId: ruleId, executionId: this.executionId, services: { savedObjectsClient, @@ -372,11 +371,8 @@ export class TaskRunner< previousStartedAt: previousStartedAt ? new Date(previousStartedAt) : null, spaceId, namespace, - name, - tags, - createdBy, - updatedBy, rule: { + id: ruleId, name, tags, consumer, diff --git a/x-pack/plugins/alerting/server/types.ts b/x-pack/plugins/alerting/server/types.ts index 9326f30dd7828..288e0a353d0c0 100644 --- a/x-pack/plugins/alerting/server/types.ts +++ b/x-pack/plugins/alerting/server/types.ts @@ -90,11 +90,8 @@ export interface RuleExecutorOptions< InstanceContext extends AlertInstanceContext = never, ActionGroupIds extends string = never > { - alertId: string; // Is actually the Rule ID. Will be updated as part of https://github.com/elastic/kibana/issues/100115 - createdBy: string | null; executionId: string; logger: Logger; - name: string; params: Params; previousStartedAt: Date | null; rule: SanitizedRuleConfig; @@ -102,8 +99,6 @@ export interface RuleExecutorOptions< spaceId: string; startedAt: Date; state: State; - tags: string[]; - updatedBy: string | null; namespace?: string; } diff --git a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts index 20b804a2cc7db..4a5fe10081355 100644 --- a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts +++ b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts @@ -66,14 +66,17 @@ export const createInventoryMetricThresholdExecutor = (libs: InfraBackendLibs) = InventoryMetricThresholdAlertState, InventoryMetricThresholdAlertContext, InventoryMetricThresholdAllowedActionGroups - >(async ({ services, params, alertId, executionId, spaceId, startedAt }) => { + >(async ({ services, params, executionId, spaceId, startedAt, rule: { id: ruleId } }) => { const startTime = Date.now(); const { criteria, filterQuery, sourceId = 'default', nodeType, alertOnNoData } = params; if (criteria.length === 0) throw new Error('Cannot execute an alert with 0 conditions'); - const logger = createScopedLogger(libs.logger, 'inventoryRule', { alertId, executionId }); + const logger = createScopedLogger(libs.logger, 'inventoryRule', { + alertId: ruleId, + executionId, + }); const esClient = services.scopedClusterClient.asCurrentUser; diff --git a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.test.ts b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.test.ts index d56984da1c85c..a9f8ce56c441f 100644 --- a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.test.ts +++ b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.test.ts @@ -69,7 +69,6 @@ const logger = { } as unknown as Logger; const mockOptions = { - alertId: '', executionId: '', startedAt: new Date(), previousStartedAt: null, @@ -89,11 +88,8 @@ const mockOptions = { }, }, spaceId: '', - name: '', - tags: [], - createdBy: null, - updatedBy: null, rule: { + id: '', name: '', tags: [], consumer: '', diff --git a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts index a6fdbe3aa801c..6c3a5f2378b6f 100644 --- a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts +++ b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts @@ -74,12 +74,23 @@ export const createMetricThresholdExecutor = (libs: InfraBackendLibs) => >(async function (options) { const startTime = Date.now(); - const { services, params, state, startedAt, alertId, executionId, spaceId } = options; + const { + services, + params, + state, + startedAt, + executionId, + spaceId, + rule: { id: ruleId }, + } = options; const { criteria } = params; if (criteria.length === 0) throw new Error('Cannot execute an alert with 0 conditions'); - const logger = createScopedLogger(libs.logger, 'metricThresholdRule', { alertId, executionId }); + const logger = createScopedLogger(libs.logger, 'metricThresholdRule', { + alertId: ruleId, + executionId, + }); const { alertWithLifecycle, savedObjectsClient, getAlertUuid } = services; diff --git a/x-pack/plugins/ml/server/lib/alerts/register_anomaly_detection_alert_type.ts b/x-pack/plugins/ml/server/lib/alerts/register_anomaly_detection_alert_type.ts index 7aa81e7668c0f..442267c2c98d8 100644 --- a/x-pack/plugins/ml/server/lib/alerts/register_anomaly_detection_alert_type.ts +++ b/x-pack/plugins/ml/server/lib/alerts/register_anomaly_detection_alert_type.ts @@ -137,7 +137,7 @@ export function registerAnomalyDetectionAlertType({ minimumLicenseRequired: MINIMUM_FULL_LICENSE, isExportable: true, doesSetRecoveryContext: true, - async executor({ services, params, alertId, state, previousStartedAt, startedAt, name }) { + async executor({ services, params }) { const fakeRequest = {} as KibanaRequest; const { execute } = mlSharedServices.alertingServiceProvider( services.savedObjectsClient, diff --git a/x-pack/plugins/ml/server/lib/alerts/register_jobs_monitoring_rule_type.ts b/x-pack/plugins/ml/server/lib/alerts/register_jobs_monitoring_rule_type.ts index 7ea087e1239a6..5c75cec536944 100644 --- a/x-pack/plugins/ml/server/lib/alerts/register_jobs_monitoring_rule_type.ts +++ b/x-pack/plugins/ml/server/lib/alerts/register_jobs_monitoring_rule_type.ts @@ -142,7 +142,10 @@ export function registerJobsMonitoringRuleType({ isExportable: true, doesSetRecoveryContext: true, async executor(options) { - const { services, name } = options; + const { + services, + rule: { name }, + } = options; const fakeRequest = {} as KibanaRequest; const { getTestsResults } = mlServicesProviders.jobsHealthServiceProvider( diff --git a/x-pack/plugins/rule_registry/server/utils/create_lifecycle_executor.ts b/x-pack/plugins/rule_registry/server/utils/create_lifecycle_executor.ts index 615201fe44d99..abf5ec53b537c 100644 --- a/x-pack/plugins/rule_registry/server/utils/create_lifecycle_executor.ts +++ b/x-pack/plugins/rule_registry/server/utils/create_lifecycle_executor.ts @@ -89,12 +89,6 @@ export type LifecycleRuleExecutor< > ) => Promise; -/* - `alertId` will at some point be renamed to `ruleId` as that more - accurately describes the meaning of the variable. - See https://github.com/elastic/kibana/issues/100115 -*/ - const trackedAlertStateRt = rt.type({ alertId: rt.string, alertUuid: rt.string, @@ -269,7 +263,7 @@ export const createLifecycleExecutor = [ALERT_WORKFLOW_STATUS]: alertData?.fields[ALERT_WORKFLOW_STATUS] ?? 'open', [EVENT_KIND]: 'signal', [EVENT_ACTION]: isNew ? 'open' : isActive ? 'active' : 'close', - [TAGS]: options.tags, + [TAGS]: options.rule.tags, [VERSION]: ruleDataClient.kibanaVersion, ...(isRecovered ? { [ALERT_END]: commonRuleFields[TIMESTAMP] } : {}), }; diff --git a/x-pack/plugins/rule_registry/server/utils/create_lifecycle_rule_type.test.ts b/x-pack/plugins/rule_registry/server/utils/create_lifecycle_rule_type.test.ts index 132eb096e0aaa..74f79751dd57b 100644 --- a/x-pack/plugins/rule_registry/server/utils/create_lifecycle_rule_type.test.ts +++ b/x-pack/plugins/rule_registry/server/utils/create_lifecycle_rule_type.test.ts @@ -95,15 +95,13 @@ function createRule(shouldWriteAlerts: boolean = true) { scheduleActions.mockClear(); state = ((await type.executor({ - alertId: 'alertId', - createdBy: 'createdBy', executionId: 'b33f65d7-6e8b-4aae-8d20-c93613dec9f9', logger: loggerMock.create(), - name: 'name', namespace: 'namespace', params: {}, previousStartedAt, rule: { + id: 'alertId', actions: [], consumer: 'consumer', createdAt, @@ -135,8 +133,6 @@ function createRule(shouldWriteAlerts: boolean = true) { spaceId: 'spaceId', startedAt, state, - tags: ['tags'], - updatedBy: 'updatedBy', })) ?? {}) as Record; previousStartedAt = startedAt; diff --git a/x-pack/plugins/rule_registry/server/utils/get_common_alert_fields.ts b/x-pack/plugins/rule_registry/server/utils/get_common_alert_fields.ts index be611d8e959b2..7401186fa59e7 100644 --- a/x-pack/plugins/rule_registry/server/utils/get_common_alert_fields.ts +++ b/x-pack/plugins/rule_registry/server/utils/get_common_alert_fields.ts @@ -31,9 +31,9 @@ export const getCommonAlertFields = ( [ALERT_RULE_NAME]: options.rule.name, [ALERT_RULE_PRODUCER]: options.rule.producer, [ALERT_RULE_TYPE_ID]: options.rule.ruleTypeId, - [ALERT_RULE_UUID]: options.alertId, + [ALERT_RULE_UUID]: options.rule.id, [SPACE_IDS]: [options.spaceId], - [ALERT_RULE_TAGS]: options.tags, + [ALERT_RULE_TAGS]: options.rule.tags, [TIMESTAMP]: options.startedAt.toISOString(), }; }; diff --git a/x-pack/plugins/rule_registry/server/utils/rule_executor.test_helpers.ts b/x-pack/plugins/rule_registry/server/utils/rule_executor.test_helpers.ts index 4a9ab6652ec6e..70c827942ade3 100644 --- a/x-pack/plugins/rule_registry/server/utils/rule_executor.test_helpers.ts +++ b/x-pack/plugins/rule_registry/server/utils/rule_executor.test_helpers.ts @@ -47,15 +47,13 @@ export const createDefaultAlertExecutorOptions = < updatedAt?: Date; shouldWriteAlerts?: boolean; }): RuleExecutorOptions => ({ - alertId, - createdBy: 'CREATED_BY', startedAt, - name: ruleName, rule: { + id: alertId, updatedBy: null, tags: [], name: ruleName, - createdBy: null, + createdBy: 'CREATED_BY', actions: [], enabled: true, consumer: 'CONSUMER', @@ -68,7 +66,6 @@ export const createDefaultAlertExecutorOptions = < ruleTypeId: 'RULE_TYPE_ID', ruleTypeName: 'RULE_TYPE_NAME', }, - tags: [], params, spaceId: 'SPACE_ID', services: { @@ -82,7 +79,6 @@ export const createDefaultAlertExecutorOptions = < searchSourceClient: searchSourceCommonMock, }, state, - updatedBy: null, previousStartedAt: null, namespace: undefined, executionId: 'b33f65d7-6e8b-4aae-8d20-c93613deb33f', diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_rules_notification_alert_type.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_rules_notification_alert_type.test.ts index ddfca67279074..2ffbde91145c8 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_rules_notification_alert_type.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_rules_notification_alert_type.test.ts @@ -39,19 +39,15 @@ describe('legacyRules_notification_alert_type', () => { logger = loggingSystemMock.createLogger(); payload = { - alertId: '1111', executionId: 'b33f65d7-b33f-4aae-8d20-c93613dec9f9', services: alertServices, params: { ruleAlertId: '2222' }, state: {}, spaceId: '', - name: 'name', - tags: [], startedAt: new Date('2019-12-14T16:40:33.400Z'), previousStartedAt: new Date('2019-12-13T16:40:33.400Z'), - createdBy: 'elastic', - updatedBy: 'elastic', rule: { + id: '1111', name: 'name', tags: [], consumer: 'foo', diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_rules_notification_alert_type.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_rules_notification_alert_type.ts index 7e76c2c1158d2..2bb349f6f070b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_rules_notification_alert_type.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_rules_notification_alert_type.ts @@ -50,7 +50,14 @@ export const legacyRulesNotificationAlertType = ({ }, minimumLicenseRequired: 'basic', isExportable: false, - async executor({ startedAt, previousStartedAt, alertId, services, params, spaceId }) { + async executor({ + startedAt, + previousStartedAt, + rule: { id: ruleId }, + services, + params, + spaceId, + }) { const ruleAlertSavedObject = await services.savedObjectsClient.get( 'alert', params.ruleAlertId @@ -60,7 +67,7 @@ export const legacyRulesNotificationAlertType = ({ logger.error( [ `Security Solution notification (Legacy) saved object for alert ${params.ruleAlertId} was not found with`, - `id: "${alertId}".`, + `id: "${ruleId}".`, `space id: "${spaceId}"`, 'This indicates a dangling (Legacy) notification alert.', 'You should delete this rule through "Kibana UI -> Stack Management -> Rules and Connectors" to remove this error message.', @@ -118,7 +125,7 @@ export const legacyRulesNotificationAlertType = ({ ); if (signalsCount !== 0) { - const alertInstance = services.alertFactory.create(alertId); + const alertInstance = services.alertFactory.create(ruleId); scheduleNotificationActions({ alertInstance, signalsCount, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/route.ts index 5c5094fae4633..01bc55bf12467 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/route.ts @@ -217,6 +217,7 @@ export const previewRulesRoute = async ( const rule = { ...internalRule, + id: previewId, createdAt: new Date(), createdBy: username ?? 'preview-created-by', producer: 'preview-producer', @@ -232,10 +233,7 @@ export const previewRulesRoute = async ( invocationStartTime = moment(); statePreview = (await executor({ - alertId: previewId, - createdBy: rule.createdBy, executionId: uuid.v4(), - name: rule.name, params, previousStartedAt, rule, @@ -257,8 +255,6 @@ export const previewRulesRoute = async ( spaceId, startedAt: startedAt.toDate(), state: statePreview, - tags: [], - updatedBy: rule.updatedBy, logger, })) as TState; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_schema/model/rule_schemas.mock.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_schema/model/rule_schemas.mock.ts index f41494cf5fed4..04cec44000f78 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_schema/model/rule_schemas.mock.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_schema/model/rule_schemas.mock.ts @@ -195,6 +195,7 @@ export const getThreatRuleParams = (): ThreatRuleParams => { }; export const getRuleConfigMock = (type: string = 'rule-type'): SanitizedRuleConfig => ({ + id: sampleRuleGuid, actions: [], enabled: true, name: 'rule-name', diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/create_security_rule_type_wrapper.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/create_security_rule_type_wrapper.ts index fabda51b5602d..8ee773bb91cf7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/create_security_rule_type_wrapper.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/create_security_rule_type_wrapper.ts @@ -62,7 +62,6 @@ export const createSecurityRuleTypeWrapper: CreateSecurityRuleTypeWrapper = agent.setTransactionName(`${options.rule.ruleTypeId} execution`); return withSecuritySpan('securityRuleTypeExecutor', async () => { const { - alertId, executionId, params, previousStartedAt, @@ -70,7 +69,6 @@ export const createSecurityRuleTypeWrapper: CreateSecurityRuleTypeWrapper = services, spaceId, state, - updatedBy: updatedByUser, rule, } = options; let runState = state; @@ -99,7 +97,7 @@ export const createSecurityRuleTypeWrapper: CreateSecurityRuleTypeWrapper = savedObjectsClient, context: { executionId, - ruleId: alertId, + ruleId: rule.id, ruleUuid: params.ruleId, ruleName: rule.name, ruleType: rule.ruleTypeId, @@ -110,7 +108,7 @@ export const createSecurityRuleTypeWrapper: CreateSecurityRuleTypeWrapper = const completeRule = { ruleConfig: rule, ruleParams: params, - alertId, + alertId: rule.id, }; const { @@ -135,7 +133,7 @@ export const createSecurityRuleTypeWrapper: CreateSecurityRuleTypeWrapper = const notificationRuleParams: NotificationRuleTypeParams = { ...params, name, - id: alertId, + id: rule.id, }; const primaryTimestamp = timestampOverride ?? TIMESTAMP; @@ -270,7 +268,7 @@ export const createSecurityRuleTypeWrapper: CreateSecurityRuleTypeWrapper = try { const { listClient, exceptionsClient } = getListClient({ esClient: services.scopedClusterClient.asCurrentUser, - updatedByUser, + updatedByUser: rule.updatedBy, spaceId, lists, savedObjectClient: options.services.savedObjectsClient, @@ -393,7 +391,7 @@ export const createSecurityRuleTypeWrapper: CreateSecurityRuleTypeWrapper = const resultsLink = getNotificationResultsLink({ from: fromInMs, to: toInMs, - id: alertId, + id: rule.id, kibanaSiemAppUrl: (meta as { kibana_siem_app_url?: string } | undefined) ?.kibana_siem_app_url, }); @@ -403,10 +401,10 @@ export const createSecurityRuleTypeWrapper: CreateSecurityRuleTypeWrapper = if (completeRule.ruleConfig.throttle != null) { // NOTE: Since this is throttled we have to call it even on an error condition, otherwise it will "reset" the throttle and fire early await scheduleThrottledNotificationActions({ - alertInstance: services.alertFactory.create(alertId), + alertInstance: services.alertFactory.create(rule.id), throttle: completeRule.ruleConfig.throttle ?? '', startedAt, - id: alertId, + id: rule.id, kibanaSiemAppUrl: (meta as { kibana_siem_app_url?: string } | undefined) ?.kibana_siem_app_url, outputIndex: ruleDataClient.indexNameWithNamespace(spaceId), @@ -417,7 +415,7 @@ export const createSecurityRuleTypeWrapper: CreateSecurityRuleTypeWrapper = logger, }); } else if (createdSignalsCount) { - const alertInstance = services.alertFactory.create(alertId); + const alertInstance = services.alertFactory.create(rule.id); scheduleNotificationActions({ alertInstance, signalsCount: createdSignalsCount, @@ -482,7 +480,7 @@ export const createSecurityRuleTypeWrapper: CreateSecurityRuleTypeWrapper = // NOTE: Since this is throttled we have to call it even on an error condition, otherwise it will "reset" the throttle and fire early if (actions.length && completeRule.ruleConfig.throttle != null) { await scheduleThrottledNotificationActions({ - alertInstance: services.alertFactory.create(alertId), + alertInstance: services.alertFactory.create(rule.id), throttle: completeRule.ruleConfig.throttle ?? '', startedAt, id: completeRule.alertId, diff --git a/x-pack/plugins/stack_alerts/server/alert_types/es_query/action_context.test.ts b/x-pack/plugins/stack_alerts/server/alert_types/es_query/action_context.test.ts index c19d4ed5c3d1f..5aa40290c2f44 100644 --- a/x-pack/plugins/stack_alerts/server/alert_types/es_query/action_context.test.ts +++ b/x-pack/plugins/stack_alerts/server/alert_types/es_query/action_context.test.ts @@ -29,7 +29,7 @@ describe('ActionContext', () => { hits: [], link: 'link-mock', }; - const context = addMessages({ name: '[rule-name]' }, base, params); + const context = addMessages('[rule-name]', base, params); expect(context.title).toMatchInlineSnapshot(`"rule '[rule-name]' matched query"`); expect(context.message).toEqual( `rule '[rule-name]' is active: @@ -60,7 +60,7 @@ describe('ActionContext', () => { hits: [], link: 'link-mock', }; - const context = addMessages({ name: '[rule-name]' }, base, params, true); + const context = addMessages('[rule-name]', base, params, true); expect(context.title).toMatchInlineSnapshot(`"rule '[rule-name]' recovered"`); expect(context.message).toEqual( `rule '[rule-name]' is recovered: @@ -91,7 +91,7 @@ describe('ActionContext', () => { hits: [], link: 'link-mock', }; - const context = addMessages({ name: '[rule-name]' }, base, params); + const context = addMessages('[rule-name]', base, params); expect(context.title).toMatchInlineSnapshot(`"rule '[rule-name]' matched query"`); expect(context.message).toEqual( `rule '[rule-name]' is active: diff --git a/x-pack/plugins/stack_alerts/server/alert_types/es_query/action_context.ts b/x-pack/plugins/stack_alerts/server/alert_types/es_query/action_context.ts index f25b35c6c63d6..1dc5b5422e121 100644 --- a/x-pack/plugins/stack_alerts/server/alert_types/es_query/action_context.ts +++ b/x-pack/plugins/stack_alerts/server/alert_types/es_query/action_context.ts @@ -7,13 +7,10 @@ import { i18n } from '@kbn/i18n'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { RuleExecutorOptions, AlertInstanceContext } from '@kbn/alerting-plugin/server'; +import { AlertInstanceContext } from '@kbn/alerting-plugin/server'; import { OnlyEsQueryRuleParams, OnlySearchSourceRuleParams } from './types'; // rule type context provided to actions - -type RuleInfo = Pick; - export interface ActionContext extends EsQueryRuleActionContext { // a short pre-constructed message which may be used in an action field title: string; @@ -36,7 +33,7 @@ export interface EsQueryRuleActionContext extends AlertInstanceContext { } export function addMessages( - ruleInfo: RuleInfo, + ruleName: string, baseContext: EsQueryRuleActionContext, params: OnlyEsQueryRuleParams | OnlySearchSourceRuleParams, isRecovered: boolean = false @@ -44,7 +41,7 @@ export function addMessages( const title = i18n.translate('xpack.stackAlerts.esQuery.alertTypeContextSubjectTitle', { defaultMessage: `rule '{name}' {verb}`, values: { - name: ruleInfo.name, + name: ruleName, verb: isRecovered ? 'recovered' : 'matched query', }, }); @@ -58,7 +55,7 @@ export function addMessages( - Timestamp: {date} - Link: {link}`, values: { - name: ruleInfo.name, + name: ruleName, value: baseContext.value, conditions: baseContext.conditions, window, diff --git a/x-pack/plugins/stack_alerts/server/alert_types/es_query/executor.ts b/x-pack/plugins/stack_alerts/server/alert_types/es_query/executor.ts index f50368f29ae76..ae110adbfaa5f 100644 --- a/x-pack/plugins/stack_alerts/server/alert_types/es_query/executor.ts +++ b/x-pack/plugins/stack_alerts/server/alert_types/es_query/executor.ts @@ -20,7 +20,14 @@ import { isEsQueryRule } from './util'; export async function executor(core: CoreSetup, options: ExecutorOptions) { const esQueryRule = isEsQueryRule(options.params.searchType); - const { alertId: ruleId, name, services, params, state, spaceId, logger } = options; + const { + rule: { id: ruleId, name }, + services, + params, + state, + spaceId, + logger, + } = options; const { alertFactory, scopedClusterClient, searchSourceClient } = services; const currentTimestamp = new Date().toISOString(); const publicBaseUrl = core.http.basePath.publicBaseUrl ?? ''; @@ -75,7 +82,7 @@ export async function executor(core: CoreSetup, options: ExecutorOptions { @@ -155,7 +155,7 @@ export const getGeoContainmentExecutor = (): GeoContainmentAlertType['executor'] params.geoField, services.scopedClusterClient.asCurrentUser, logger, - alertId, + ruleId, params.boundaryNameField, params.boundaryIndexQuery ); @@ -170,7 +170,7 @@ export const getGeoContainmentExecutor = (): GeoContainmentAlertType['executor'] // Start collecting data only on the first cycle let currentIntervalResults: estypes.SearchResponse | undefined; if (!windowStart) { - logger.debug(`alert ${GEO_CONTAINMENT_ID}:${alertId} alert initialized. Collecting data`); + logger.debug(`alert ${GEO_CONTAINMENT_ID}:${ruleId} alert initialized. Collecting data`); // Consider making first time window configurable? const START_TIME_WINDOW = 1; const tempPreviousEndTime = new Date(windowEnd); diff --git a/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/tests/geo_containment.test.ts b/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/tests/geo_containment.test.ts index e4d4e49036f4e..fe7ed6c1cf424 100644 --- a/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/tests/geo_containment.test.ts +++ b/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/tests/geo_containment.test.ts @@ -518,7 +518,7 @@ describe('geo_containment', () => { boundaryIndexId: 'testBoundaryIndexId', boundaryGeoField: 'testBoundaryGeoField', }; - const alertId = 'testAlertId'; + const ruleId = 'testAlertId'; const geoContainmentState = { shapesFilters: { testShape: 'thisIsAShape', @@ -567,7 +567,10 @@ describe('geo_containment', () => { // @ts-ignore services: alertServicesWithSearchMock, params: geoContainmentParams, - alertId, + // @ts-ignore + rule: { + id: ruleId, + }, // @ts-ignore state: {}, }); @@ -587,7 +590,10 @@ describe('geo_containment', () => { // @ts-ignore services: alertServicesWithSearchMock, params: geoContainmentParams, - alertId, + // @ts-ignore + rule: { + id: ruleId, + }, state: geoContainmentState, }); if (executionResult && executionResult.shapesFilters) { @@ -606,7 +612,10 @@ describe('geo_containment', () => { // @ts-ignore services: alertServicesWithSearchMock, params: geoContainmentParams, - alertId, + // @ts-ignore + rule: { + id: ruleId, + }, state: geoContainmentState, }); if (executionResult && executionResult.shapesFilters) { @@ -642,7 +651,10 @@ describe('geo_containment', () => { // @ts-ignore services: alertServicesWithSearchMock, params: geoContainmentParams, - alertId, + // @ts-ignore + rule: { + id: ruleId, + }, state: geoContainmentState, }); if (executionResult && executionResult.prevLocationMap) { diff --git a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/action_context.test.ts b/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/action_context.test.ts index 0df74bb2f89c5..ce1bcb035c778 100644 --- a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/action_context.test.ts +++ b/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/action_context.test.ts @@ -28,7 +28,7 @@ describe('ActionContext', () => { value: 42, conditions: 'count greater than 4', }; - const context = addMessages({ name: '[rule-name]' }, base, params); + const context = addMessages('[rule-name]', base, params); expect(context.title).toMatchInlineSnapshot(`"alert [rule-name] group [group] met threshold"`); expect(context.message).toEqual( `alert '[rule-name]' is active for group '[group]': @@ -59,7 +59,7 @@ describe('ActionContext', () => { value: 42, conditions: 'avg([aggField]) greater than 4.2', }; - const context = addMessages({ name: '[rule-name]' }, base, params); + const context = addMessages('[rule-name]', base, params); expect(context.title).toMatchInlineSnapshot(`"alert [rule-name] group [group] met threshold"`); expect(context.message).toEqual( `alert '[rule-name]' is active for group '[group]': @@ -89,7 +89,7 @@ describe('ActionContext', () => { value: 4, conditions: 'count between 4 and 5', }; - const context = addMessages({ name: '[rule-name]' }, base, params); + const context = addMessages('[rule-name]', base, params); expect(context.title).toMatchInlineSnapshot(`"alert [rule-name] group [group] met threshold"`); expect(context.message).toEqual( `alert '[rule-name]' is active for group '[group]': @@ -119,7 +119,7 @@ describe('ActionContext', () => { value: 'unknown', conditions: 'count between 4 and 5', }; - const context = addMessages({ name: '[rule-name]' }, base, params); + const context = addMessages('[rule-name]', base, params); expect(context.title).toMatchInlineSnapshot(`"alert [rule-name] group [group] met threshold"`); expect(context.message).toEqual( `alert '[rule-name]' is active for group '[group]': diff --git a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/action_context.ts b/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/action_context.ts index 36ed27d8a7391..83cac7ada57f4 100644 --- a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/action_context.ts +++ b/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/action_context.ts @@ -6,13 +6,10 @@ */ import { i18n } from '@kbn/i18n'; -import { RuleExecutorOptions, AlertInstanceContext } from '@kbn/alerting-plugin/server'; +import { AlertInstanceContext } from '@kbn/alerting-plugin/server'; import { Params } from './rule_type_params'; // rule type context provided to actions - -type RuleInfo = Pick; - export interface ActionContext extends BaseActionContext { // a short pre-constructed message which may be used in an action field title: string; @@ -79,20 +76,20 @@ const RECOVERY_MESSAGE = (name: string, context: BaseActionContext, window: stri }); export function addMessages( - ruleInfo: RuleInfo, + ruleName: string, baseContext: BaseActionContext, params: Params, isRecoveryMessage?: boolean ): ActionContext { const title = isRecoveryMessage - ? RECOVERY_TITLE(ruleInfo.name, baseContext.group) - : DEFAULT_TITLE(ruleInfo.name, baseContext.group); + ? RECOVERY_TITLE(ruleName, baseContext.group) + : DEFAULT_TITLE(ruleName, baseContext.group); const window = `${params.timeWindowSize}${params.timeWindowUnit}`; const message = isRecoveryMessage - ? RECOVERY_MESSAGE(ruleInfo.name, baseContext, window) - : DEFAULT_MESSAGE(ruleInfo.name, baseContext, window); + ? RECOVERY_MESSAGE(ruleName, baseContext, window) + : DEFAULT_MESSAGE(ruleName, baseContext, window); return { ...baseContext, title, message }; } diff --git a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/rule_type.test.ts b/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/rule_type.test.ts index f7704e4699930..12991ec5c94aa 100644 --- a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/rule_type.test.ts +++ b/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/rule_type.test.ts @@ -183,7 +183,6 @@ describe('ruleType', () => { }; await ruleType.executor({ - alertId: uuid.v4(), executionId: uuid.v4(), startedAt: new Date(), previousStartedAt: new Date(), @@ -197,11 +196,8 @@ describe('ruleType', () => { latestTimestamp: undefined, }, spaceId: uuid.v4(), - name: uuid.v4(), - tags: [], - createdBy: null, - updatedBy: null, rule: { + id: uuid.v4(), name: uuid.v4(), tags: [], consumer: '', @@ -250,7 +246,6 @@ describe('ruleType', () => { }; await ruleType.executor({ - alertId: uuid.v4(), executionId: uuid.v4(), startedAt: new Date(), previousStartedAt: new Date(), @@ -264,11 +259,8 @@ describe('ruleType', () => { latestTimestamp: undefined, }, spaceId: uuid.v4(), - name: uuid.v4(), - tags: [], - createdBy: null, - updatedBy: null, rule: { + id: uuid.v4(), name: uuid.v4(), tags: [], consumer: '', @@ -317,7 +309,6 @@ describe('ruleType', () => { }; await ruleType.executor({ - alertId: uuid.v4(), executionId: uuid.v4(), startedAt: new Date(), previousStartedAt: new Date(), @@ -331,11 +322,8 @@ describe('ruleType', () => { latestTimestamp: undefined, }, spaceId: uuid.v4(), - name: uuid.v4(), - tags: [], - createdBy: null, - updatedBy: null, rule: { + id: uuid.v4(), name: uuid.v4(), tags: [], consumer: '', @@ -383,7 +371,6 @@ describe('ruleType', () => { }; await ruleType.executor({ - alertId: uuid.v4(), executionId: uuid.v4(), startedAt: new Date(), previousStartedAt: new Date(), @@ -397,11 +384,8 @@ describe('ruleType', () => { latestTimestamp: undefined, }, spaceId: uuid.v4(), - name: uuid.v4(), - tags: [], - createdBy: null, - updatedBy: null, rule: { + id: uuid.v4(), name: uuid.v4(), tags: [], consumer: '', diff --git a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/rule_type.ts b/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/rule_type.ts index 2fcb36b267d6d..8b347d58de18c 100644 --- a/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/rule_type.ts +++ b/x-pack/plugins/stack_alerts/server/alert_types/index_threshold/rule_type.ts @@ -134,7 +134,12 @@ export function getRuleType( async function executor( options: RuleExecutorOptions ) { - const { alertId: ruleId, name, services, params, logger } = options; + const { + rule: { id: ruleId, name }, + services, + params, + logger, + } = options; const { alertFactory, scopedClusterClient } = services; const alertLimit = alertFactory.alertLimit.getValue(); @@ -229,7 +234,7 @@ export function getRuleType( value, conditions: humanFn, }; - const actionContext = addMessages(options, baseContext, params); + const actionContext = addMessages(name, baseContext, params); const alert = alertFactory.create(alertId); alert.scheduleActions(ActionGroupId, actionContext); logger.debug(`scheduled actionGroup: ${JSON.stringify(actionContext)}`); @@ -249,7 +254,7 @@ export function getRuleType( params.thresholdComparator )} ${params.threshold.join(' and ')}`, }; - const recoveryContext = addMessages(options, baseContext, params, true); + const recoveryContext = addMessages(name, baseContext, params, true); recoveredAlert.setContext(recoveryContext); } } diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/server/alert_types.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/server/alert_types.ts index 068c516618616..d41d7a699e6ef 100644 --- a/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/server/alert_types.ts +++ b/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/server/alert_types.ts @@ -95,21 +95,9 @@ function getAlwaysFiringAlertType() { } async function alwaysFiringExecutor(alertExecutorOptions: any) { - const { - services, - params, - state, - alertId, - spaceId, - namespace, - name, - tags, - createdBy, - updatedBy, - rule, - } = alertExecutorOptions; + const { services, params, state, spaceId, namespace, rule } = alertExecutorOptions; let group: string | null = 'default'; - const alertInfo = { alertId, spaceId, namespace, name, tags, createdBy, updatedBy, ...rule }; + const alertInfo = { spaceId, namespace, ...rule }; if (params.groupsToScheduleActionsInSeries) { const index = state.groupInSeriesIndex || 0; diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/alerts.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/alerts.ts index 707fab5d57a3d..1dace147df4b3 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/alerts.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/alerts.ts @@ -144,7 +144,7 @@ export default function alertTests({ getService }: FtrProviderContext) { reference, }, alertInfo: { - alertId, + id: alertId, consumer: 'alertsFixture', spaceId: space.id, namespace: space.id, @@ -296,7 +296,7 @@ instanceStateValue: true reference, }, alertInfo: { - alertId, + id: alertId, consumer: 'alertsFixture', spaceId: space.id, namespace: space.id, @@ -428,7 +428,7 @@ instanceStateValue: true ['createdAt', 'updatedAt'] ); expect(alertSearchResultInfoWithoutDates).to.eql({ - alertId, + id: alertId, consumer: 'alertsFixture', spaceId: space.id, namespace: space.id, diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/alerts_base.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/alerts_base.ts index 53cb0a1f662ce..a0f3e48ed9c0e 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/alerts_base.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/alerts_base.ts @@ -98,7 +98,7 @@ export function alertTests({ getService }: FtrProviderContext, space: Space) { reference, }, alertInfo: { - alertId, + id: alertId, consumer: 'alertsFixture', spaceId: space.id, namespace: space.namespace, From ab1bca56b2d2a7ec64d00158b2caff7adae09cc5 Mon Sep 17 00:00:00 2001 From: Jonathan Budzenski Date: Fri, 4 Nov 2022 08:20:34 -0500 Subject: [PATCH 18/31] fix codeowners --- packages/kbn-rule-data-utils/kibana.jsonc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/kbn-rule-data-utils/kibana.jsonc b/packages/kbn-rule-data-utils/kibana.jsonc index 0fe42f6cb6e3d..654155c883971 100644 --- a/packages/kbn-rule-data-utils/kibana.jsonc +++ b/packages/kbn-rule-data-utils/kibana.jsonc @@ -1,7 +1,11 @@ { "type": "shared-common", "id": "@kbn/rule-data-utils", - "owner": "@elastic/apm-ui", + "owner": [ + "@elastic/security-detections-response", + "@elastic/actionable-observability", + "@elastic/response-ops" + ], "runtimeDeps": [], "typeDeps": [] } From 7c9ce43041e3d3f61bffd0446092d5244ac412fd Mon Sep 17 00:00:00 2001 From: Kevin Delemme Date: Fri, 4 Nov 2022 10:02:21 -0400 Subject: [PATCH 19/31] chore(slo): Error budget consumption for timeslices calendar aligned slo (#143982) Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .github/CODEOWNERS | 2 +- .../services/compute_error_budget.test.ts | 123 ++++++++++++++++-- .../domain/services/compute_error_budget.ts | 37 +++++- .../domain/services/compute_sli.test.ts | 10 +- .../server/domain/services/compute_sli.ts | 9 +- .../server/domain/services/date_range.ts | 7 +- .../server/services/slo/fixtures/date.ts | 14 ++ .../server/services/slo/fixtures/duration.ts | 20 +++ .../server/services/slo/fixtures/slo.ts | 10 +- .../services/slo/fixtures/time_window.ts | 25 ++++ .../server/services/slo/get_slo.test.ts | 7 +- .../server/services/slo/sli_client.test.ts | 53 ++++++-- .../server/services/slo/sli_client.ts | 44 +++---- .../server/types/models/common.ts | 12 ++ .../server/types/models/index.ts | 1 + .../server/types/schema/common.ts | 4 +- .../server/types/schema/indicators.ts | 8 +- 17 files changed, 306 insertions(+), 80 deletions(-) create mode 100644 x-pack/plugins/observability/server/services/slo/fixtures/date.ts create mode 100644 x-pack/plugins/observability/server/services/slo/fixtures/duration.ts create mode 100644 x-pack/plugins/observability/server/services/slo/fixtures/time_window.ts create mode 100644 x-pack/plugins/observability/server/types/models/common.ts diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 01f4bd562a9e0..caf16d1050725 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -950,7 +950,7 @@ packages/kbn-plugin-helpers @elastic/kibana-operations packages/kbn-react-field @elastic/kibana-app-services packages/kbn-repo-source-classifier @elastic/kibana-operations packages/kbn-repo-source-classifier-cli @elastic/kibana-operations -packages/kbn-rule-data-utils @elastic/security-detections-response @elastic/actionable-observability @elastic/response-ops +packages/kbn-rule-data-utils @elastic/apm-ui packages/kbn-safer-lodash-set @elastic/kibana-security packages/kbn-securitysolution-autocomplete @elastic/security-solution-platform packages/kbn-securitysolution-es-utils @elastic/security-solution-platform diff --git a/x-pack/plugins/observability/server/domain/services/compute_error_budget.test.ts b/x-pack/plugins/observability/server/domain/services/compute_error_budget.test.ts index 09488f7d577da..eaec5420f1953 100644 --- a/x-pack/plugins/observability/server/domain/services/compute_error_budget.test.ts +++ b/x-pack/plugins/observability/server/domain/services/compute_error_budget.test.ts @@ -5,13 +5,115 @@ * 2.0. */ +import { twoDaysAgo } from '../../services/slo/fixtures/date'; +import { oneMinute } from '../../services/slo/fixtures/duration'; import { createSLO } from '../../services/slo/fixtures/slo'; +import { sevenDaysRolling, weeklyCalendarAligned } from '../../services/slo/fixtures/time_window'; import { computeErrorBudget } from './compute_error_budget'; +import { toDateRange } from './date_range'; describe('computeErrorBudget', () => { + describe('for occurrences based SLO', () => { + describe('with rolling time window', () => { + it('computes the error budget', () => { + const slo = createSLO({ + budgeting_method: 'occurrences', + time_window: sevenDaysRolling(), + objective: { target: 0.95 }, + }); + const dateRange = toDateRange(slo.time_window); + const errorBudget = computeErrorBudget(slo, { + good: 97, + total: 100, + date_range: dateRange, + }); + + expect(errorBudget).toEqual({ + initial: 0.05, + consumed: 0.6, + remaining: 0.4, + }); + }); + }); + + describe('with calendar aligned time window', () => { + it('computes the error budget', () => { + const slo = createSLO({ + budgeting_method: 'occurrences', + time_window: weeklyCalendarAligned(twoDaysAgo()), + objective: { target: 0.95 }, + }); + const dateRange = toDateRange(slo.time_window); + const errorBudget = computeErrorBudget(slo, { + good: 97, + total: 100, + date_range: dateRange, + }); + + expect(errorBudget).toEqual({ + initial: 0.05, + consumed: 0.6, + remaining: 0.4, + }); + }); + }); + }); + + describe('for timeslices based SLO', () => { + describe('with rolling time window', () => { + it('computes the error budget', () => { + const slo = createSLO({ + budgeting_method: 'timeslices', + time_window: sevenDaysRolling(), + objective: { target: 0.95, timeslice_target: 0.95, timeslice_window: oneMinute() }, + }); + const dateRange = toDateRange(slo.time_window); + // 7 days sliced in 1m buckets = 10,080 slices + const errorBudget = computeErrorBudget(slo, { + good: 9987, + total: 10080, + date_range: dateRange, + }); + + expect(errorBudget).toEqual({ + initial: 0.05, + consumed: 0.184524, + remaining: 0.815476, + }); + }); + }); + + describe('with calendar aligned time window', () => { + it('computes the error budget', () => { + const slo = createSLO({ + budgeting_method: 'timeslices', + time_window: weeklyCalendarAligned(twoDaysAgo()), + objective: { target: 0.95, timeslice_target: 0.95, timeslice_window: oneMinute() }, + }); + const dateRange = toDateRange(slo.time_window); + // 2 days sliced in 1m buckets = 2,880 slices (slices we have data for) = total + // 7 days sliced in 1m buckets = 10,080 slices (all slices for the window) = window_total + const errorBudget = computeErrorBudget(slo, { + good: 2823, + total: 2880, + date_range: dateRange, + }); + + // error rate = (total - good) / window_total = (2880 - 2823) / 10080 = 0.00565476 + // consumed = error rate / error budget = 0.00565476 / 0.05 = 0.1130952 + expect(errorBudget).toEqual({ + initial: 0.05, + consumed: 0.113095, + remaining: 0.886905, + }); + }); + }); + }); + it("returns default values when total events is '0'", () => { const slo = createSLO(); - const errorBudget = computeErrorBudget(slo, { good: 100, total: 0 }); + const dateRange = toDateRange(slo.time_window); + const errorBudget = computeErrorBudget(slo, { good: 100, total: 0, date_range: dateRange }); expect(errorBudget).toEqual({ initial: 0.001, // 0.1% @@ -22,7 +124,8 @@ describe('computeErrorBudget', () => { it("computes the error budget when 'good > total' events", () => { const slo = createSLO(); - const errorBudget = computeErrorBudget(slo, { good: 9999, total: 9 }); + const dateRange = toDateRange(slo.time_window); + const errorBudget = computeErrorBudget(slo, { good: 9999, total: 9, date_range: dateRange }); expect(errorBudget).toEqual({ initial: 0.001, @@ -33,7 +136,8 @@ describe('computeErrorBudget', () => { it('computes the error budget with all good events', () => { const slo = createSLO(); - const errorBudget = computeErrorBudget(slo, { good: 100, total: 100 }); + const dateRange = toDateRange(slo.time_window); + const errorBudget = computeErrorBudget(slo, { good: 100, total: 100, date_range: dateRange }); expect(errorBudget).toEqual({ initial: 0.001, @@ -44,7 +148,8 @@ describe('computeErrorBudget', () => { it('computes the error budget when exactly consumed', () => { const slo = createSLO(); - const errorBudget = computeErrorBudget(slo, { good: 999, total: 1000 }); + const dateRange = toDateRange(slo.time_window); + const errorBudget = computeErrorBudget(slo, { good: 999, total: 1000, date_range: dateRange }); expect(errorBudget).toEqual({ initial: 0.001, @@ -55,22 +160,24 @@ describe('computeErrorBudget', () => { it('computes the error budget with rounded values', () => { const slo = createSLO(); - const errorBudget = computeErrorBudget(slo, { good: 333, total: 777 }); + const dateRange = toDateRange(slo.time_window); + const errorBudget = computeErrorBudget(slo, { good: 333, total: 777, date_range: dateRange }); expect(errorBudget).toEqual({ initial: 0.001, - consumed: 571.428571, // i.e. 57142% consumed + consumed: 571.428571, // i.e. 57,142% consumed remaining: 0, }); }); it('computes the error budget with no good events', () => { const slo = createSLO(); - const errorBudget = computeErrorBudget(slo, { good: 0, total: 100 }); + const dateRange = toDateRange(slo.time_window); + const errorBudget = computeErrorBudget(slo, { good: 0, total: 100, date_range: dateRange }); expect(errorBudget).toEqual({ initial: 0.001, - consumed: 1000, // i.e. 100000% consumed + consumed: 1000, // i.e. 100,000% consumed remaining: 0, }); }); diff --git a/x-pack/plugins/observability/server/domain/services/compute_error_budget.ts b/x-pack/plugins/observability/server/domain/services/compute_error_budget.ts index 98ee17962b818..68531d4f4cb0b 100644 --- a/x-pack/plugins/observability/server/domain/services/compute_error_budget.ts +++ b/x-pack/plugins/observability/server/domain/services/compute_error_budget.ts @@ -5,14 +5,19 @@ * 2.0. */ -import { ErrorBudget, IndicatorData, SLO } from '../../types/models'; +import moment from 'moment'; +import { ErrorBudget, IndicatorData, SLO, toMomentUnitOfTime } from '../../types/models'; +import { + calendarAlignedTimeWindowSchema, + timeslicesBudgetingMethodSchema, +} from '../../types/schema'; import { toHighPrecision } from '../../utils/number'; +// More details about calculus: https://github.com/elastic/kibana/issues/143980 export function computeErrorBudget(slo: SLO, sliData: IndicatorData): ErrorBudget { - const goodEvents = sliData.good; - const totalEvents = sliData.total; + const { good, total, date_range: dateRange } = sliData; const initialErrorBudget = toHighPrecision(1 - slo.objective.target); - if (totalEvents === 0 || goodEvents >= totalEvents) { + if (total === 0 || good >= total) { return { initial: initialErrorBudget, consumed: 0, @@ -20,10 +25,28 @@ export function computeErrorBudget(slo: SLO, sliData: IndicatorData): ErrorBudge }; } - const consumedErrorBudget = toHighPrecision( - (totalEvents - goodEvents) / (totalEvents * initialErrorBudget) - ); + if ( + timeslicesBudgetingMethodSchema.is(slo.budgeting_method) && + calendarAlignedTimeWindowSchema.is(slo.time_window) + ) { + const dateRangeDurationInUnit = moment(dateRange.to).diff( + dateRange.from, + toMomentUnitOfTime(slo.objective.timeslice_window!.unit) + ); + const totalSlices = Math.ceil(dateRangeDurationInUnit / slo.objective.timeslice_window!.value); + const consumedErrorBudget = toHighPrecision( + (total - good) / (totalSlices * initialErrorBudget) + ); + const remainingErrorBudget = Math.max(toHighPrecision(1 - consumedErrorBudget), 0); + return { + initial: initialErrorBudget, + consumed: consumedErrorBudget, + remaining: remainingErrorBudget, + }; + } + + const consumedErrorBudget = toHighPrecision((total - good) / (total * initialErrorBudget)); const remainingErrorBudget = Math.max(toHighPrecision(1 - consumedErrorBudget), 0); return { diff --git a/x-pack/plugins/observability/server/domain/services/compute_sli.test.ts b/x-pack/plugins/observability/server/domain/services/compute_sli.test.ts index ba864fc1fea19..9d69539c72f70 100644 --- a/x-pack/plugins/observability/server/domain/services/compute_sli.test.ts +++ b/x-pack/plugins/observability/server/domain/services/compute_sli.test.ts @@ -5,22 +5,24 @@ * 2.0. */ +import { DateRange } from '../../types/models'; import { computeSLI } from './compute_sli'; +const DATE_RANGE: DateRange = { from: new Date(), to: new Date() }; describe('computeSLI', () => { it('returns 0 when no total events', () => { - expect(computeSLI({ good: 100, total: 0 })).toEqual(0); + expect(computeSLI({ good: 100, total: 0, date_range: DATE_RANGE })).toEqual(0); }); it('returns the sli value', () => { - expect(computeSLI({ good: 100, total: 1000 })).toEqual(0.1); + expect(computeSLI({ good: 100, total: 1000, date_range: DATE_RANGE })).toEqual(0.1); }); it('returns 1 when good is greater than total events', () => { - expect(computeSLI({ good: 9999, total: 9 })).toEqual(1); + expect(computeSLI({ good: 9999, total: 9, date_range: DATE_RANGE })).toEqual(1); }); it('returns rounds the value to 6 digits', () => { - expect(computeSLI({ good: 33, total: 90 })).toEqual(0.366667); + expect(computeSLI({ good: 33, total: 90, date_range: DATE_RANGE })).toEqual(0.366667); }); }); diff --git a/x-pack/plugins/observability/server/domain/services/compute_sli.ts b/x-pack/plugins/observability/server/domain/services/compute_sli.ts index 2def35dc37329..6a0f885737633 100644 --- a/x-pack/plugins/observability/server/domain/services/compute_sli.ts +++ b/x-pack/plugins/observability/server/domain/services/compute_sli.ts @@ -9,15 +9,14 @@ import { IndicatorData } from '../../types/models'; import { toHighPrecision } from '../../utils/number'; export function computeSLI(sliData: IndicatorData): number { - const goodEvents = sliData.good; - const totalEvents = sliData.total; - if (totalEvents === 0) { + const { good, total } = sliData; + if (total === 0) { return 0; } - if (goodEvents >= totalEvents) { + if (good >= total) { return 1; } - return toHighPrecision(goodEvents / totalEvents); + return toHighPrecision(good / total); } diff --git a/x-pack/plugins/observability/server/domain/services/date_range.ts b/x-pack/plugins/observability/server/domain/services/date_range.ts index e556d85a09f6f..2c23d0672fa31 100644 --- a/x-pack/plugins/observability/server/domain/services/date_range.ts +++ b/x-pack/plugins/observability/server/domain/services/date_range.ts @@ -7,16 +7,11 @@ import { assertNever } from '@kbn/std'; import moment from 'moment'; -import { toMomentUnitOfTime } from '../../types/models'; +import { DateRange, toMomentUnitOfTime } from '../../types/models'; import type { TimeWindow } from '../../types/models/time_window'; import { calendarAlignedTimeWindowSchema, rollingTimeWindowSchema } from '../../types/schema'; -export interface DateRange { - from: Date; - to: Date; -} - export const toDateRange = (timeWindow: TimeWindow, currentDate: Date = new Date()): DateRange => { if (calendarAlignedTimeWindowSchema.is(timeWindow)) { const unit = toMomentUnitOfTime(timeWindow.duration.unit); diff --git a/x-pack/plugins/observability/server/services/slo/fixtures/date.ts b/x-pack/plugins/observability/server/services/slo/fixtures/date.ts new file mode 100644 index 0000000000000..b62a1fd918e51 --- /dev/null +++ b/x-pack/plugins/observability/server/services/slo/fixtures/date.ts @@ -0,0 +1,14 @@ +/* + * 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. + */ + +const DAYS_IN_MILLISECONDS = 24 * 60 * 60 * 1000; + +export function twoDaysAgo(): Date { + const now = new Date(); + now.setTime(now.getTime() - 2 * DAYS_IN_MILLISECONDS); + return now; +} diff --git a/x-pack/plugins/observability/server/services/slo/fixtures/duration.ts b/x-pack/plugins/observability/server/services/slo/fixtures/duration.ts new file mode 100644 index 0000000000000..be0eb1407145c --- /dev/null +++ b/x-pack/plugins/observability/server/services/slo/fixtures/duration.ts @@ -0,0 +1,20 @@ +/* + * 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 { Duration, DurationUnit } from '../../../types/models'; + +export function sevenDays(): Duration { + return new Duration(7, DurationUnit.d); +} + +export function oneWeek(): Duration { + return new Duration(1, DurationUnit.w); +} + +export function oneMinute(): Duration { + return new Duration(1, DurationUnit.m); +} diff --git a/x-pack/plugins/observability/server/services/slo/fixtures/slo.ts b/x-pack/plugins/observability/server/services/slo/fixtures/slo.ts index 4c4139c0e9120..d1d600c7706e2 100644 --- a/x-pack/plugins/observability/server/services/slo/fixtures/slo.ts +++ b/x-pack/plugins/observability/server/services/slo/fixtures/slo.ts @@ -7,7 +7,6 @@ import { cloneDeep } from 'lodash'; import uuid from 'uuid'; -import { Duration, DurationUnit } from '../../../types/models/duration'; import { APMTransactionDurationIndicator, @@ -17,6 +16,8 @@ import { SLO, } from '../../../types/models'; import { CreateSLOParams } from '../../../types/rest_specs'; +import { sevenDays } from './duration'; +import { sevenDaysRolling } from './time_window'; export const createAPMTransactionErrorRateIndicator = ( params: Partial = {} @@ -62,10 +63,7 @@ export const createKQLCustomIndicator = ( const defaultSLO: Omit = { name: 'irrelevant', description: 'irrelevant', - time_window: { - duration: new Duration(7, DurationUnit.d), - is_rolling: true, - }, + time_window: sevenDaysRolling(), budgeting_method: 'occurrences', objective: { target: 0.999, @@ -93,7 +91,7 @@ export const createSLO = (params: Partial = {}): SLO => { export const createSLOWithCalendarTimeWindow = (params: Partial = {}): SLO => { return createSLO({ time_window: { - duration: new Duration(7, DurationUnit.d), + duration: sevenDays(), calendar: { start_time: new Date('2022-10-01T00:00:00.000Z') }, }, ...params, diff --git a/x-pack/plugins/observability/server/services/slo/fixtures/time_window.ts b/x-pack/plugins/observability/server/services/slo/fixtures/time_window.ts new file mode 100644 index 0000000000000..6f9228bc9304f --- /dev/null +++ b/x-pack/plugins/observability/server/services/slo/fixtures/time_window.ts @@ -0,0 +1,25 @@ +/* + * 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 { TimeWindow } from '../../../types/models/time_window'; +import { oneWeek, sevenDays } from './duration'; + +export function sevenDaysRolling(): TimeWindow { + return { + duration: sevenDays(), + is_rolling: true, + }; +} + +export function weeklyCalendarAligned(startTime: Date): TimeWindow { + return { + duration: oneWeek(), + calendar: { + start_time: startTime, + }, + }; +} diff --git a/x-pack/plugins/observability/server/services/slo/get_slo.test.ts b/x-pack/plugins/observability/server/services/slo/get_slo.test.ts index f78f04c37f38e..568afe7799ba4 100644 --- a/x-pack/plugins/observability/server/services/slo/get_slo.test.ts +++ b/x-pack/plugins/observability/server/services/slo/get_slo.test.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { toDateRange } from '../../domain/services'; import { createAPMTransactionErrorRateIndicator, createSLO } from './fixtures/slo'; import { GetSLO } from './get_slo'; import { createSLIClientMock, createSLORepositoryMock } from './mocks'; @@ -26,7 +27,11 @@ describe('GetSLO', () => { it('retrieves the SLO from the repository', async () => { const slo = createSLO({ indicator: createAPMTransactionErrorRateIndicator() }); mockRepository.findById.mockResolvedValueOnce(slo); - mockSLIClient.fetchCurrentSLIData.mockResolvedValueOnce({ good: 9999, total: 10000 }); + mockSLIClient.fetchCurrentSLIData.mockResolvedValueOnce({ + good: 9999, + total: 10000, + date_range: toDateRange(slo.time_window), + }); const result = await getSLO.execute(slo.id); diff --git a/x-pack/plugins/observability/server/services/slo/sli_client.test.ts b/x-pack/plugins/observability/server/services/slo/sli_client.test.ts index 7729bab2f9055..359b74cd58cca 100644 --- a/x-pack/plugins/observability/server/services/slo/sli_client.test.ts +++ b/x-pack/plugins/observability/server/services/slo/sli_client.test.ts @@ -6,6 +6,8 @@ */ import { ElasticsearchClientMock, elasticsearchServiceMock } from '@kbn/core/server/mocks'; +import moment from 'moment'; + import { SLO_DESTINATION_INDEX_NAME } from '../../assets/constants'; import { toDateRange } from '../../domain/services'; import { InternalQueryError } from '../../errors'; @@ -79,7 +81,15 @@ describe('SLIClient', () => { const result = await sliClient.fetchCurrentSLIData(slo); - expect(result).toEqual({ good: 90, total: 100 }); + const expectedDateRange = toDateRange(slo.time_window); + + expect(result).toMatchObject({ + good: 90, + total: 100, + }); + expect(result.date_range.from).toBeClose(expectedDateRange.from); + expect(result.date_range.to).toBeClose(expectedDateRange.to); + expect(esClientMock.search).toHaveBeenCalledWith( expect.objectContaining({ index: `${SLO_DESTINATION_INDEX_NAME}*`, @@ -90,7 +100,7 @@ describe('SLIClient', () => { { term: { 'slo.revision': slo.revision } }, { range: { - '@timestamp': { gte: 'now-7d/m', lt: 'now/m' }, + '@timestamp': { gte: expect.anything(), lt: expect.anything() }, }, }, ], @@ -138,7 +148,9 @@ describe('SLIClient', () => { const expectedDateRange = toDateRange(slo.time_window); - expect(result).toEqual({ good: 90, total: 100 }); + expect(result).toMatchObject({ good: 90, total: 100 }); + expect(result.date_range.from).toBeClose(expectedDateRange.from); + expect(result.date_range.to).toBeClose(expectedDateRange.to); expect(esClientMock.search).toHaveBeenCalledWith( expect.objectContaining({ index: `${SLO_DESTINATION_INDEX_NAME}*`, @@ -239,8 +251,9 @@ describe('SLIClient', () => { const result = await sliClient.fetchCurrentSLIData(slo); const expectedDateRange = toDateRange(slo.time_window); - - expect(result).toEqual({ good: 90, total: 100 }); + expect(result).toMatchObject({ good: 90, total: 100 }); + expect(result.date_range.from).toBeClose(expectedDateRange.from); + expect(result.date_range.to).toBeClose(expectedDateRange.to); expect(esClientMock.search).toHaveBeenCalledWith( expect.objectContaining({ index: `${SLO_DESTINATION_INDEX_NAME}*`, @@ -345,7 +358,10 @@ describe('SLIClient', () => { const result = await sliClient.fetchCurrentSLIData(slo); - expect(result).toEqual({ good: 90, total: 100 }); + const expectedDateRange = toDateRange(slo.time_window); + expect(result).toMatchObject({ good: 90, total: 100 }); + expect(result.date_range.from).toBeClose(expectedDateRange.from); + expect(result.date_range.to).toBeClose(expectedDateRange.to); expect(esClientMock.search).toHaveBeenCalledWith( expect.objectContaining({ index: `${SLO_DESTINATION_INDEX_NAME}*`, @@ -356,10 +372,7 @@ describe('SLIClient', () => { { term: { 'slo.revision': slo.revision } }, { range: { - '@timestamp': { - gte: 'now-1M/m', - lt: 'now/m', - }, + '@timestamp': { gte: expect.anything(), lt: expect.anything() }, }, }, ], @@ -417,3 +430,23 @@ describe('SLIClient', () => { }); }); }); + +expect.extend({ + toBeClose(received: Date | string, actual: Date | string) { + const receivedDate = moment(received); + const actualDate = moment(actual); + return { + message: () => + `expected ${receivedDate.toISOString()} to be close to ${actualDate.toISOString()}`, + pass: Math.abs(receivedDate.diff(actualDate, 'seconds')) <= 120, + }; + }, +}); +declare global { + // eslint-disable-next-line @typescript-eslint/no-namespace + namespace jest { + interface Matchers { + toBeClose(actual: Date | string): R; + } + } +} diff --git a/x-pack/plugins/observability/server/services/slo/sli_client.ts b/x-pack/plugins/observability/server/services/slo/sli_client.ts index dc97aa1c651f0..a1cc948a31368 100644 --- a/x-pack/plugins/observability/server/services/slo/sli_client.ts +++ b/x-pack/plugins/observability/server/services/slo/sli_client.ts @@ -11,8 +11,7 @@ import { assertNever } from '@kbn/std'; import { SLO_DESTINATION_INDEX_NAME } from '../../assets/constants'; import { toDateRange } from '../../domain/services/date_range'; import { InternalQueryError } from '../../errors'; -import { Duration, IndicatorData, SLO } from '../../types/models'; -import { calendarAlignedTimeWindowSchema, rollingTimeWindowSchema } from '../../types/schema'; +import { DateRange, Duration, IndicatorData, SLO } from '../../types/models'; import { occurencesBudgetingMethodSchema, timeslicesBudgetingMethodSchema, @@ -28,21 +27,22 @@ export class DefaultSLIClient implements SLIClient { constructor(private esClient: ElasticsearchClient) {} async fetchCurrentSLIData(slo: SLO): Promise { + const dateRange = toDateRange(slo.time_window); if (occurencesBudgetingMethodSchema.is(slo.budgeting_method)) { const result = await this.esClient.search>({ - ...commonQuery(slo), + ...commonQuery(slo, dateRange), aggs: { good: { sum: { field: 'slo.numerator' } }, total: { sum: { field: 'slo.denominator' } }, }, }); - return handleResult(result.aggregations); + return handleResult(result.aggregations, dateRange); } if (timeslicesBudgetingMethodSchema.is(slo.budgeting_method)) { const result = await this.esClient.search>({ - ...commonQuery(slo), + ...commonQuery(slo, dateRange), aggs: { slices: { date_histogram: { @@ -82,34 +82,14 @@ export class DefaultSLIClient implements SLIClient { }, }); - return handleResult(result.aggregations); + return handleResult(result.aggregations, dateRange); } assertNever(slo.budgeting_method); } } -function fromSLOTimeWindowToEsRange(slo: SLO): { gte: string; lt: string } { - if (calendarAlignedTimeWindowSchema.is(slo.time_window)) { - const dateRange = toDateRange(slo.time_window); - - return { - gte: `${dateRange.from.toISOString()}`, - lt: `${dateRange.to.toISOString()}`, - }; - } - - if (rollingTimeWindowSchema.is(slo.time_window)) { - return { - gte: `now-${slo.time_window.duration.value}${slo.time_window.duration.unit}/m`, - lt: `now/m`, - }; - } - - assertNever(slo.time_window); -} - -function commonQuery(slo: SLO) { +function commonQuery(slo: SLO, dateRange: DateRange) { return { size: 0, index: `${SLO_DESTINATION_INDEX_NAME}*`, @@ -118,7 +98,11 @@ function commonQuery(slo: SLO) { filter: [ { term: { 'slo.id': slo.id } }, { term: { 'slo.revision': slo.revision } }, - { range: { '@timestamp': fromSLOTimeWindowToEsRange(slo) } }, + { + range: { + '@timestamp': { gte: dateRange.from.toISOString(), lt: dateRange.to.toISOString() }, + }, + }, ], }, }, @@ -126,7 +110,8 @@ function commonQuery(slo: SLO) { } function handleResult( - aggregations: Record | undefined + aggregations: Record | undefined, + dateRange: DateRange ): IndicatorData { const good = aggregations?.good; const total = aggregations?.total; @@ -135,6 +120,7 @@ function handleResult( } return { + date_range: dateRange, good: good.value, total: total.value, }; diff --git a/x-pack/plugins/observability/server/types/models/common.ts b/x-pack/plugins/observability/server/types/models/common.ts new file mode 100644 index 0000000000000..7f672136c9194 --- /dev/null +++ b/x-pack/plugins/observability/server/types/models/common.ts @@ -0,0 +1,12 @@ +/* + * 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 * as t from 'io-ts'; +import { dateRangeSchema } from '../schema'; + +type DateRange = t.TypeOf; + +export type { DateRange }; diff --git a/x-pack/plugins/observability/server/types/models/index.ts b/x-pack/plugins/observability/server/types/models/index.ts index d27c9f27c868b..443dea8f09d6d 100644 --- a/x-pack/plugins/observability/server/types/models/index.ts +++ b/x-pack/plugins/observability/server/types/models/index.ts @@ -9,3 +9,4 @@ export * from './slo'; export * from './indicators'; export * from './error_budget'; export * from './duration'; +export * from './common'; diff --git a/x-pack/plugins/observability/server/types/schema/common.ts b/x-pack/plugins/observability/server/types/schema/common.ts index d565b0eb5f31f..b3265178d5260 100644 --- a/x-pack/plugins/observability/server/types/schema/common.ts +++ b/x-pack/plugins/observability/server/types/schema/common.ts @@ -29,4 +29,6 @@ const errorBudgetSchema = t.type({ remaining: t.number, }); -export { allOrAnyString, ALL_VALUE, dateType, errorBudgetSchema }; +const dateRangeSchema = t.type({ from: dateType, to: dateType }); + +export { allOrAnyString, ALL_VALUE, dateType, errorBudgetSchema, dateRangeSchema }; diff --git a/x-pack/plugins/observability/server/types/schema/indicators.ts b/x-pack/plugins/observability/server/types/schema/indicators.ts index ab343e5b7b995..46d3e8694e684 100644 --- a/x-pack/plugins/observability/server/types/schema/indicators.ts +++ b/x-pack/plugins/observability/server/types/schema/indicators.ts @@ -6,7 +6,7 @@ */ import * as t from 'io-ts'; -import { allOrAnyString } from './common'; +import { allOrAnyString, dateRangeSchema } from './common'; const apmTransactionDurationIndicatorTypeSchema = t.literal('slo.apm.transaction_duration'); const apmTransactionDurationIndicatorSchema = t.type({ @@ -49,7 +49,11 @@ const kqlCustomIndicatorSchema = t.type({ }), }); -const indicatorDataSchema = t.type({ good: t.number, total: t.number }); +const indicatorDataSchema = t.type({ + date_range: dateRangeSchema, + good: t.number, + total: t.number, +}); const indicatorTypesSchema = t.union([ apmTransactionDurationIndicatorTypeSchema, From 56e193022bc3126574bcfee5b8d6f0f0e385f365 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Fri, 4 Nov 2022 15:04:47 +0100 Subject: [PATCH 20/31] Timings breakdown donut !! (#144496) --- .../components/network_timings_donut.tsx | 89 ++++++++ .../timings_breakdown/breakdown_legend.tsx | 40 ++++ .../hooks/use_network_timings.ts | 204 ++++++++++++++++++ .../network_timings_breakdown.tsx | 6 +- .../step_details_page/step_detail_page.tsx | 9 +- 5 files changed, 343 insertions(+), 5 deletions(-) create mode 100644 x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/components/network_timings_donut.tsx create mode 100644 x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/components/timings_breakdown/breakdown_legend.tsx create mode 100644 x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/hooks/use_network_timings.ts diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/components/network_timings_donut.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/components/network_timings_donut.tsx new file mode 100644 index 0000000000000..62e5219c68105 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/components/network_timings_donut.tsx @@ -0,0 +1,89 @@ +/* + * 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 { + Chart, + Partition, + Settings, + PartitionLayout, + Datum, + LIGHT_THEME, + PartialTheme, +} from '@elastic/charts'; +import React from 'react'; +import { useTheme } from '@kbn/observability-plugin/public'; + +import { EuiLoadingSpinner, EuiSpacer, EuiTitle } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { useNetworkTimings } from '../hooks/use_network_timings'; + +const themeOverrides: PartialTheme = { + chartMargins: { top: 0, bottom: 0, left: 0, right: 0 }, + partition: { + linkLabel: { + maximumSection: Infinity, + maxCount: 0, + }, + idealFontSizeJump: 1.1, + outerSizeRatio: 0.9, + emptySizeRatio: 0.6, + circlePadding: 5, + }, +}; + +export const NetworkTimingsDonut = () => { + const networkTimings = useNetworkTimings(); + + const theme = useTheme(); + + if (!networkTimings) { + return ; + } + + return ( + <> + +

{TIMINGS_BREAKDOWN}

+
+ + + + d?.value} + valueFormatter={(d: number) => formatMillisecond(d)} + layers={[ + { + groupByRollup: (d: Datum) => d.label, + nodeLabel: (d: Datum) => d, + shape: { + fillColor: (d: Datum, index: number) => { + return (theme.eui as unknown as Record)[ + `euiColorVis${index + 1}` + ]; + }, + }, + }, + ]} + /> + + + ); +}; + +const TIMINGS_BREAKDOWN = i18n.translate('xpack.synthetics.stepDetailsRoute.timingsBreakdown', { + defaultMessage: 'Timings breakdown', +}); + +export const formatMillisecond = (ms: number) => { + if (ms < 1000) { + return `${ms.toFixed(0)} ms`; + } + return `${(ms / 1000).toFixed(1)} s`; +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/components/timings_breakdown/breakdown_legend.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/components/timings_breakdown/breakdown_legend.tsx new file mode 100644 index 0000000000000..323bd98a4f758 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/components/timings_breakdown/breakdown_legend.tsx @@ -0,0 +1,40 @@ +/* + * 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 { EuiFlexGroup, EuiFlexItem, EuiHealth, EuiSpacer, EuiText } from '@elastic/eui'; +import React from 'react'; +import { useTheme } from '@kbn/observability-plugin/public'; +import { formatMillisecond } from '../network_timings_donut'; +import { useNetworkTimings } from '../../hooks/use_network_timings'; + +export const BreakdownLegend = () => { + const networkTimings = useNetworkTimings(); + + const theme = useTheme(); + + return ( + <> + + + {networkTimings.timingsWithLabels.map(({ label, value }, index) => ( + + + )[`euiColorVis${index + 1}`]} + > + {label} + + + + {formatMillisecond(value)} + + + ))} + + + ); +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/hooks/use_network_timings.ts b/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/hooks/use_network_timings.ts new file mode 100644 index 0000000000000..911e5a54f05f7 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/hooks/use_network_timings.ts @@ -0,0 +1,204 @@ +/* + * 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 { useEsSearch } from '@kbn/observability-plugin/public'; +import { + NETWORK_TIMINGS_FIELDS, + SYNTHETICS_BLOCKED_TIMINGS, + SYNTHETICS_CONNECT_TIMINGS, + SYNTHETICS_DNS_TIMINGS, + SYNTHETICS_RECEIVE_TIMINGS, + SYNTHETICS_SEND_TIMINGS, + SYNTHETICS_SSL_TIMINGS, + SYNTHETICS_STEP_DURATION, + SYNTHETICS_TOTAL_TIMINGS, + SYNTHETICS_WAIT_TIMINGS, +} from '@kbn/observability-plugin/common'; +import { useParams } from 'react-router-dom'; +import { i18n } from '@kbn/i18n'; + +export const useStepFilters = (prevCheckGroupId?: string) => { + const { checkGroupId, stepIndex } = useParams<{ checkGroupId: string; stepIndex: string }>(); + return [ + { + term: { + 'monitor.check_group': prevCheckGroupId ?? checkGroupId, + }, + }, + { + term: { + 'synthetics.step.index': Number(stepIndex), + }, + }, + ]; +}; + +export const useNetworkTimings = () => { + const runTimeMappings = NETWORK_TIMINGS_FIELDS.reduce( + (acc, field) => ({ + ...acc, + [field]: { + type: 'double', + }, + }), + {} + ); + + const networkAggs = NETWORK_TIMINGS_FIELDS.reduce( + (acc, field) => ({ + ...acc, + [field]: { + sum: { + field, + }, + }, + }), + {} + ); + + const { data } = useEsSearch( + { + index: 'synthetics-*', + body: { + size: 0, + runtime_mappings: runTimeMappings, + query: { + bool: { + filter: [ + { + term: { + 'synthetics.type': 'journey/network_info', + }, + }, + ...useStepFilters(), + ], + }, + }, + aggs: { + ...networkAggs, + totalDuration: { + sum: { + field: SYNTHETICS_STEP_DURATION, + }, + }, + dns: { + sum: { + field: SYNTHETICS_DNS_TIMINGS, + }, + }, + ssl: { + sum: { + field: SYNTHETICS_SSL_TIMINGS, + }, + }, + blocked: { + sum: { + field: SYNTHETICS_BLOCKED_TIMINGS, + }, + }, + connect: { + sum: { + field: SYNTHETICS_CONNECT_TIMINGS, + }, + }, + receive: { + sum: { + field: SYNTHETICS_RECEIVE_TIMINGS, + }, + }, + send: { + sum: { + field: SYNTHETICS_SEND_TIMINGS, + }, + }, + wait: { + sum: { + field: SYNTHETICS_WAIT_TIMINGS, + }, + }, + total: { + sum: { + field: SYNTHETICS_TOTAL_TIMINGS, + }, + }, + }, + }, + }, + [], + { name: 'networkTimings' } + ); + + const aggs = data?.aggregations; + + const timings = { + dns: aggs?.dns.value ?? 0, + connect: aggs?.connect.value ?? 0, + receive: aggs?.receive.value ?? 0, + send: aggs?.send.value ?? 0, + wait: aggs?.wait.value ?? 0, + blocked: aggs?.blocked.value ?? 0, + ssl: aggs?.ssl.value ?? 0, + }; + + return { + timings, + timingsWithLabels: [ + { + value: timings.dns, + label: SYNTHETICS_DNS_TIMINGS_LABEL, + }, + { + value: timings.ssl, + label: SYNTHETICS_SSL_TIMINGS_LABEL, + }, + { + value: timings.blocked, + label: SYNTHETICS_BLOCKED_TIMINGS_LABEL, + }, + { + value: timings.connect, + label: SYNTHETICS_CONNECT_TIMINGS_LABEL, + }, + { + value: timings.receive, + label: SYNTHETICS_RECEIVE_TIMINGS_LABEL, + }, + { + value: timings.send, + label: SYNTHETICS_SEND_TIMINGS_LABEL, + }, + { + value: timings.wait, + label: SYNTHETICS_WAIT_TIMINGS_LABEL, + }, + ].sort((a, b) => b.value - a.value), + totalDuration: aggs?.totalDuration.value ?? 0, + }; +}; + +const SYNTHETICS_CONNECT_TIMINGS_LABEL = i18n.translate('xpack.synthetics.connect.label', { + defaultMessage: 'Connect', +}); +const SYNTHETICS_DNS_TIMINGS_LABEL = i18n.translate('xpack.synthetics.dns', { + defaultMessage: 'DNS', +}); +const SYNTHETICS_WAIT_TIMINGS_LABEL = i18n.translate('xpack.synthetics.wait', { + defaultMessage: 'Wait', +}); + +const SYNTHETICS_SSL_TIMINGS_LABEL = i18n.translate('xpack.synthetics.ssl', { + defaultMessage: 'SSL', +}); +const SYNTHETICS_BLOCKED_TIMINGS_LABEL = i18n.translate('xpack.synthetics.blocked', { + defaultMessage: 'Blocked', +}); +const SYNTHETICS_SEND_TIMINGS_LABEL = i18n.translate('xpack.synthetics.send', { + defaultMessage: 'Send', +}); +const SYNTHETICS_RECEIVE_TIMINGS_LABEL = i18n.translate('xpack.synthetics.receive', { + defaultMessage: 'Receive', +}); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/network_timings_breakdown.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/network_timings_breakdown.tsx index 2413d917665d4..27ec3e6deffbb 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/network_timings_breakdown.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/network_timings_breakdown.tsx @@ -12,12 +12,12 @@ import { EuiSpacer, EuiTitle } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { ClientPluginsStart } from '../../../../plugin'; -export const NetworkTimingsBreakdown = () => { +export const NetworkTimingsBreakdown = ({ monitorId }: { monitorId: string }) => { const { observability } = useKibana().services; const ExploratoryViewEmbeddable = observability.ExploratoryViewEmbeddable; - const { checkGroupId, stepIndex } = useParams<{ checkGroupId: string; stepIndex: string }>(); + const { stepIndex } = useParams<{ checkGroupId: string; stepIndex: string }>(); return ( <> @@ -37,7 +37,7 @@ export const NetworkTimingsBreakdown = () => { dataType: 'synthetics', name: 'Network timings', selectedMetricField: 'network_timings', - reportDefinitions: { 'monitor.check_group': [checkGroupId] }, + reportDefinitions: { 'monitor.id': [monitorId] }, time: { from: 'now-24h/h', to: 'now', diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/step_detail_page.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/step_detail_page.tsx index 999d805d6167c..af7e8dfe9ced2 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/step_detail_page.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/step_detail_page.tsx @@ -16,8 +16,10 @@ import { EuiLoadingSpinner, EuiSpacer, } from '@elastic/eui'; +import { BreakdownLegend } from './components/timings_breakdown/breakdown_legend'; import { WaterfallChartContainer } from './components/network_waterfall/step_detail/waterfall/waterfall_chart_container'; import { ObjectWeightList } from './components/object_weight_list'; +import { NetworkTimingsDonut } from './components/network_timings_donut'; import { NetworkTimingsBreakdown } from './network_timings_breakdown'; import { ObjectCountList } from './components/object_count_list'; import { StepImage } from './components/step_image'; @@ -73,10 +75,13 @@ export const StepDetailPage = () => { - {/* TODO: Add breakdown of network timings donut*/} + + + + - + From b9da846ed99a33cb8041e82be2a345a7e924572b Mon Sep 17 00:00:00 2001 From: Ying Mao Date: Fri, 4 Nov 2022 10:22:16 -0400 Subject: [PATCH 21/31] [Response Ops][Task Manager] Increasing buckets returned by schedule interval aggregation in TM health workload agg. (#144562) * Increasing buckets returned by schedule interval * Unskipping test * Increasing agg size more --- .../server/monitoring/workload_statistics.test.ts | 1 + .../task_manager/server/monitoring/workload_statistics.ts | 4 ++-- .../test_suites/task_manager/health_route.ts | 3 +-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/task_manager/server/monitoring/workload_statistics.test.ts b/x-pack/plugins/task_manager/server/monitoring/workload_statistics.test.ts index 947f8e397a2cf..f60531886453f 100644 --- a/x-pack/plugins/task_manager/server/monitoring/workload_statistics.test.ts +++ b/x-pack/plugins/task_manager/server/monitoring/workload_statistics.test.ts @@ -123,6 +123,7 @@ describe('Workload Statistics Aggregator', () => { schedule: { terms: { field: 'task.schedule.interval', + size: 100, }, }, nonRecurringTasks: { diff --git a/x-pack/plugins/task_manager/server/monitoring/workload_statistics.ts b/x-pack/plugins/task_manager/server/monitoring/workload_statistics.ts index c79a5660b20f7..bacd05dcb6a06 100644 --- a/x-pack/plugins/task_manager/server/monitoring/workload_statistics.ts +++ b/x-pack/plugins/task_manager/server/monitoring/workload_statistics.ts @@ -62,7 +62,7 @@ export interface WorkloadAggregation { }; }; schedule: { - terms: { field: string }; + terms: { field: string; size: number }; }; idleTasks: { filter: { @@ -141,7 +141,7 @@ export function createWorkloadAggregator( }, }, schedule: { - terms: { field: 'task.schedule.interval' }, + terms: { field: 'task.schedule.interval', size: 100 }, }, nonRecurringTasks: { missing: { field: 'task.schedule' }, diff --git a/x-pack/test/plugin_api_integration/test_suites/task_manager/health_route.ts b/x-pack/test/plugin_api_integration/test_suites/task_manager/health_route.ts index 6a2cfa6c71323..1bd158019c6f4 100644 --- a/x-pack/test/plugin_api_integration/test_suites/task_manager/health_route.ts +++ b/x-pack/test/plugin_api_integration/test_suites/task_manager/health_route.ts @@ -145,8 +145,7 @@ export default function ({ getService }: FtrProviderContext) { }); }); - // https://github.com/elastic/kibana/issues/144558 - it.skip('should return the task manager workload', async () => { + it('should return the task manager workload', async () => { const health = await getHealth(); const { status, From dd0e1f0f5e06e54609e1ec1a364637d1e3659bf1 Mon Sep 17 00:00:00 2001 From: Jonathan Budzenski Date: Fri, 4 Nov 2022 09:23:31 -0500 Subject: [PATCH 22/31] update codeowners --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index caf16d1050725..01f4bd562a9e0 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -950,7 +950,7 @@ packages/kbn-plugin-helpers @elastic/kibana-operations packages/kbn-react-field @elastic/kibana-app-services packages/kbn-repo-source-classifier @elastic/kibana-operations packages/kbn-repo-source-classifier-cli @elastic/kibana-operations -packages/kbn-rule-data-utils @elastic/apm-ui +packages/kbn-rule-data-utils @elastic/security-detections-response @elastic/actionable-observability @elastic/response-ops packages/kbn-safer-lodash-set @elastic/kibana-security packages/kbn-securitysolution-autocomplete @elastic/security-solution-platform packages/kbn-securitysolution-es-utils @elastic/security-solution-platform From c4ad1be10df5ebc5391541d2e41aa12e59995eb3 Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Fri, 4 Nov 2022 15:27:47 +0100 Subject: [PATCH 23/31] Fix nested formatter for terms (#144543) * fix nested formatter for terms * fix tests * fix * fix tests --- src/plugins/data/common/search/aggs/buckets/terms.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/plugins/data/common/search/aggs/buckets/terms.ts b/src/plugins/data/common/search/aggs/buckets/terms.ts index 8314d2cd532de..7c2b6ad062a55 100644 --- a/src/plugins/data/common/search/aggs/buckets/terms.ts +++ b/src/plugins/data/common/search/aggs/buckets/terms.ts @@ -79,9 +79,13 @@ export const getTermsBucketAgg = () => id: 'terms', params: { id: format.id, + ...(format.params + ? { + params: format.params, + } + : {}), otherBucketLabel: agg.params.otherBucketLabel, missingBucketLabel: agg.params.missingBucketLabel, - ...format.params, }, }; }, From b5ee95d0530a9553857197702a17083e4674fbd5 Mon Sep 17 00:00:00 2001 From: "Christiane (Tina) Heiligers" Date: Fri, 4 Nov 2022 08:13:30 -0700 Subject: [PATCH 24/31] Read coreApp assets directly from package (#144492) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../core-apps-server-internal/BUILD.bazel | 15 +- .../assets/favicons/favicon.distribution.ico | Bin .../assets/favicons/favicon.distribution.png | Bin .../assets/favicons/favicon.distribution.svg | 0 .../{src => }/assets/favicons/favicon.ico | Bin .../{src => }/assets/favicons/favicon.png | Bin .../{src => }/assets/favicons/favicon.svg | 0 .../assets/fonts/inter/Inter-Black.woff | Bin .../assets/fonts/inter/Inter-Black.woff2 | Bin .../assets/fonts/inter/Inter-BlackItalic.woff | Bin .../fonts/inter/Inter-BlackItalic.woff2 | Bin .../assets/fonts/inter/Inter-Bold.woff | Bin .../assets/fonts/inter/Inter-Bold.woff2 | Bin .../assets/fonts/inter/Inter-BoldItalic.woff | Bin .../assets/fonts/inter/Inter-BoldItalic.woff2 | Bin .../assets/fonts/inter/Inter-ExtraBold.woff | Bin .../assets/fonts/inter/Inter-ExtraBold.woff2 | Bin .../fonts/inter/Inter-ExtraBoldItalic.woff | Bin .../fonts/inter/Inter-ExtraBoldItalic.woff2 | Bin .../assets/fonts/inter/Inter-ExtraLight.woff | Bin .../assets/fonts/inter/Inter-ExtraLight.woff2 | Bin .../fonts/inter/Inter-ExtraLightItalic.woff | Bin .../fonts/inter/Inter-ExtraLightItalic.woff2 | Bin .../assets/fonts/inter/Inter-Italic.woff | Bin .../assets/fonts/inter/Inter-Italic.woff2 | Bin .../assets/fonts/inter/Inter-Light.woff | Bin .../assets/fonts/inter/Inter-Light.woff2 | Bin .../assets/fonts/inter/Inter-LightItalic.woff | Bin .../fonts/inter/Inter-LightItalic.woff2 | Bin .../assets/fonts/inter/Inter-Medium.woff | Bin .../assets/fonts/inter/Inter-Medium.woff2 | Bin .../fonts/inter/Inter-MediumItalic.woff | Bin .../fonts/inter/Inter-MediumItalic.woff2 | Bin .../assets/fonts/inter/Inter-Regular.woff | Bin .../assets/fonts/inter/Inter-Regular.woff2 | Bin .../assets/fonts/inter/Inter-SemiBold.woff | Bin .../assets/fonts/inter/Inter-SemiBold.woff2 | Bin .../fonts/inter/Inter-SemiBoldItalic.woff | Bin .../fonts/inter/Inter-SemiBoldItalic.woff2 | Bin .../assets/fonts/inter/Inter-Thin.woff | Bin .../assets/fonts/inter/Inter-Thin.woff2 | Bin .../assets/fonts/inter/Inter-ThinItalic.woff | Bin .../assets/fonts/inter/Inter-ThinItalic.woff2 | Bin .../assets/fonts/inter/Inter-italic.var.woff2 | Bin .../assets/fonts/inter/Inter-roman.var.woff2 | Bin .../assets/fonts/inter/Inter.var.woff2 | Bin .../{src => }/assets/fonts/inter/LICENSE.txt | 0 .../{src => }/assets/fonts/readme.md | 0 .../assets/fonts/roboto_mono/LICENSE.txt | 0 .../fonts/roboto_mono/RobotoMono-Bold.ttf | Bin .../roboto_mono/RobotoMono-BoldItalic.ttf | Bin .../fonts/roboto_mono/RobotoMono-Italic.ttf | Bin .../fonts/roboto_mono/RobotoMono-Light.ttf | Bin .../roboto_mono/RobotoMono-LightItalic.ttf | Bin .../fonts/roboto_mono/RobotoMono-Medium.ttf | Bin .../roboto_mono/RobotoMono-MediumItalic.ttf | Bin .../fonts/roboto_mono/RobotoMono-Regular.ttf | Bin .../fonts/roboto_mono/RobotoMono-Thin.ttf | Bin .../roboto_mono/RobotoMono-ThinItalic.ttf | Bin .../{src => }/assets/legacy_dark_theme.css | 0 .../assets/legacy_dark_theme.min.css | 0 .../{src => }/assets/legacy_light_theme.css | 0 .../assets/legacy_light_theme.min.css | 0 .../core-apps-server-internal/src/core_app.ts | 8 +- .../assets/favicons/favicon.distribution.ico | Bin 15086 -> 0 bytes .../assets/favicons/favicon.distribution.png | Bin 5234 -> 0 bytes .../assets/favicons/favicon.distribution.svg | 4 - .../core_app/assets/favicons/favicon.ico | Bin 15086 -> 0 bytes .../core_app/assets/favicons/favicon.png | Bin 4335 -> 0 bytes .../core_app/assets/favicons/favicon.svg | 4 - .../core_app/assets/legacy_light_theme.css | 4419 ----------------- src/dev/build/build_distributables.ts | 3 +- src/dev/build/tasks/copy_source_task.ts | 1 - src/dev/build/tasks/replace_favicon.ts | 18 +- src/dev/precommit_hook/casing_check_config.js | 2 +- .../plugins/canvas/shareable_runtime/index.ts | 2 +- 76 files changed, 30 insertions(+), 4446 deletions(-) rename packages/core/apps/core-apps-server-internal/{src => }/assets/favicons/favicon.distribution.ico (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/favicons/favicon.distribution.png (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/favicons/favicon.distribution.svg (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/favicons/favicon.ico (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/favicons/favicon.png (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/favicons/favicon.svg (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-Black.woff (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-Black.woff2 (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-BlackItalic.woff (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-BlackItalic.woff2 (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-Bold.woff (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-Bold.woff2 (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-BoldItalic.woff (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-BoldItalic.woff2 (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-ExtraBold.woff (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-ExtraBold.woff2 (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-ExtraBoldItalic.woff (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-ExtraBoldItalic.woff2 (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-ExtraLight.woff (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-ExtraLight.woff2 (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-ExtraLightItalic.woff (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-ExtraLightItalic.woff2 (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-Italic.woff (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-Italic.woff2 (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-Light.woff (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-Light.woff2 (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-LightItalic.woff (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-LightItalic.woff2 (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-Medium.woff (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-Medium.woff2 (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-MediumItalic.woff (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-MediumItalic.woff2 (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-Regular.woff (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-Regular.woff2 (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-SemiBold.woff (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-SemiBold.woff2 (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-SemiBoldItalic.woff (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-SemiBoldItalic.woff2 (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-Thin.woff (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-Thin.woff2 (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-ThinItalic.woff (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-ThinItalic.woff2 (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-italic.var.woff2 (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter-roman.var.woff2 (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/Inter.var.woff2 (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/inter/LICENSE.txt (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/readme.md (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/roboto_mono/LICENSE.txt (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/roboto_mono/RobotoMono-Bold.ttf (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/roboto_mono/RobotoMono-BoldItalic.ttf (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/roboto_mono/RobotoMono-Italic.ttf (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/roboto_mono/RobotoMono-Light.ttf (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/roboto_mono/RobotoMono-LightItalic.ttf (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/roboto_mono/RobotoMono-Medium.ttf (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/roboto_mono/RobotoMono-MediumItalic.ttf (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/roboto_mono/RobotoMono-Regular.ttf (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/roboto_mono/RobotoMono-Thin.ttf (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/fonts/roboto_mono/RobotoMono-ThinItalic.ttf (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/legacy_dark_theme.css (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/legacy_dark_theme.min.css (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/legacy_light_theme.css (100%) rename packages/core/apps/core-apps-server-internal/{src => }/assets/legacy_light_theme.min.css (100%) delete mode 100644 src/core/server/core_app/assets/favicons/favicon.distribution.ico delete mode 100644 src/core/server/core_app/assets/favicons/favicon.distribution.png delete mode 100644 src/core/server/core_app/assets/favicons/favicon.distribution.svg delete mode 100644 src/core/server/core_app/assets/favicons/favicon.ico delete mode 100644 src/core/server/core_app/assets/favicons/favicon.png delete mode 100644 src/core/server/core_app/assets/favicons/favicon.svg delete mode 100644 src/core/server/core_app/assets/legacy_light_theme.css diff --git a/packages/core/apps/core-apps-server-internal/BUILD.bazel b/packages/core/apps/core-apps-server-internal/BUILD.bazel index adf8562deb1aa..94f52482c27d4 100644 --- a/packages/core/apps/core-apps-server-internal/BUILD.bazel +++ b/packages/core/apps/core-apps-server-internal/BUILD.bazel @@ -8,13 +8,6 @@ PKG_REQUIRE_NAME = "@kbn/core-apps-server-internal" SOURCE_FILES = glob( [ "**/*.ts", - "src/**/*.css", - "src/**/*.ttf", - "src/**/*.woff", - "src/**/*.woff2", - "src/**/*.ico", - "src/**/*.png", - "src/**/*.svg", ], exclude = [ "**/*.config.js", @@ -38,8 +31,16 @@ filegroup( srcs = SRCS, ) +ASSETS = glob(["assets/**/*"]) + +filegroup( + name = "assets", + srcs = ASSETS, +) + NPM_MODULE_EXTRA_FILES = [ "package.json", + ":assets" ] RUNTIME_DEPS = [ diff --git a/packages/core/apps/core-apps-server-internal/src/assets/favicons/favicon.distribution.ico b/packages/core/apps/core-apps-server-internal/assets/favicons/favicon.distribution.ico similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/favicons/favicon.distribution.ico rename to packages/core/apps/core-apps-server-internal/assets/favicons/favicon.distribution.ico diff --git a/packages/core/apps/core-apps-server-internal/src/assets/favicons/favicon.distribution.png b/packages/core/apps/core-apps-server-internal/assets/favicons/favicon.distribution.png similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/favicons/favicon.distribution.png rename to packages/core/apps/core-apps-server-internal/assets/favicons/favicon.distribution.png diff --git a/packages/core/apps/core-apps-server-internal/src/assets/favicons/favicon.distribution.svg b/packages/core/apps/core-apps-server-internal/assets/favicons/favicon.distribution.svg similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/favicons/favicon.distribution.svg rename to packages/core/apps/core-apps-server-internal/assets/favicons/favicon.distribution.svg diff --git a/packages/core/apps/core-apps-server-internal/src/assets/favicons/favicon.ico b/packages/core/apps/core-apps-server-internal/assets/favicons/favicon.ico similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/favicons/favicon.ico rename to packages/core/apps/core-apps-server-internal/assets/favicons/favicon.ico diff --git a/packages/core/apps/core-apps-server-internal/src/assets/favicons/favicon.png b/packages/core/apps/core-apps-server-internal/assets/favicons/favicon.png similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/favicons/favicon.png rename to packages/core/apps/core-apps-server-internal/assets/favicons/favicon.png diff --git a/packages/core/apps/core-apps-server-internal/src/assets/favicons/favicon.svg b/packages/core/apps/core-apps-server-internal/assets/favicons/favicon.svg similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/favicons/favicon.svg rename to packages/core/apps/core-apps-server-internal/assets/favicons/favicon.svg diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-Black.woff b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-Black.woff similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-Black.woff rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-Black.woff diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-Black.woff2 b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-Black.woff2 similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-Black.woff2 rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-Black.woff2 diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-BlackItalic.woff b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-BlackItalic.woff similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-BlackItalic.woff rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-BlackItalic.woff diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-BlackItalic.woff2 b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-BlackItalic.woff2 similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-BlackItalic.woff2 rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-BlackItalic.woff2 diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-Bold.woff b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-Bold.woff similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-Bold.woff rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-Bold.woff diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-Bold.woff2 b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-Bold.woff2 similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-Bold.woff2 rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-Bold.woff2 diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-BoldItalic.woff b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-BoldItalic.woff similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-BoldItalic.woff rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-BoldItalic.woff diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-BoldItalic.woff2 b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-BoldItalic.woff2 similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-BoldItalic.woff2 rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-BoldItalic.woff2 diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-ExtraBold.woff b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-ExtraBold.woff similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-ExtraBold.woff rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-ExtraBold.woff diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-ExtraBold.woff2 b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-ExtraBold.woff2 similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-ExtraBold.woff2 rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-ExtraBold.woff2 diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-ExtraBoldItalic.woff b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-ExtraBoldItalic.woff similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-ExtraBoldItalic.woff rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-ExtraBoldItalic.woff diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-ExtraBoldItalic.woff2 b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-ExtraBoldItalic.woff2 similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-ExtraBoldItalic.woff2 rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-ExtraBoldItalic.woff2 diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-ExtraLight.woff b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-ExtraLight.woff similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-ExtraLight.woff rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-ExtraLight.woff diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-ExtraLight.woff2 b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-ExtraLight.woff2 similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-ExtraLight.woff2 rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-ExtraLight.woff2 diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-ExtraLightItalic.woff b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-ExtraLightItalic.woff similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-ExtraLightItalic.woff rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-ExtraLightItalic.woff diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-ExtraLightItalic.woff2 b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-ExtraLightItalic.woff2 similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-ExtraLightItalic.woff2 rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-ExtraLightItalic.woff2 diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-Italic.woff b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-Italic.woff similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-Italic.woff rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-Italic.woff diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-Italic.woff2 b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-Italic.woff2 similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-Italic.woff2 rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-Italic.woff2 diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-Light.woff b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-Light.woff similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-Light.woff rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-Light.woff diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-Light.woff2 b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-Light.woff2 similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-Light.woff2 rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-Light.woff2 diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-LightItalic.woff b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-LightItalic.woff similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-LightItalic.woff rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-LightItalic.woff diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-LightItalic.woff2 b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-LightItalic.woff2 similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-LightItalic.woff2 rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-LightItalic.woff2 diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-Medium.woff b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-Medium.woff similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-Medium.woff rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-Medium.woff diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-Medium.woff2 b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-Medium.woff2 similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-Medium.woff2 rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-Medium.woff2 diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-MediumItalic.woff b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-MediumItalic.woff similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-MediumItalic.woff rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-MediumItalic.woff diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-MediumItalic.woff2 b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-MediumItalic.woff2 similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-MediumItalic.woff2 rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-MediumItalic.woff2 diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-Regular.woff b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-Regular.woff similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-Regular.woff rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-Regular.woff diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-Regular.woff2 b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-Regular.woff2 similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-Regular.woff2 rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-Regular.woff2 diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-SemiBold.woff b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-SemiBold.woff similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-SemiBold.woff rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-SemiBold.woff diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-SemiBold.woff2 b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-SemiBold.woff2 similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-SemiBold.woff2 rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-SemiBold.woff2 diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-SemiBoldItalic.woff b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-SemiBoldItalic.woff similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-SemiBoldItalic.woff rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-SemiBoldItalic.woff diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-SemiBoldItalic.woff2 b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-SemiBoldItalic.woff2 similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-SemiBoldItalic.woff2 rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-SemiBoldItalic.woff2 diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-Thin.woff b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-Thin.woff similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-Thin.woff rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-Thin.woff diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-Thin.woff2 b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-Thin.woff2 similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-Thin.woff2 rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-Thin.woff2 diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-ThinItalic.woff b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-ThinItalic.woff similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-ThinItalic.woff rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-ThinItalic.woff diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-ThinItalic.woff2 b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-ThinItalic.woff2 similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-ThinItalic.woff2 rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-ThinItalic.woff2 diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-italic.var.woff2 b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-italic.var.woff2 similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-italic.var.woff2 rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-italic.var.woff2 diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-roman.var.woff2 b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-roman.var.woff2 similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter-roman.var.woff2 rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter-roman.var.woff2 diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter.var.woff2 b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter.var.woff2 similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/Inter.var.woff2 rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/Inter.var.woff2 diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/LICENSE.txt b/packages/core/apps/core-apps-server-internal/assets/fonts/inter/LICENSE.txt similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/inter/LICENSE.txt rename to packages/core/apps/core-apps-server-internal/assets/fonts/inter/LICENSE.txt diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/readme.md b/packages/core/apps/core-apps-server-internal/assets/fonts/readme.md similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/readme.md rename to packages/core/apps/core-apps-server-internal/assets/fonts/readme.md diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/roboto_mono/LICENSE.txt b/packages/core/apps/core-apps-server-internal/assets/fonts/roboto_mono/LICENSE.txt similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/roboto_mono/LICENSE.txt rename to packages/core/apps/core-apps-server-internal/assets/fonts/roboto_mono/LICENSE.txt diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/roboto_mono/RobotoMono-Bold.ttf b/packages/core/apps/core-apps-server-internal/assets/fonts/roboto_mono/RobotoMono-Bold.ttf similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/roboto_mono/RobotoMono-Bold.ttf rename to packages/core/apps/core-apps-server-internal/assets/fonts/roboto_mono/RobotoMono-Bold.ttf diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/roboto_mono/RobotoMono-BoldItalic.ttf b/packages/core/apps/core-apps-server-internal/assets/fonts/roboto_mono/RobotoMono-BoldItalic.ttf similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/roboto_mono/RobotoMono-BoldItalic.ttf rename to packages/core/apps/core-apps-server-internal/assets/fonts/roboto_mono/RobotoMono-BoldItalic.ttf diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/roboto_mono/RobotoMono-Italic.ttf b/packages/core/apps/core-apps-server-internal/assets/fonts/roboto_mono/RobotoMono-Italic.ttf similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/roboto_mono/RobotoMono-Italic.ttf rename to packages/core/apps/core-apps-server-internal/assets/fonts/roboto_mono/RobotoMono-Italic.ttf diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/roboto_mono/RobotoMono-Light.ttf b/packages/core/apps/core-apps-server-internal/assets/fonts/roboto_mono/RobotoMono-Light.ttf similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/roboto_mono/RobotoMono-Light.ttf rename to packages/core/apps/core-apps-server-internal/assets/fonts/roboto_mono/RobotoMono-Light.ttf diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/roboto_mono/RobotoMono-LightItalic.ttf b/packages/core/apps/core-apps-server-internal/assets/fonts/roboto_mono/RobotoMono-LightItalic.ttf similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/roboto_mono/RobotoMono-LightItalic.ttf rename to packages/core/apps/core-apps-server-internal/assets/fonts/roboto_mono/RobotoMono-LightItalic.ttf diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/roboto_mono/RobotoMono-Medium.ttf b/packages/core/apps/core-apps-server-internal/assets/fonts/roboto_mono/RobotoMono-Medium.ttf similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/roboto_mono/RobotoMono-Medium.ttf rename to packages/core/apps/core-apps-server-internal/assets/fonts/roboto_mono/RobotoMono-Medium.ttf diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/roboto_mono/RobotoMono-MediumItalic.ttf b/packages/core/apps/core-apps-server-internal/assets/fonts/roboto_mono/RobotoMono-MediumItalic.ttf similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/roboto_mono/RobotoMono-MediumItalic.ttf rename to packages/core/apps/core-apps-server-internal/assets/fonts/roboto_mono/RobotoMono-MediumItalic.ttf diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/roboto_mono/RobotoMono-Regular.ttf b/packages/core/apps/core-apps-server-internal/assets/fonts/roboto_mono/RobotoMono-Regular.ttf similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/roboto_mono/RobotoMono-Regular.ttf rename to packages/core/apps/core-apps-server-internal/assets/fonts/roboto_mono/RobotoMono-Regular.ttf diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/roboto_mono/RobotoMono-Thin.ttf b/packages/core/apps/core-apps-server-internal/assets/fonts/roboto_mono/RobotoMono-Thin.ttf similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/roboto_mono/RobotoMono-Thin.ttf rename to packages/core/apps/core-apps-server-internal/assets/fonts/roboto_mono/RobotoMono-Thin.ttf diff --git a/packages/core/apps/core-apps-server-internal/src/assets/fonts/roboto_mono/RobotoMono-ThinItalic.ttf b/packages/core/apps/core-apps-server-internal/assets/fonts/roboto_mono/RobotoMono-ThinItalic.ttf similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/fonts/roboto_mono/RobotoMono-ThinItalic.ttf rename to packages/core/apps/core-apps-server-internal/assets/fonts/roboto_mono/RobotoMono-ThinItalic.ttf diff --git a/packages/core/apps/core-apps-server-internal/src/assets/legacy_dark_theme.css b/packages/core/apps/core-apps-server-internal/assets/legacy_dark_theme.css similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/legacy_dark_theme.css rename to packages/core/apps/core-apps-server-internal/assets/legacy_dark_theme.css diff --git a/packages/core/apps/core-apps-server-internal/src/assets/legacy_dark_theme.min.css b/packages/core/apps/core-apps-server-internal/assets/legacy_dark_theme.min.css similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/legacy_dark_theme.min.css rename to packages/core/apps/core-apps-server-internal/assets/legacy_dark_theme.min.css diff --git a/packages/core/apps/core-apps-server-internal/src/assets/legacy_light_theme.css b/packages/core/apps/core-apps-server-internal/assets/legacy_light_theme.css similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/legacy_light_theme.css rename to packages/core/apps/core-apps-server-internal/assets/legacy_light_theme.css diff --git a/packages/core/apps/core-apps-server-internal/src/assets/legacy_light_theme.min.css b/packages/core/apps/core-apps-server-internal/assets/legacy_light_theme.min.css similarity index 100% rename from packages/core/apps/core-apps-server-internal/src/assets/legacy_light_theme.min.css rename to packages/core/apps/core-apps-server-internal/assets/legacy_light_theme.min.css diff --git a/packages/core/apps/core-apps-server-internal/src/core_app.ts b/packages/core/apps/core-apps-server-internal/src/core_app.ts index 97c9eadd75707..3e094fab889a6 100644 --- a/packages/core/apps/core-apps-server-internal/src/core_app.ts +++ b/packages/core/apps/core-apps-server-internal/src/core_app.ts @@ -6,7 +6,6 @@ * Side Public License, v 1. */ -import Path from 'path'; import { stringify } from 'querystring'; import { Env } from '@kbn/config'; import { schema } from '@kbn/config-schema'; @@ -202,8 +201,13 @@ export class CoreAppsService { }); } + // After the package is built and bootstrap extracts files to bazel-bin, + // assets are exposed at the root of the package and in the package's node_modules dir private registerStaticDirs(core: InternalCoreSetup | InternalCorePreboot) { - core.http.registerStaticDir('/ui/{path*}', Path.resolve(__dirname, './assets')); + core.http.registerStaticDir( + '/ui/{path*}', + fromRoot('node_modules/@kbn/core-apps-server-internal/assets') + ); core.http.registerStaticDir( '/node_modules/@kbn/ui-framework/dist/{path*}', diff --git a/src/core/server/core_app/assets/favicons/favicon.distribution.ico b/src/core/server/core_app/assets/favicons/favicon.distribution.ico deleted file mode 100644 index b466b3b4f4eb3dada6c419d23a74439e7924579e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15086 zcmche33MG*8OJ9rDz2>pwq$1BOWu2J(ITRC!!2{m$Hb^ z0tQ+|mI`|4K|Jk&B1=F@dt?&|($-j71d_C&P13%;@%O)Tr%tBx<}C^2oSVCR%l+>5 z-S7MEJjZEqCOZ4>>yWoO*G_YscR7yJ)@JLI9p@?9CX)+(!Y+<;HVAux1Br7SN$uvZ z6lUY`f94*0yr$^;#}#w_RmGh5FsY9ekT#MYEBW5<$&dFu?+xS8-+1xJ<#Mkt<@~u; zPRSdkGG&cnORP<>&7^txe16aIlA&2XrJQ>hvOHtu+g8kbHx=^UQ8V)S_Bc&o;xi;JVXGIq#o_kMCV99;H(06|@~=&Wi8#6qRz`0{S~*=FFKdZ>FCl4g25_ zcvcEI?}cfe_wFRTk@{Y)yBoZgn=$0Pi{SZ`El1~md#t{ym}`AsBm9%Ng+gHx{MM5y zrCjT$lkjHh(>>3H-_xO-?uJs{|9Y`F<&EN{IdAv<53nYSLbx~7p38l#nSMkAkMqQ* z;Cojz%Oj1Bv-BM+|5wxCYSUQPCz__^>3dH+{gcxfFsX*gMJ(5zvNAJ4)W3rzNhkw51x6(8Am=!`>Ylg*?%ZkvTm zhba9GeYIb`eX_3iLNiz|elvLRe~u*k^hr`Ar*hd@*yR3YdzWXiY3Fu>??#g<2G3K^t4A^)F$7wiE2LT%<4I%G$XU&@R zGTCd?pC!qL_%-+w;xx^cjqeuv5ySP`;Za|*kB~?EYmMwzwKJBz?ObmzwRxQpuJX3F z*1d$QF-Vt1G;y3p%i6=@CqJ%HTHzzd^`bBM{^x9cNyyJVHjSUP86OJA;4Re|NyDqB zZF(+OfKNYZQ)%kdJ?f!J;#j>J&L{J2409^AhrLSCd~Pnd(`#q=erp_7 zt*kw&GaB~e&8~*mWcvhU31bhT|8DF~`dTA9G>s?c=3FbwnzVI5-pQQJ1Hn5-`&08^ z@teO0xi*Ue~F4?ZTUS~yiC-nzyyL3#Hi0`3qm>>Ggj3LBj zYP2l=^z%@?bh^*MkKgx_w=Dfaet~>E)?%vo!Q0pYjm8G*l|^_uTlCx42#ui&-&CHF z{Zeh+!o6f{r_2~aqkYHm?H#){-d3y3etsQeR?PW^EL_$??-^BN2wAlC!r-s7`)s}V z!b7)ClU%aXvgnGQS2FV37(y0qGcer;@Yi{KxDk5AGOS#;)}U(vZ-9ODd=0#&z|!-Q zqnY?ObnA8Yr8l!W=X@&d7bBob}Tu1?O5?-ZZ_x)kBL|4-`n_!c%{18qwPYHiQA?5#1XHo+`Q%4 z^~NtcJq!0mfK5bx6U!jqD*LgP?uulX*5>Yu9{YxfTIOVb?d|PTkV$7kv4QBERLynIAp5!Xu2-_Z z7prdG4~hAhHNXaDEPbR+B;pPJ1IYY4&gkJ|d1DKLmLLcmCm41*Og>P_o4hyZG5N}% z_Z-2ygMk+19l`K0d8H%RUg;w53d)s^Fb~MfK~PTQ6r%Zur>jFbZx!dLn5diY9UB6U4)|7uQ1|*vC^qDO(~oRZ#XM)*xb?(hzV*G-SIA$L{;VZ~d23VLvcXuR z_!3um2Yr>3dMk|Y8$CC#R{zk?NB=FVg_j0rj(3HATUwlkyY66M`Ys|f9tO_Cx+~N8 z*V6|5g9YC`A&G14cGOAs_lD5-DR!EqueToFDgI?ieA!-h{F!@7{WtO+p6tiIpZ=Zp z35r9?cC+7%{s-QJs&`g7Q?lXFbE_5mPV%j{&N=)D{TTmS*>fI*Ygg zwoP)6N{<4QJ+3#r=Spqvd+O~ojtA}ejNwtecc=LXdK(1iA!N8EqO-B;5zgrM!Z@pU zp==lG`$stSfvIE%-`+cV0<+`TKH zxhDf>2ME0Rq+9JbyUTX~VgR?%F7qdWIJns?l@=$gsU&7u8i!zb_llzqFmxeK|cb%(^*>{PTqtnP8W?Hsrh zLaZUW3uOc7Z4~@pLbr+jpCUhbpD9yb9ieMq(`g`sCL}^wn~W4cv7k z-D}IKAJJLm9K&OxjW2HjZ`Ah?mVXPfuVmhct@}$D&n4CRjoOWF2*3UKQPfr|*LgzL zZKRXqxU`={|1apR9Qlp}zNOatg!T(~eUV=q=a*I1JV7_id6(a~t36kG+daV2$-i7m zTA}yPBrmn;ofY^hz0D@!_0;V*Hu5nB7{}_kog{k2OlZFoxZZbXOCM=XD9bmI{UX|} zF`4V>b`*}C=XIS`_Kd#Kl@6jG`Kaqyqib|maE|mIHbLh~b2o}<0~Kor4c8!kVr@0}`Px8;Ihc*rGf;GP5iSr2WWaC@Oeo@R0oontlz55NKyMGYJuU0m5 z7RI{!YTZX^Ji>Ph-rd6Zsj(X=e^N5Amv1Pxw)$ywYST9s==b};?brQP4X>GY)*`xR zrP~+FFGV*T#=bp@@)@+Avhj-jrpSq3ZhniifWG9H>n@kwsozLlDLXWUW~ZiL zSr7y{#T*}-U(h?6bh>Pt=zCN7 znTB`lwoU*w*r`_dG-_=?!Sq+Cl<)+ jC_O;iQ;u_L&T;1OCB*4Nj&t)i$9W=_Hq%zgJI?({R$ zBOFHM__QdBa~!AIQ8G?yR}{q>e_s|waj*XSq1vtu?@Jb$(4GMTPl}?r#BnTi1}l(! z`A}__(OwY8$b|L)kaz|nb1biGC`-Oj$3wMU^!ZwvkO?h>Q8_*VffbR@B04oi?s-uZ zHxJeJK7#XcicDz7fHj_i$WrcvE8KzD$+#q$(2f9$d{Y#~haR53^0%*2Aa*8nM}Ww) zo>*iP6tSm$c11FwJ783fC$P#c1HBdgG+9eqiO&Yta7BJP{#4>f<+f4aT7EheA@CsROdhGgA0-g%|Hhi;}*VXG^yxOIaZ{; zYT=To)#Wnww0b7A0U-0za@oFx3>K|g(304S)U$_bI~P2)PRN8NFe=CAATxKF-r$D! zCXgDH;~9u;Sdw{zfT{O&5zy7=7S=jCQb$i{T;xehZFQrSP_nAbV6E<%H}&g7wVhd>Q`CUb zSXjgiQIR@ILgS)dfyl1X$rY^6yvdqc1c1>8M_tgOF6C`3aYIyu)`%=!;PVwe?+ce? zRE`%6Ke89{l?zzt?$KP6qtGW%0~hayr)srN%B?_z{|J1)iOkhd$gF@2;YY?x)harN zWesWp)D@ZA*>+H{nY*}AmN>8Rc9{BDhE&I8cd&BU9ZznD_IaiwIEOjI9SLS-Vh2{fwITMY9;)rB@1NpLw!@Rnd17~Xx<%@5;Xa(> zfuYVJXtW+PkeD)MNK5$KUg1-R=IrvQbzae>3J(hPuq=lt&)EQ3QpzYO%zSIpUI>kP z43qDwbl!81YQj13Z-ZAfn3!QTYr-+Zk~@Vj3vCLlb^($WR8W&u4F=$PnC@*_godhN z3c$RQ8G#{%Y@wMzdb}cDeGCqGfe#C93Jg96NLo%0o2 z^Jf3qArK%^R{9JzJK~VG(59s(RKEvGAI<)AJ49inr3p=yW8MW!DN~9|w$LpAD@`dL zUXoN|goe98AxKJ@vGip^w+FR@=a|8X&XBaw6mhD6*4Y#gCf5YqBTPohq%L)aB%!I3 z4>=Yg2ZTa^G1w5Fo~(t=giaTf+fkyhNeq&NZmin~Twk06LRpyZt*F}}LTJNNNG(aC z$N`}|kR+otX;D2|%0g3w4w;1`m%F^p${8pt-Ah7K2&p1a7js4YTZSDdLfh;Zvc}K| zP5E!xI=cgTEhTHDr3g*A6(O6EP!>At&yK)w-Nf7u5keb&ke4EreIQV!cFbf8?G{w< z-#ZH(Bgh9Sw<>TBYL)Jng$9~}EYYBV0Cf?ANr?#~$ciUP=*A!9t2TBIIUw|lAo8pv zp{XTYyh!B$C=EIj+An(PLsNwI+VcW35w&wB6WTAtR_NcQK3MI`8Oh1^p{1MxE)pYXm7$W;^El{QSdI91*h>m6d6zf(eYm{MA!Cin+@ zUbRQ?ww5%PjK+ny35`A%Hv(PwOC0a;Jv)$l4T5vE<4ov*pcA26OiSvDV~|@NUq|A(2(2GFRu(dvSNs>d5ns{qMGe;8WSYamMi=`bFzCI+=;kh6w4C1!X7NZDi93*lL z{QswaLpoe1xer$+`_FP{j9VmEMb=0POET{;N}|)wZV+52xr>Qb`v^LMELC8j>7NZh zPjucRm(Xh_nMLNJ6wmd{I>BA|;n!#fo8bsHLpm{c-RUZ6B(#Ok>~&%kR*g%IG|w&k@Q-LTn9=Rp+lmGIP^)sq2a^+ZFqmwQ&zP=lX@tFj2}w{EyMx}J6P-1EB!%2<0RLHK&&?-gBjK%Tj>@+ zT(c0!E3}Tqn(CoB1xC{zHD)mdemO9-1Xe$;Sg^6&=B7#;)@^n+y&^O|#N^n2?vvaF zzl>@mQ!)k#WdJA-UNU2pTBcLHdTY_pM;X+m?R`09p-uivsJSRzk*%}?K$iQ)B=fDV zIV<7dq1s-8*c^+kzT>;i6s;FNG-DRG@|#clTK_OA$4i5}_cpgPXoh7C&+S9CC5dSH zd8{~R-$EO$SkH@jq8bv}Cm^u4A)nEzBB}L;X|4a__|#7pnjzCAA#aV!@x3A7{UeX1 zcm@=&1v7EAgO+Ti7~wnSj4gXRjL&YoKe~lBStqYMwFQxVX(lv{nM>x&Hu9%h^&hJ3 z1U@$f9GlY09NdKrYu*v$VtFWF_HR=GCGfhh73bR zt*Ke9>`N1XIA9~oox93OFiHKXNzSV+G-aK4frtD^z%(RsD%rz0WeGvXV?R;DS*P>oK&?dqwP2T@dxVM&)>6 zQTqAOSEd-{6?eo-Uah1iLT?h^70vl=C6-}D?5mWBt;upG{kOns_9j48;*7D9KHU=& zp_APejV0D*cf~O>W&f!6_FdYutd)qSke z1DTi1jmI0*?}RjN#(1ax%h8b9WWirtJ8WI{4%J{wX!+3tfi72LUP4E@cB-l?Z{@8eyUQ>h+-&HAo_USO@vOu<r~um&p+t`_wpOZk_p3@4@b!_YML`ry0nWJF@!}{8NNJ zIWk0!K?cpYg~h%%CrhmIH?>{NrW)QRlsM;_*sU{=wmY&_Yk?k?Hc?qWbao4cO z{%u_Qi`bs8$n-}CV%MqlA8k_WXq3oxv%bbA%UOVY0FMmWz~~8Wnf-H4W*utj22uW{ z0u)2KmO`CcXEj=}tV>ZbL!WECNkS`?V}fO>3DNF?wv?qr8*Lu~&TrCjc4GlQeZKGS zw~*zmcVx#1Od&o9MQC+V{vpoWYu{%s5Xmo?L@_o!@o>IVNPb;X?-d@71p;<%qr~3G zavYF^R(&}P9r{-Ye4;_y>|YFk3vtzPP*Uy6aFvWcHP$3yO0Lwh9py(~#8mrhxg%M8 ztB@_U{%&0ZNE=x$rMh;Ki#4H5epM8tu-uXCZL3flXaVFO9RtWF+{RG)=^J`0Fe;@O zyh)=)_OF-0kCs}WI+*wsm7C=fh6az7o+*rWTfc?I+PWQ8XlSYR(~hb2=-e#FAa_{l zgf=x_d9`KS2P`z!WFmPjwQkcOT;aN>y}NBd?ty(GG_(1N*RgGu*}py&*s!1lkZ+g) zWYSXzU{EQUa=qX1`~M^XLlr?~^<;kOrgqN`)+H@8nI!vpfhLNu@j+-=b+?<=^Hm8%AMtXgJCy^jva`z1i^z>=fTam zVUU^RN@qfAC)9Q~b558z0<-+L39CJl`|MxBeGrYSxHCf60I_Ebi=9m4lbB#Z4ih#t zxz(Q%iW45d1=9$s5rf7~Ud{w?`L!CA(sg==cHBk6aEU#g+$q}%pX&M?DQgUw^OmFoC1D#wN9hu0*3 zA|W2Msb!3H3%8W*&x;Y-uuUuL%yJ0XG4?_y?5G@XK<-J4K=t6v8xtfg^dLtrM*!-& zzl92NiQ`;oZexwJ7N5UErnpsnCGB!#cmx7*$`Y=%sjQFc5>`^3;9Z(XcEueUOSWFY zB?(Q{MrR8x1IjvAhlqmzx6pTeAaK)3?jjRRVFO>ev+5O!(AkHU0YzxGjtpWwkqc6w zPVlb1_i9uaapx=-kzJ0oKLRxHet<@H6@GsGiDREaD@@sgN9%Y;q`F=l3)YIa=7ey@;S zj&wkgB)UYF)MPbDLQ@wpnlW)Hz|=lB;2uKn91tV4As;Wchpf9z28@6( zS@-0|K?IngRDW85P-EG!q`Kam1%?;1(L0M?80U=zCKMgMvzsKGP zjU-D&yyRUjSmJ}xCCQs)r%gDcuuF>20DHu3h7pvD=514~MrKoYC95u?ZQ+&B@Si9v zeTEM78D<3cpW$XSwJXrE@-?X;#1CXPvewu46h}?uw%--Z5CtQ2!CyXin1VD| zQadKIB!bVL4BD&_$(FB%m#O7-IdJ7;&LFdzpJKX}lBmb81$7aFTId?oJVOnGv(&K6 zbH-HOr-@Nm_2wRXpFCy&+f1yIKrDpj&Zr&?sV&@$gY&N;*$!~(g zwuMAJ$bKm?7sVx_B6MLtt9s)*6D0|zHea}Ky|4l3w7x9@dDC(1kszckttS zTd8N^ViZ}%q!A^d3wu%*s1KR-=|&^)yJA}90xQxqlernu61uPp6m>)wc^?9{D_vRq zHY=ZbsEC@-h5d4@BRXQkB2QY#X`N?a4+YT^y0A+y9KtQ8mIe!MpfJo(7i?QtbRA35 zq7Uc=p=)57Hf_XgLWM2#b00paCX-EDYQPn&a<5c|(C8JRi*7E6j;hvGp{;gyOSDqU z%Z`<5MRqaTqj!X^fn6Im#pWigkbc*XCY)$31TIl>=_19Pt#U{7me9rXvVPT~_&he$ zTl{abRqlpf6S@Xc=2tzP3UKRdi~kUi1fgqy*wY?Z?AjvFQ%T#$f}{vt1FpyvM@%yj zHz4vNTVxp|NoXCYUaJpR0i+GQ%7sHm@`Tm_$!`K>LdxIXX_DX~yA*ygC_?W81V4xD scCN{B97|s9NqmpHs55~Bq9}_00e?uvBRsGQ9smFU07*qoM6N<$f<%wLlK=n! diff --git a/src/core/server/core_app/assets/favicons/favicon.distribution.svg b/src/core/server/core_app/assets/favicons/favicon.distribution.svg deleted file mode 100644 index 2d02461a0b8f9..0000000000000 --- a/src/core/server/core_app/assets/favicons/favicon.distribution.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/core/server/core_app/assets/favicons/favicon.ico b/src/core/server/core_app/assets/favicons/favicon.ico deleted file mode 100644 index 7ac743a2d1fe4660ca6dd3675197f7c049b3326a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15086 zcmeHO3zSt=89u{gS`iRPz&-n%bLZYWK(R6&y)$Qezbs2bGc9`()mm2e0JFLzEkUu6 z%#_GREDgvCA0*adK}|8{f|(-42Md{TgwaA~285ZB%bdP%Kkl4+xcA(1FN0)x*V?lm z|MTqg?|=XM-)AhV#;UcZPq$DftyT4w^*YP4l1bekV_A=4Yz%6`=f1$Qt^mSR;DE&X zBnrpnFQckre>1KGll%4VHH)4E{vW@;3$N3`qJ422#=b)45yZpwA8pgf~Lp66_=k2QrQuvQ$=0kRs> z;$60IJ;^rKRw=#B_;BivdH#@;i**>(pJU-4*8RVX4$yfC;j}@F9l_eTll@twjdoyFhs=u3fGvz}50`fQW&oz;9#k^2?+USsW-C2@OtrM<^z9~~qeJRKA&TbgO zJKFAsQU5)sO_=Z!B~#oL)IZYxJ@GJU_=B#0%T2g-u`c}Uy6(#$=dVVV z(VxDMuwVhsHN?xf?kmX!e)u9or|bP0?MpMRvor+D``ya*cWw&mL0<=7`l__&d=2Zc zqd*SUa}YP!1|Iacx0^Ap*#cVmZ1!xz;ZxrohM9il`WL=G!{RRXppS!)ZXTKGGWFPmzsHfoG4qy3uiR+2G&0Zfx6NEALPI>kZ;6I;G^27t! zBa%U!xNYwFnnx>Q@Sma0IPz2F=o5*=i-Eh2_$XV_=?O0{M^h)nX^4S-0erR3su*sA z=Fw&1pmKb|aL_ZxJBacSdDYd`O$g%@>#O+CSxFj{9g|%*RSYlX+HVJ(=RtX{A#TdC z=OSi!5%6nFyp8b#JdYOR5j6(7CnYW7KGspVMPN0cxeA5P(8V((aT;-!LEQ6E*y2_V z^Hppw&IWh{ae_bC(&vGfLphxB#Ak!Bs5Z=Q3}}vUFGtPyx;qNL6pZI4&~koz(vH0l z{C1(uXCm+0&H1VnJ;(8$&V+rbxEee#B+oQaH1Pi)p&V`dooEkCn>Ou*Q8cAsh+!^N z`bxd~(O!{ECYb(<{o@%9&&zd{b*9;AtC*L#y*0Xo>a*a5tJ9w&;X z9E|#4J^UIxxsEy+r_<-@wMJj_OgR2A>jAKK&+{gglR-FbRQq+TBYSQfnhJ16ARqBV z{R}C?in;p&6`Hk5%%_`#mXfMyW--4;cMb$>4P$KHE&6yCAG!2faXZI$py+4f}W zg&f+?qv+B?WTgJC*bs$REo|EO@gu>XYw_=u@X$F)?9bw!GIWgNdgz17;8g{NUA|Ax z&+<;cF){h9 zWjx=g?^|eBJac0FF%93#7_wSfK{|B?k}~&{*>i(rMcdRFbMdIwknD52xZ;1Vz z>vexyoHKDzL3$ARgtvhgW0NDpWs|f&IoFQ(E%a|Pg~G2L$+}@_m#Rna8O44XxxV~amZ_UM{SH58Sq;7Z0$KMD ziY)uN`Pl~6evQ9W){Fd>0rs2xPSj0)gWrqn7VG{l%W50U`Z=6}T6(g+kBmjHrRx4s zs?Gt<@f`3=)q`2UvkgA$!EBSCL+yK>pYu^K80`!e;V!lykxw@4CdA&UF9<62WDZRJG& zu$C6WZvIeA51B`zT_YYX2G?VV&-qQ7{MKb3?=TQIjg7#UAgq@UgNA#=gQzbqh0n7R z;D<7f{jDGl)+6%s@}BDvz`Ma`5!WZ`zmaFTGpEj>8~|-E+d`AK^Z8^CMOc7 z;`^9yqx~eFwF7#6HF)RCa~JLq?*KgV4wUN~exeO{doj-+56cYqwT}k8*9= z82IdtxPu&_ad?h<9J>AzxrHxiKgBhEFW{G!lT!+=_aNSBME$r|@2{&%ObH_?dsZ<` z7#63mnG`d@X8x7vg+9N~VFSJ&NCIi@m(lFynD+`X0t_%sCqx z*b&b(`{B25rJiOyTx0FN26)?~YX*_T7iIEvnJ-a?qlb2>Mr@vS{%GFIs0n#bC^4P|jjdVB`}8$4I8N1TgkkJy`L^ZbS9 z`37x)d`i)q@whehmwWWkJem25RZCiZF6S#%=Q(G!xm%O-Bk!DP%XSm}M&Q-s%*#1) zRtCp_Glo8Z{t&)$3HnLG)&CtitNG1~!N%%q`|R zF@t*0m*X9ukGZ=B{nbWBxTb!L8NmNN28OYT(0P-&dk;U8!80{vEH`b|>U$S;#%7;6 z^hSN}#D4h4xeSjn)`k2t<##SJ=U`yd~8AD+Rva~9u0y%4Vt;_%Pvp<9B}NJ|{+3Ta}iIor;8ngjQV*fxOoEe+Br@ z_4r`uABk&4>8WPwLqbB$_^*(T&4pf&kkIF=Bj5%BIa_acyk=CGdPlN?)91;=bsct} zKDm)BRE-Q1jP;E-8)$^a)OH>A)>;sKE9XT@P-rH{Q`szB-;_p z``IxbMF* zFP5)^Sl=UJxv^-H*8M!5&?BP-K$&+t{Rt?vcQ*QVh)+u5Did5XW6?GkE0*<|KC8Z& zJ@fWAo%GmQauo(C((X^_TaVC6^N!ff!)@ntPo_&?-yLlIi$|_oiSf}yKZ#5SS}K@d?4HC*>gT%0Y+4M96sLgd1FEJ z6mw@}?pXM7P!=nr06me5K0Ce+pY2yE-5Ud z^?Na?ddTl3$H69lxzmE}+CMocG;*plrzZo0o+XXk`=*tvGQH!XggecSK2;d}-8VOW z{DXVd>j=SuFSMWU;A4AI2MgXN3o99LG4Ts@;JSv!NWdAN`pRRFlu^N@L+b_eOxP#I zCh#loWC}R~_TB;y!#Qt%5V+?I!qfMprfWk#@yuK}QrNSLrY0hr8>|>L5_d3e>m@8W z3K*(jSR=2-X_hrYWCozl3KQTL3O15dS$q|NQUyTvP)ShA`oxrTH;J3gsVpT~phX9e z)(bqNLBS%mtt(i);mTuc_SjrkGTYKqzx}8HaQmx9Uo|l&6vP5ONCVQKq9Yv0PCQ)$ zkD$mBy=XqC+dE7@15w+(+82(Fr6haulVJdmRIp>VU#n)yFVNL@p3h*E@XnM(?kh_m zD!)us>;1%3*~&sUhLgfRqrhU*8mj`aHcvfI@sunRS>|RA0?=5=zvAK;Q_{DB^e0QC zwWFeOeRk##<$5)|bd{*4@8)QAVz~q%6;+f0h|(K1i=n=P@RC^r0a6=?HH}+`%_#Hq zYDqE8Cj`-^hOL}g`auVf+sVbA-z%gB5N?yNq4KhcBVQOlL^Xfo>NC1 zaf=3PcU6A)OgFIMjDu05Ry{B+cu@)8Cy&I;vIFj zhB$!??q1HIR;NLz!EZk3Oi=#7Olz&V7Tc^xdFKYISy|urYZ6T#jT+xtX~bVf`r#-m zr4W4%)@zuvO+5{n$Ir!%`tB+2J~K4kj~|&HYZEuIg+$|OFmaNzd$Sg>PFicKS!4I9 zyK9whuV}Ga_>SQQW4N9E@1yXJb;ngLB7P3-(Rgm6DR}7dGp5KyMgVNw{8cwN?hz7-3eP}Md{F(>Xt>1Vj~SNb2{W= z=5Jmxku9(q1rG%rs?(~ny1CMJ4GuUJ=1rSbHfhbVA_i9Or!hV;4U|nvq{7_I*4|ujoeCLjn}dY2UE7aCEsKf(May4 zpGkJ|BMK8Rt%%r+gHeDZl~Cd|UtANIkwiL0pTiiv-7c-9=CdCPPiPZUm2SpGf4C)l zTqkB@enacNe9+nUdH-L%KR=2;!$KQP)?)(95~i#-zVmWi-+hxi)O+WqI;PSWo-=>! z-!^I1#TEys@KW)YB5=B;8jtqT^;J-%&ve^%0;+^8Z#UdgYn>Fa2As||Q{SI{oV!d<$s z53e?eWgB8FdRGu96G!tY?Z+(i1#zJma4UyO!J@bp5`orGK|7{m;rC`G2ftaEzn z_~kb~k%nEvn_c(`kH`z>c$|M6f$ebzE90q*Uh~JFkN7c?Jr|=-22RO#)QgUcqAU_D ziS@o;e`%DDmhuOqTczqJ3GY^vdJWSN8asb<@B0F*`q8qJW+ZLg+Ed=z$-Q-kLND7?0pT2R^WJ4v!iXb^pcJpC7ISH-X77!32r(1YxWh75lJfAc z@+Y5eRvQbSJ%v6U#mJShmNR#k{mR#1Nyn3syLx^r$pOii)Wf`$&pCFjP&WonW2~y z1!m9uJ5T80P75bY;*_;0ErcY~Wk20@uv%H#yy{#?pkW#B0#}&eJv{x&#hm2Jc`IVA z4d%u%txCPl1xVDBG;ZoLalc>5X8XGd4#70P9c(hd3 zz7-%{b|}d#r#M6Spihk7D%B>iFq%iDeV)Ux3jCJjd0`O=gwV>yjywI5d5O=Vp7aV! z!Nr<`ly|#82c^_y7}cG0<(FChh?RMI5iDL&a%sgPVJa!abjqcA=uZxq0j{HmMVtIR za7d+plxy4dYl>uFhvx-2WSGPMS=)%PNMBF=ls_8bt1o67_zjwT(>B%jQ4Gm`ot-}D zO{nu6?1gWDguuI%0-4FfXuqSgXz?HYV_Ftqo>QItN=6BuDlNlfm~7f)WnXM|=J~T} z8z#>>)CfPEt7I@ADd)Zv*R*dhWq3LgPO?7>gnT$AS6g;K3;eAJQaxwjX-K!zG_ zyQ7rGy>Ct8SB>Gzoil=&^TnbuzWgD=!&ZlQyt~8{e+`)%c0NNW!ho1EsG*Re7__X*@L40;c8$&Maw-dFHTO=m$EnVZ#mSK=w?uGJLL-^h)RahxQO@k zaB9On>XQK})V+23J8U{LQN}qV%+w+V5kRw2Dh9kR=>J>a!7{&B0{j<)j;g5m&#pRL zeqooB)DAk-qOI`>wq7{GaQrCkF`z3s*lU0_C@=eKj%8UP3XK?(*FZe zbB4KY&(=O1)jZTk4QJKQ1mt8qR}OK+I}cz@8^LQFvVK8^qMq#HXB)Zr!ls6T<+Kmq z*WYBO-b6`pSv_&G%VyUm53&*ohv^hnurG~B@FVoQV@X8Z?1;#}O>90j1W$Jw247KJ z1S+OrwUI+H_;0~1ZK`t`kD%EEuw9NrTb-3wj4)NP3o2~c8|ohH5-Ef_q7VFEG2uD= zBG+}#-Cnby&!kOC~yk5$Mq9@+{1+_7>5J~ydp>GUW!NFTT$U}c)9HU$1LXX%j_5$ zvuHcT@2sK@gnO{siF~|X=g9$aqEMn4{+2nu49Aj5&(ct6;;%e(jj@GO6O+m)4B-XtV`m6`6ln zS>yEU5QnzI2kmR7as2vkue*V7Cg3Go5Pn!d7Ue%s+FX4$VlsI`FzrsYWxT?S$|v@#__{ot9NB$Zoej@2*(z2 zr4JyencNF5o}(*ZUUvAf@bA`&tiLl02Rh1%vt4ZTmp0G_NpowNg}Ac5&4QG^O%j88 zJB+Ga>KuRXoUSBD%23PbtYCoc>#DU*_t(bTE|J*F_R=E}?yP&bR%MJn3!!$VHwVxH z|Mm{^YF z$tPjWs8gnDnL>d|N}lvAKnwJX;#>Bi#idkydScf~x9!DJMXjJ7(dpw_c4}W|c2S9u zb(R=Y=t=oZ2R|i;65uJf*38_W4cC%Z3JXhCr=aal? - - - \ No newline at end of file diff --git a/src/core/server/core_app/assets/legacy_light_theme.css b/src/core/server/core_app/assets/legacy_light_theme.css deleted file mode 100644 index c5c639f60e3be..0000000000000 --- a/src/core/server/core_app/assets/legacy_light_theme.css +++ /dev/null @@ -1,4419 +0,0 @@ -/*! - * Bootstrap v3.3.6 (http://getbootstrap.com) - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */ -/* @notice - * This product bundles bootstrap@3.3.6 which is available under a - * "MIT" license. - * - * The MIT License (MIT) - * - * Copyright (c) 2011-2015 Twitter, Inc - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -.container { - margin-right: auto; - margin-left: auto; - padding-left: 15px; - padding-right: 15px; -} -@media (min-width: 768px) { - .container { - width: 750px; - } -} -@media (min-width: 992px) { - .container { - width: 970px; - } -} -@media (min-width: 1200px) { - .container { - width: 1170px; - } -} -.container-fluid { - margin-right: auto; - margin-left: auto; - padding-left: 15px; - padding-right: 15px; -} -.row { - margin-left: -15px; - margin-right: -15px; -} -.col-xs-1, -.col-sm-1, -.col-md-1, -.col-lg-1, -.col-xs-2, -.col-sm-2, -.col-md-2, -.col-lg-2, -.col-xs-3, -.col-sm-3, -.col-md-3, -.col-lg-3, -.col-xs-4, -.col-sm-4, -.col-md-4, -.col-lg-4, -.col-xs-5, -.col-sm-5, -.col-md-5, -.col-lg-5, -.col-xs-6, -.col-sm-6, -.col-md-6, -.col-lg-6, -.col-xs-7, -.col-sm-7, -.col-md-7, -.col-lg-7, -.col-xs-8, -.col-sm-8, -.col-md-8, -.col-lg-8, -.col-xs-9, -.col-sm-9, -.col-md-9, -.col-lg-9, -.col-xs-10, -.col-sm-10, -.col-md-10, -.col-lg-10, -.col-xs-11, -.col-sm-11, -.col-md-11, -.col-lg-11, -.col-xs-12, -.col-sm-12, -.col-md-12, -.col-lg-12 { - position: relative; - min-height: 1px; - padding-left: 15px; - padding-right: 15px; -} -.col-xs-1, -.col-xs-2, -.col-xs-3, -.col-xs-4, -.col-xs-5, -.col-xs-6, -.col-xs-7, -.col-xs-8, -.col-xs-9, -.col-xs-10, -.col-xs-11, -.col-xs-12 { - float: left; -} -.col-xs-12 { - width: 100%; -} -.col-xs-11 { - width: 91.66666667%; -} -.col-xs-10 { - width: 83.33333333%; -} -.col-xs-9 { - width: 75%; -} -.col-xs-8 { - width: 66.66666667%; -} -.col-xs-7 { - width: 58.33333333%; -} -.col-xs-6 { - width: 50%; -} -.col-xs-5 { - width: 41.66666667%; -} -.col-xs-4 { - width: 33.33333333%; -} -.col-xs-3 { - width: 25%; -} -.col-xs-2 { - width: 16.66666667%; -} -.col-xs-1 { - width: 8.33333333%; -} -.col-xs-pull-12 { - right: 100%; -} -.col-xs-pull-11 { - right: 91.66666667%; -} -.col-xs-pull-10 { - right: 83.33333333%; -} -.col-xs-pull-9 { - right: 75%; -} -.col-xs-pull-8 { - right: 66.66666667%; -} -.col-xs-pull-7 { - right: 58.33333333%; -} -.col-xs-pull-6 { - right: 50%; -} -.col-xs-pull-5 { - right: 41.66666667%; -} -.col-xs-pull-4 { - right: 33.33333333%; -} -.col-xs-pull-3 { - right: 25%; -} -.col-xs-pull-2 { - right: 16.66666667%; -} -.col-xs-pull-1 { - right: 8.33333333%; -} -.col-xs-pull-0 { - right: auto; -} -.col-xs-push-12 { - left: 100%; -} -.col-xs-push-11 { - left: 91.66666667%; -} -.col-xs-push-10 { - left: 83.33333333%; -} -.col-xs-push-9 { - left: 75%; -} -.col-xs-push-8 { - left: 66.66666667%; -} -.col-xs-push-7 { - left: 58.33333333%; -} -.col-xs-push-6 { - left: 50%; -} -.col-xs-push-5 { - left: 41.66666667%; -} -.col-xs-push-4 { - left: 33.33333333%; -} -.col-xs-push-3 { - left: 25%; -} -.col-xs-push-2 { - left: 16.66666667%; -} -.col-xs-push-1 { - left: 8.33333333%; -} -.col-xs-push-0 { - left: auto; -} -.col-xs-offset-12 { - margin-left: 100%; -} -.col-xs-offset-11 { - margin-left: 91.66666667%; -} -.col-xs-offset-10 { - margin-left: 83.33333333%; -} -.col-xs-offset-9 { - margin-left: 75%; -} -.col-xs-offset-8 { - margin-left: 66.66666667%; -} -.col-xs-offset-7 { - margin-left: 58.33333333%; -} -.col-xs-offset-6 { - margin-left: 50%; -} -.col-xs-offset-5 { - margin-left: 41.66666667%; -} -.col-xs-offset-4 { - margin-left: 33.33333333%; -} -.col-xs-offset-3 { - margin-left: 25%; -} -.col-xs-offset-2 { - margin-left: 16.66666667%; -} -.col-xs-offset-1 { - margin-left: 8.33333333%; -} -.col-xs-offset-0 { - margin-left: 0%; -} -@media (min-width: 768px) { - .col-sm-1, - .col-sm-2, - .col-sm-3, - .col-sm-4, - .col-sm-5, - .col-sm-6, - .col-sm-7, - .col-sm-8, - .col-sm-9, - .col-sm-10, - .col-sm-11, - .col-sm-12 { - float: left; - } - .col-sm-12 { - width: 100%; - } - .col-sm-11 { - width: 91.66666667%; - } - .col-sm-10 { - width: 83.33333333%; - } - .col-sm-9 { - width: 75%; - } - .col-sm-8 { - width: 66.66666667%; - } - .col-sm-7 { - width: 58.33333333%; - } - .col-sm-6 { - width: 50%; - } - .col-sm-5 { - width: 41.66666667%; - } - .col-sm-4 { - width: 33.33333333%; - } - .col-sm-3 { - width: 25%; - } - .col-sm-2 { - width: 16.66666667%; - } - .col-sm-1 { - width: 8.33333333%; - } - .col-sm-pull-12 { - right: 100%; - } - .col-sm-pull-11 { - right: 91.66666667%; - } - .col-sm-pull-10 { - right: 83.33333333%; - } - .col-sm-pull-9 { - right: 75%; - } - .col-sm-pull-8 { - right: 66.66666667%; - } - .col-sm-pull-7 { - right: 58.33333333%; - } - .col-sm-pull-6 { - right: 50%; - } - .col-sm-pull-5 { - right: 41.66666667%; - } - .col-sm-pull-4 { - right: 33.33333333%; - } - .col-sm-pull-3 { - right: 25%; - } - .col-sm-pull-2 { - right: 16.66666667%; - } - .col-sm-pull-1 { - right: 8.33333333%; - } - .col-sm-pull-0 { - right: auto; - } - .col-sm-push-12 { - left: 100%; - } - .col-sm-push-11 { - left: 91.66666667%; - } - .col-sm-push-10 { - left: 83.33333333%; - } - .col-sm-push-9 { - left: 75%; - } - .col-sm-push-8 { - left: 66.66666667%; - } - .col-sm-push-7 { - left: 58.33333333%; - } - .col-sm-push-6 { - left: 50%; - } - .col-sm-push-5 { - left: 41.66666667%; - } - .col-sm-push-4 { - left: 33.33333333%; - } - .col-sm-push-3 { - left: 25%; - } - .col-sm-push-2 { - left: 16.66666667%; - } - .col-sm-push-1 { - left: 8.33333333%; - } - .col-sm-push-0 { - left: auto; - } - .col-sm-offset-12 { - margin-left: 100%; - } - .col-sm-offset-11 { - margin-left: 91.66666667%; - } - .col-sm-offset-10 { - margin-left: 83.33333333%; - } - .col-sm-offset-9 { - margin-left: 75%; - } - .col-sm-offset-8 { - margin-left: 66.66666667%; - } - .col-sm-offset-7 { - margin-left: 58.33333333%; - } - .col-sm-offset-6 { - margin-left: 50%; - } - .col-sm-offset-5 { - margin-left: 41.66666667%; - } - .col-sm-offset-4 { - margin-left: 33.33333333%; - } - .col-sm-offset-3 { - margin-left: 25%; - } - .col-sm-offset-2 { - margin-left: 16.66666667%; - } - .col-sm-offset-1 { - margin-left: 8.33333333%; - } - .col-sm-offset-0 { - margin-left: 0%; - } -} -@media (min-width: 992px) { - .col-md-1, - .col-md-2, - .col-md-3, - .col-md-4, - .col-md-5, - .col-md-6, - .col-md-7, - .col-md-8, - .col-md-9, - .col-md-10, - .col-md-11, - .col-md-12 { - float: left; - } - .col-md-12 { - width: 100%; - } - .col-md-11 { - width: 91.66666667%; - } - .col-md-10 { - width: 83.33333333%; - } - .col-md-9 { - width: 75%; - } - .col-md-8 { - width: 66.66666667%; - } - .col-md-7 { - width: 58.33333333%; - } - .col-md-6 { - width: 50%; - } - .col-md-5 { - width: 41.66666667%; - } - .col-md-4 { - width: 33.33333333%; - } - .col-md-3 { - width: 25%; - } - .col-md-2 { - width: 16.66666667%; - } - .col-md-1 { - width: 8.33333333%; - } - .col-md-pull-12 { - right: 100%; - } - .col-md-pull-11 { - right: 91.66666667%; - } - .col-md-pull-10 { - right: 83.33333333%; - } - .col-md-pull-9 { - right: 75%; - } - .col-md-pull-8 { - right: 66.66666667%; - } - .col-md-pull-7 { - right: 58.33333333%; - } - .col-md-pull-6 { - right: 50%; - } - .col-md-pull-5 { - right: 41.66666667%; - } - .col-md-pull-4 { - right: 33.33333333%; - } - .col-md-pull-3 { - right: 25%; - } - .col-md-pull-2 { - right: 16.66666667%; - } - .col-md-pull-1 { - right: 8.33333333%; - } - .col-md-pull-0 { - right: auto; - } - .col-md-push-12 { - left: 100%; - } - .col-md-push-11 { - left: 91.66666667%; - } - .col-md-push-10 { - left: 83.33333333%; - } - .col-md-push-9 { - left: 75%; - } - .col-md-push-8 { - left: 66.66666667%; - } - .col-md-push-7 { - left: 58.33333333%; - } - .col-md-push-6 { - left: 50%; - } - .col-md-push-5 { - left: 41.66666667%; - } - .col-md-push-4 { - left: 33.33333333%; - } - .col-md-push-3 { - left: 25%; - } - .col-md-push-2 { - left: 16.66666667%; - } - .col-md-push-1 { - left: 8.33333333%; - } - .col-md-push-0 { - left: auto; - } - .col-md-offset-12 { - margin-left: 100%; - } - .col-md-offset-11 { - margin-left: 91.66666667%; - } - .col-md-offset-10 { - margin-left: 83.33333333%; - } - .col-md-offset-9 { - margin-left: 75%; - } - .col-md-offset-8 { - margin-left: 66.66666667%; - } - .col-md-offset-7 { - margin-left: 58.33333333%; - } - .col-md-offset-6 { - margin-left: 50%; - } - .col-md-offset-5 { - margin-left: 41.66666667%; - } - .col-md-offset-4 { - margin-left: 33.33333333%; - } - .col-md-offset-3 { - margin-left: 25%; - } - .col-md-offset-2 { - margin-left: 16.66666667%; - } - .col-md-offset-1 { - margin-left: 8.33333333%; - } - .col-md-offset-0 { - margin-left: 0%; - } -} -@media (min-width: 1200px) { - .col-lg-1, - .col-lg-2, - .col-lg-3, - .col-lg-4, - .col-lg-5, - .col-lg-6, - .col-lg-7, - .col-lg-8, - .col-lg-9, - .col-lg-10, - .col-lg-11, - .col-lg-12 { - float: left; - } - .col-lg-12 { - width: 100%; - } - .col-lg-11 { - width: 91.66666667%; - } - .col-lg-10 { - width: 83.33333333%; - } - .col-lg-9 { - width: 75%; - } - .col-lg-8 { - width: 66.66666667%; - } - .col-lg-7 { - width: 58.33333333%; - } - .col-lg-6 { - width: 50%; - } - .col-lg-5 { - width: 41.66666667%; - } - .col-lg-4 { - width: 33.33333333%; - } - .col-lg-3 { - width: 25%; - } - .col-lg-2 { - width: 16.66666667%; - } - .col-lg-1 { - width: 8.33333333%; - } - .col-lg-pull-12 { - right: 100%; - } - .col-lg-pull-11 { - right: 91.66666667%; - } - .col-lg-pull-10 { - right: 83.33333333%; - } - .col-lg-pull-9 { - right: 75%; - } - .col-lg-pull-8 { - right: 66.66666667%; - } - .col-lg-pull-7 { - right: 58.33333333%; - } - .col-lg-pull-6 { - right: 50%; - } - .col-lg-pull-5 { - right: 41.66666667%; - } - .col-lg-pull-4 { - right: 33.33333333%; - } - .col-lg-pull-3 { - right: 25%; - } - .col-lg-pull-2 { - right: 16.66666667%; - } - .col-lg-pull-1 { - right: 8.33333333%; - } - .col-lg-pull-0 { - right: auto; - } - .col-lg-push-12 { - left: 100%; - } - .col-lg-push-11 { - left: 91.66666667%; - } - .col-lg-push-10 { - left: 83.33333333%; - } - .col-lg-push-9 { - left: 75%; - } - .col-lg-push-8 { - left: 66.66666667%; - } - .col-lg-push-7 { - left: 58.33333333%; - } - .col-lg-push-6 { - left: 50%; - } - .col-lg-push-5 { - left: 41.66666667%; - } - .col-lg-push-4 { - left: 33.33333333%; - } - .col-lg-push-3 { - left: 25%; - } - .col-lg-push-2 { - left: 16.66666667%; - } - .col-lg-push-1 { - left: 8.33333333%; - } - .col-lg-push-0 { - left: auto; - } - .col-lg-offset-12 { - margin-left: 100%; - } - .col-lg-offset-11 { - margin-left: 91.66666667%; - } - .col-lg-offset-10 { - margin-left: 83.33333333%; - } - .col-lg-offset-9 { - margin-left: 75%; - } - .col-lg-offset-8 { - margin-left: 66.66666667%; - } - .col-lg-offset-7 { - margin-left: 58.33333333%; - } - .col-lg-offset-6 { - margin-left: 50%; - } - .col-lg-offset-5 { - margin-left: 41.66666667%; - } - .col-lg-offset-4 { - margin-left: 33.33333333%; - } - .col-lg-offset-3 { - margin-left: 25%; - } - .col-lg-offset-2 { - margin-left: 16.66666667%; - } - .col-lg-offset-1 { - margin-left: 8.33333333%; - } - .col-lg-offset-0 { - margin-left: 0%; - } -} -.table { - width: 100%; - max-width: 100%; - margin-bottom: 20px; - font-size: 14px; -} -.table thead { - font-size: 12px; -} -.table > thead > tr > th, -.table > tbody > tr > th, -.table > tfoot > tr > th, -.table > thead > tr > td, -.table > tbody > tr > td, -.table > tfoot > tr > td { - padding: 8px; - line-height: 1.42857143; - vertical-align: top; - border-top: 1px solid #D3DAE6; -} -.table > thead > tr > th { - vertical-align: bottom; - border-bottom: 1px solid #D3DAE6; -} -.table > caption + thead > tr:first-child > th, -.table > colgroup + thead > tr:first-child > th, -.table > thead:first-child > tr:first-child > th, -.table > caption + thead > tr:first-child > td, -.table > colgroup + thead > tr:first-child > td, -.table > thead:first-child > tr:first-child > td { - border-top: 0; -} -.table > tbody + tbody { - border-top: 2px solid #D3DAE6; -} -.table .table { - background-color: #FFF; -} -.table-condensed > thead > tr > th, -.table-condensed > tbody > tr > th, -.table-condensed > tfoot > tr > th, -.table-condensed > thead > tr > td, -.table-condensed > tbody > tr > td, -.table-condensed > tfoot > tr > td { - padding: 5px; - font-size: 12px; -} -.table-bordered { - border: 1px solid #D3DAE6; -} -.table-bordered > thead > tr > th, -.table-bordered > tbody > tr > th, -.table-bordered > tfoot > tr > th, -.table-bordered > thead > tr > td, -.table-bordered > tbody > tr > td, -.table-bordered > tfoot > tr > td { - border: 1px solid #D3DAE6; -} -.table-bordered > thead > tr > th, -.table-bordered > thead > tr > td { - border-bottom-width: 2px; -} -.table-striped > tbody > tr:nth-of-type(odd) { - background-color: #D3DAE6; -} -.table-hover > tbody > tr:hover { - background-color: #D3DAE6; -} -table col[class*="col-"] { - position: static; - float: none; - display: table-column; -} -table td[class*="col-"], -table th[class*="col-"] { - position: static; - float: none; - display: table-cell; -} -.table > thead > tr > td.active, -.table > tbody > tr > td.active, -.table > tfoot > tr > td.active, -.table > thead > tr > th.active, -.table > tbody > tr > th.active, -.table > tfoot > tr > th.active, -.table > thead > tr.active > td, -.table > tbody > tr.active > td, -.table > tfoot > tr.active > td, -.table > thead > tr.active > th, -.table > tbody > tr.active > th, -.table > tfoot > tr.active > th { - background-color: #D3DAE6; -} -.table-hover > tbody > tr > td.active:hover, -.table-hover > tbody > tr > th.active:hover, -.table-hover > tbody > tr.active:hover > td, -.table-hover > tbody > tr:hover > .active, -.table-hover > tbody > tr.active:hover > th { - background-color: #c3ccdd; -} -.table > thead > tr > td.success, -.table > tbody > tr > td.success, -.table > tfoot > tr > td.success, -.table > thead > tr > th.success, -.table > tbody > tr > th.success, -.table > tfoot > tr > th.success, -.table > thead > tr.success > td, -.table > tbody > tr.success > td, -.table > tfoot > tr.success > td, -.table > thead > tr.success > th, -.table > tbody > tr.success > th, -.table > tfoot > tr.success > th { - background-color: #017D73; -} -.table-hover > tbody > tr > td.success:hover, -.table-hover > tbody > tr > th.success:hover, -.table-hover > tbody > tr.success:hover > td, -.table-hover > tbody > tr:hover > .success, -.table-hover > tbody > tr.success:hover > th { - background-color: #01645c; -} -.table > thead > tr > td.info, -.table > tbody > tr > td.info, -.table > tfoot > tr > td.info, -.table > thead > tr > th.info, -.table > tbody > tr > th.info, -.table > tfoot > tr > th.info, -.table > thead > tr.info > td, -.table > tbody > tr.info > td, -.table > tfoot > tr.info > td, -.table > thead > tr.info > th, -.table > tbody > tr.info > th, -.table > tfoot > tr.info > th { - background-color: #006BB4; -} -.table-hover > tbody > tr > td.info:hover, -.table-hover > tbody > tr > th.info:hover, -.table-hover > tbody > tr.info:hover > td, -.table-hover > tbody > tr:hover > .info, -.table-hover > tbody > tr.info:hover > th { - background-color: #005c9b; -} -.table > thead > tr > td.warning, -.table > tbody > tr > td.warning, -.table > tfoot > tr > td.warning, -.table > thead > tr > th.warning, -.table > tbody > tr > th.warning, -.table > tfoot > tr > th.warning, -.table > thead > tr.warning > td, -.table > tbody > tr.warning > td, -.table > tfoot > tr.warning > td, -.table > thead > tr.warning > th, -.table > tbody > tr.warning > th, -.table > tfoot > tr.warning > th { - background-color: #F5A700; -} -.table-hover > tbody > tr > td.warning:hover, -.table-hover > tbody > tr > th.warning:hover, -.table-hover > tbody > tr.warning:hover > td, -.table-hover > tbody > tr:hover > .warning, -.table-hover > tbody > tr.warning:hover > th { - background-color: #dc9600; -} -.table > thead > tr > td.danger, -.table > tbody > tr > td.danger, -.table > tfoot > tr > td.danger, -.table > thead > tr > th.danger, -.table > tbody > tr > th.danger, -.table > tfoot > tr > th.danger, -.table > thead > tr.danger > td, -.table > tbody > tr.danger > td, -.table > tfoot > tr.danger > td, -.table > thead > tr.danger > th, -.table > tbody > tr.danger > th, -.table > tfoot > tr.danger > th { - background-color: #BD271E; -} -.table-hover > tbody > tr > td.danger:hover, -.table-hover > tbody > tr > th.danger:hover, -.table-hover > tbody > tr.danger:hover > td, -.table-hover > tbody > tr:hover > .danger, -.table-hover > tbody > tr.danger:hover > th { - background-color: #a7221b; -} -.table-responsive { - overflow-x: auto; - min-height: 0.01%; -} -@media screen and (max-width: 767px) { - .table-responsive { - width: 100%; - margin-bottom: 15px; - overflow-y: hidden; - -ms-overflow-style: -ms-autohiding-scrollbar; - border: 1px solid #D3DAE6; - } - .table-responsive > .table { - margin-bottom: 0; - } - .table-responsive > .table > thead > tr > th, - .table-responsive > .table > tbody > tr > th, - .table-responsive > .table > tfoot > tr > th, - .table-responsive > .table > thead > tr > td, - .table-responsive > .table > tbody > tr > td, - .table-responsive > .table > tfoot > tr > td { - white-space: nowrap; - } - .table-responsive > .table-bordered { - border: 0; - } - .table-responsive > .table-bordered > thead > tr > th:first-child, - .table-responsive > .table-bordered > tbody > tr > th:first-child, - .table-responsive > .table-bordered > tfoot > tr > th:first-child, - .table-responsive > .table-bordered > thead > tr > td:first-child, - .table-responsive > .table-bordered > tbody > tr > td:first-child, - .table-responsive > .table-bordered > tfoot > tr > td:first-child { - border-left: 0; - } - .table-responsive > .table-bordered > thead > tr > th:last-child, - .table-responsive > .table-bordered > tbody > tr > th:last-child, - .table-responsive > .table-bordered > tfoot > tr > th:last-child, - .table-responsive > .table-bordered > thead > tr > td:last-child, - .table-responsive > .table-bordered > tbody > tr > td:last-child, - .table-responsive > .table-bordered > tfoot > tr > td:last-child { - border-right: 0; - } - .table-responsive > .table-bordered > tbody > tr:last-child > th, - .table-responsive > .table-bordered > tfoot > tr:last-child > th, - .table-responsive > .table-bordered > tbody > tr:last-child > td, - .table-responsive > .table-bordered > tfoot > tr:last-child > td { - border-bottom: 0; - } -} -.form-control { - display: block; - width: 100%; - height: 32px; - padding: 5px 15px; - font-size: 14px; - line-height: 1.42857143; - color: #343741; - background-color: #fafbfd; - background-image: none; - border: 1px solid #D3DAE6; - border-radius: 4px; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; - -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; - transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; -} -.form-control:focus { - border-color: #006BB4; - outline: 0; - -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(0, 107, 180, 0.6); - box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(0, 107, 180, 0.6); -} -.form-control::-moz-placeholder { - color: #98A2B3; - opacity: 1; -} -.form-control:-ms-input-placeholder { - color: #98A2B3; -} -.form-control::-webkit-input-placeholder { - color: #98A2B3; -} -.form-control::-ms-expand { - border: 0; - background-color: transparent; -} -.form-control[disabled], -.form-control[readonly], -fieldset[disabled] .form-control { - background-color: #D3DAE6; - opacity: 1; -} -.form-control[disabled], -fieldset[disabled] .form-control { - cursor: not-allowed; -} -textarea.form-control { - height: auto; -} -.form-group:not(:empty) { - margin-bottom: 15px; -} -.radio, -.checkbox { - position: relative; - display: block; - margin-top: 10px; - margin-bottom: 10px; -} -.radio label, -.checkbox label { - min-height: 20px; - padding-left: 20px; - margin-bottom: 0; - font-weight: normal; - cursor: pointer; -} -.radio input[type="radio"], -.radio-inline input[type="radio"], -.checkbox input[type="checkbox"], -.checkbox-inline input[type="checkbox"] { - position: absolute; - margin-left: -20px; - margin-top: 4px \9; -} -.radio + .radio, -.checkbox + .checkbox { - margin-top: -5px; -} -.radio-inline, -.checkbox-inline { - position: relative; - display: inline-block; - padding-left: 20px; - margin-bottom: 0; - vertical-align: middle; - font-weight: normal; - cursor: pointer; -} -.radio-inline + .radio-inline, -.checkbox-inline + .checkbox-inline { - margin-top: 0; - margin-left: 10px; -} -.radio-inline.disabled, -.checkbox-inline.disabled, -fieldset[disabled] .radio-inline, -fieldset[disabled] .checkbox-inline { - cursor: not-allowed; -} -.radio.disabled label, -.checkbox.disabled label, -fieldset[disabled] .radio label, -fieldset[disabled] .checkbox label { - cursor: not-allowed; -} -.form-control-static { - padding-top: 6px; - padding-bottom: 6px; - margin-bottom: 0; - min-height: 34px; -} -.form-control-static.input-lg, -.form-control-static.input-sm { - padding-left: 0; - padding-right: 0; -} -.input-sm { - height: 32px; - padding: 6px 9px; - font-size: 12px; - line-height: 1.5; - border-radius: 4px; -} -select.input-sm { - height: 32px; - line-height: 32px; -} -textarea.input-sm, -select[multiple].input-sm { - height: auto; -} -.form-group-sm .form-control { - height: 32px; - padding: 6px 9px; - font-size: 12px; - line-height: 1.5; - border-radius: 4px; -} -.form-group-sm select.form-control { - height: 32px; - line-height: 32px; -} -.form-group-sm textarea.form-control, -.form-group-sm select[multiple].form-control { - height: auto; -} -.form-group-sm .form-control-static { - height: 32px; - min-height: 32px; - padding: 7px 9px; - font-size: 12px; - line-height: 1.5; -} -.input-lg { - height: 62px; - padding: 18px 27px; - font-size: 18px; - line-height: 1.3333333; - border-radius: 4px; -} -select.input-lg { - height: 62px; - line-height: 62px; -} -textarea.input-lg, -select[multiple].input-lg { - height: auto; -} -.form-group-lg .form-control { - height: 62px; - padding: 18px 27px; - font-size: 18px; - line-height: 1.3333333; - border-radius: 4px; -} -.form-group-lg select.form-control { - height: 62px; - line-height: 62px; -} -.form-group-lg textarea.form-control, -.form-group-lg select[multiple].form-control { - height: auto; -} -.form-group-lg .form-control-static { - height: 62px; - min-height: 38px; - padding: 19px 27px; - font-size: 18px; - line-height: 1.3333333; -} -.has-feedback { - position: relative; -} -.has-feedback .form-control { - padding-right: 40px; -} -.form-control-feedback { - position: absolute; - top: 0; - right: 0; - z-index: 2; - display: block; - width: 32px; - height: 32px; - line-height: 32px; - text-align: center; - pointer-events: none; -} -.input-lg + .form-control-feedback, -.input-group-lg + .form-control-feedback, -.form-group-lg .form-control + .form-control-feedback { - width: 62px; - height: 62px; - line-height: 62px; -} -.input-sm + .form-control-feedback, -.input-group-sm + .form-control-feedback, -.form-group-sm .form-control + .form-control-feedback { - width: 32px; - height: 32px; - line-height: 32px; -} -.has-success .help-block, -.has-success .control-label, -.has-success .radio, -.has-success .checkbox, -.has-success .radio-inline, -.has-success .checkbox-inline, -.has-success.radio label, -.has-success.checkbox label, -.has-success.radio-inline label, -.has-success.checkbox-inline label { - color: #FFF; -} -.has-success .form-control { - border-color: #FFF; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} -.has-success .form-control:focus { - border-color: #e6e6e6; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ffffff; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ffffff; -} -.has-success .input-group-addon { - color: #FFF; - border-color: #FFF; - background-color: #017D73; -} -.has-success .form-control-feedback { - color: #FFF; -} -.has-warning .help-block, -.has-warning .control-label, -.has-warning .radio, -.has-warning .checkbox, -.has-warning .radio-inline, -.has-warning .checkbox-inline, -.has-warning.radio label, -.has-warning.checkbox label, -.has-warning.radio-inline label, -.has-warning.checkbox-inline label { - color: #FFF; -} -.has-warning .form-control { - border-color: #FFF; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} -.has-warning .form-control:focus { - border-color: #e6e6e6; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ffffff; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ffffff; -} -.has-warning .input-group-addon { - color: #FFF; - border-color: #FFF; - background-color: #F5A700; -} -.has-warning .form-control-feedback { - color: #FFF; -} -.has-error .help-block, -.has-error .control-label, -.has-error .radio, -.has-error .checkbox, -.has-error .radio-inline, -.has-error .checkbox-inline, -.has-error.radio label, -.has-error.checkbox label, -.has-error.radio-inline label, -.has-error.checkbox-inline label { - color: #FFF; -} -.has-error .form-control { - border-color: #FFF; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} -.has-error .form-control:focus { - border-color: #e6e6e6; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ffffff; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ffffff; -} -.has-error .input-group-addon { - color: #FFF; - border-color: #FFF; - background-color: #BD271E; -} -.has-error .form-control-feedback { - color: #FFF; -} -.has-feedback label ~ .form-control-feedback { - top: 25px; -} -.has-feedback label.sr-only ~ .form-control-feedback { - top: 0; -} -.help-block { - display: block; - margin-top: 5px; - margin-bottom: 10px; - color: #6d7388; -} -@media (min-width: 768px) { - .form-inline .form-group { - display: inline-block; - margin-bottom: 0; - vertical-align: middle; - } - .form-inline .form-control { - display: inline-block; - width: auto; - vertical-align: middle; - } - .form-inline .form-control-static { - display: inline-block; - } - .form-inline .input-group { - display: inline-table; - vertical-align: middle; - } - .form-inline .input-group .input-group-addon, - .form-inline .input-group .form-control { - width: auto; - } - .form-inline .input-group > .form-control { - width: 100%; - } - .form-inline .control-label { - margin-bottom: 0; - vertical-align: middle; - } - .form-inline .radio, - .form-inline .checkbox { - display: inline-block; - margin-top: 0; - margin-bottom: 0; - vertical-align: middle; - } - .form-inline .radio label, - .form-inline .checkbox label { - padding-left: 0; - } - .form-inline .radio input[type="radio"], - .form-inline .checkbox input[type="checkbox"] { - position: relative; - margin-left: 0; - } - .form-inline .has-feedback .form-control-feedback { - top: 0; - } -} -.form-horizontal .radio, -.form-horizontal .checkbox, -.form-horizontal .radio-inline, -.form-horizontal .checkbox-inline { - margin-top: 0; - margin-bottom: 0; - padding-top: 6px; -} -.form-horizontal .radio, -.form-horizontal .checkbox { - min-height: 26px; -} -.form-horizontal .form-group { - margin-left: -15px; - margin-right: -15px; -} -@media (min-width: 768px) { - .form-horizontal .control-label { - text-align: right; - margin-bottom: 0; - padding-top: 6px; - } -} -.form-horizontal .has-feedback .form-control-feedback { - right: 15px; -} -@media (min-width: 768px) { - .form-horizontal .form-group-lg .control-label { - padding-top: 19px; - font-size: 18px; - } -} -@media (min-width: 768px) { - .form-horizontal .form-group-sm .control-label { - padding-top: 7px; - font-size: 12px; - } -} -.text-left { - text-align: left; -} -.text-right { - text-align: right; -} -.text-center { - text-align: center; -} -.text-muted { - color: #b2bac6; -} -.text-primary { - color: #343741; -} -a.text-primary:hover, -a.text-primary:focus { - color: #1d1f25; -} -.text-success { - color: #FFF; -} -a.text-success:hover, -a.text-success:focus { - color: #e6e6e6; -} -.text-info { - color: #FFF; -} -a.text-info:hover, -a.text-info:focus { - color: #e6e6e6; -} -.text-warning { - color: #FFF; -} -a.text-warning:hover, -a.text-warning:focus { - color: #e6e6e6; -} -.text-danger { - color: #FFF; -} -a.text-danger:hover, -a.text-danger:focus { - color: #e6e6e6; -} -.bg-info { - background-color: #006BB4; -} -a.bg-info:hover, -a.bg-info:focus { - background-color: #004d81; -} -.list-unstyled { - padding-left: 0; - list-style: none; -} -@media (min-width: 0) { - .dl-horizontal dt { - float: left; - width: 160px; - clear: left; - text-align: right; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - .dl-horizontal dd { - margin-left: 180px; - } -} -.fade { - opacity: 0; - -webkit-transition: opacity 0.15s linear; - -o-transition: opacity 0.15s linear; - transition: opacity 0.15s linear; -} -.fade.in { - opacity: 1; -} -.collapse { - display: none; -} -.collapse.in { - display: block; -} -tr.collapse.in { - display: table-row; -} -tbody.collapse.in { - display: table-row-group; -} -.collapsing { - position: relative; - height: 0; - overflow: hidden; - -webkit-transition-property: height, visibility; - transition-property: height, visibility; - -webkit-transition-duration: 0.35s; - transition-duration: 0.35s; - -webkit-transition-timing-function: ease; - transition-timing-function: ease; -} -/** - * ui/angular-ui-select depends upon these styles. Don't use them in your markup. - * Please use the UI Framework styles instead. - */ -.btn { - display: inline-block; - margin-bottom: 0; - font-weight: normal; - text-align: center; - vertical-align: middle; - touch-action: manipulation; - cursor: pointer; - background-image: none; - border: 1px solid transparent; - white-space: nowrap; - padding: 5px 15px; - font-size: 14px; - line-height: 1.42857143; - border-radius: 4px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} -.btn:focus, -.btn:active:focus, -.btn.active:focus, -.btn.focus, -.btn:active.focus, -.btn.active.focus { - box-shadow: 0 0 0 1px white, 0 0 0 2px #0079a5; - /* 3 */ -} -.btn:hover, -.btn:focus, -.btn.focus { - color: #FFF; - text-decoration: none; -} -.btn:active, -.btn.active { - outline: 0; - background-image: none; - -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); -} -.btn.disabled, -.btn[disabled], -fieldset[disabled] .btn { - cursor: not-allowed; - opacity: 0.65; - filter: alpha(opacity=65); - -webkit-box-shadow: none; - box-shadow: none; -} -a.btn.disabled, -fieldset[disabled] a.btn { - pointer-events: none; -} -.btn-default { - color: #FFF; - background-color: #006BB4; - border-color: #006BB4; -} -.btn-default:focus, -.btn-default.focus { - color: #FFF; - background-color: #004d81; - border-color: #001f35; -} -.btn-default:hover { - color: #FFF; - background-color: #004d81; - border-color: #004777; -} -.btn-default:active, -.btn-default.active, -.open > .dropdown-toggle.btn-default { - color: #FFF; - background-color: #004d81; - border-color: #004777; -} -.btn-default:active:hover, -.btn-default.active:hover, -.open > .dropdown-toggle.btn-default:hover, -.btn-default:active:focus, -.btn-default.active:focus, -.open > .dropdown-toggle.btn-default:focus, -.btn-default:active.focus, -.btn-default.active.focus, -.open > .dropdown-toggle.btn-default.focus { - color: #FFF; - background-color: #00375d; - border-color: #001f35; -} -.btn-default:active, -.btn-default.active, -.open > .dropdown-toggle.btn-default { - background-image: none; -} -.btn-default.disabled:hover, -.btn-default[disabled]:hover, -fieldset[disabled] .btn-default:hover, -.btn-default.disabled:focus, -.btn-default[disabled]:focus, -fieldset[disabled] .btn-default:focus, -.btn-default.disabled.focus, -.btn-default[disabled].focus, -fieldset[disabled] .btn-default.focus { - background-color: #006BB4; - border-color: #006BB4; -} -.btn-default .badge { - color: #006BB4; - background-color: #FFF; -} -.btn-primary { - color: #FFF; - background-color: #006BB4; - border-color: #006BB4; -} -.btn-primary:focus, -.btn-primary.focus { - color: #FFF; - background-color: #004d81; - border-color: #001f35; -} -.btn-primary:hover { - color: #FFF; - background-color: #004d81; - border-color: #004777; -} -.btn-primary:active, -.btn-primary.active, -.open > .dropdown-toggle.btn-primary { - color: #FFF; - background-color: #004d81; - border-color: #004777; -} -.btn-primary:active:hover, -.btn-primary.active:hover, -.open > .dropdown-toggle.btn-primary:hover, -.btn-primary:active:focus, -.btn-primary.active:focus, -.open > .dropdown-toggle.btn-primary:focus, -.btn-primary:active.focus, -.btn-primary.active.focus, -.open > .dropdown-toggle.btn-primary.focus { - color: #FFF; - background-color: #00375d; - border-color: #001f35; -} -.btn-primary:active, -.btn-primary.active, -.open > .dropdown-toggle.btn-primary { - background-image: none; -} -.btn-primary.disabled:hover, -.btn-primary[disabled]:hover, -fieldset[disabled] .btn-primary:hover, -.btn-primary.disabled:focus, -.btn-primary[disabled]:focus, -fieldset[disabled] .btn-primary:focus, -.btn-primary.disabled.focus, -.btn-primary[disabled].focus, -fieldset[disabled] .btn-primary.focus { - background-color: #006BB4; - border-color: #006BB4; -} -.btn-primary .badge { - color: #006BB4; - background-color: #FFF; -} -.btn-xs { - padding: 1px 5px; - font-size: 12px; - line-height: 1.5; - border-radius: 4px; -} -.navbar { - position: relative; - min-height: 45px; - margin-bottom: 0px; - border: 1px solid transparent; -} -@media (min-width: 0) { - .navbar { - border-radius: 4px; - } -} -@media (min-width: 0) { - .navbar-header { - float: left; - } -} -.navbar-collapse { - overflow-x: visible; - padding-right: 10px; - padding-left: 10px; - border-top: 1px solid transparent; - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); - -webkit-overflow-scrolling: touch; -} -.navbar-collapse.in { - overflow-y: auto; -} -@media (min-width: 0) { - .navbar-collapse { - width: auto; - border-top: 0; - box-shadow: none; - } - .navbar-collapse.collapse { - display: block !important; - height: auto !important; - padding-bottom: 0; - overflow: visible !important; - } - .navbar-collapse.in { - overflow-y: visible; - } - .navbar-fixed-top .navbar-collapse, - .navbar-fixed-bottom .navbar-collapse { - padding-left: 0; - padding-right: 0; - } -} -.navbar-fixed-top .navbar-collapse, -.navbar-fixed-bottom .navbar-collapse { - max-height: 340px; -} -@media (max-device-width: 480px) and (orientation: landscape) { - .navbar-fixed-top .navbar-collapse, - .navbar-fixed-bottom .navbar-collapse { - max-height: 200px; - } -} -.container > .navbar-header, -.container-fluid > .navbar-header, -.container > .navbar-collapse, -.container-fluid > .navbar-collapse { - margin-right: -10px; - margin-left: -10px; -} -@media (min-width: 0) { - .container > .navbar-header, - .container-fluid > .navbar-header, - .container > .navbar-collapse, - .container-fluid > .navbar-collapse { - margin-right: 0; - margin-left: 0; - } -} -.navbar-fixed-top, -.navbar-fixed-bottom { - position: fixed; - right: 0; - left: 0; - z-index: 1050; -} -@media (min-width: 0) { - .navbar-fixed-top, - .navbar-fixed-bottom { - border-radius: 0; - } -} -.navbar-fixed-top { - top: 0; - border-width: 0 0 1px; -} -.navbar-fixed-bottom { - bottom: 0; - margin-bottom: 0; - border-width: 1px 0 0; -} -.navbar-brand { - float: left; - padding: 12.5px 10px; - font-size: 18px; - line-height: 20px; - height: 45px; -} -.navbar-brand:hover, -.navbar-brand:focus { - text-decoration: none; -} -.navbar-brand > img { - display: block; -} -@media (min-width: 0) { - .navbar > .container .navbar-brand, - .navbar > .container-fluid .navbar-brand { - margin-left: -10px; - } -} -.navbar-toggle { - position: relative; - float: right; - margin-right: 10px; - padding: 9px 10px; - margin-top: 5.5px; - margin-bottom: 5.5px; - background-color: transparent; - background-image: none; - border: 1px solid transparent; - border-radius: 4px; -} -.navbar-toggle:focus { - outline: 0; -} -.navbar-toggle .icon-bar { - display: block; - width: 22px; - height: 2px; - border-radius: 1px; -} -.navbar-toggle .icon-bar + .icon-bar { - margin-top: 4px; -} -@media (min-width: 0) { - .navbar-toggle { - display: none; - } -} -.navbar-nav { - margin: 6.25px -10px; -} -.navbar-nav > li > a { - padding-top: 10px; - padding-bottom: 10px; - line-height: 20px; -} -@media (max-width: -1) { - .navbar-nav .open .dropdown-menu { - position: static; - float: none; - width: auto; - margin-top: 0; - background-color: transparent; - border: 0; - box-shadow: none; - } - .navbar-nav .open .dropdown-menu > li > a, - .navbar-nav .open .dropdown-menu .dropdown-header { - padding: 5px 15px 5px 25px; - } - .navbar-nav .open .dropdown-menu > li > a { - line-height: 20px; - } - .navbar-nav .open .dropdown-menu > li > a:hover, - .navbar-nav .open .dropdown-menu > li > a:focus { - background-image: none; - } -} -@media (min-width: 0) { - .navbar-nav { - float: left; - margin: 0; - } - .navbar-nav > li { - float: left; - } - .navbar-nav > li > a { - padding-top: 12.5px; - padding-bottom: 12.5px; - } -} -.navbar-form { - margin-left: -10px; - margin-right: -10px; - padding: 10px 10px; - border-top: 1px solid transparent; - border-bottom: 1px solid transparent; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); - margin-top: 6.5px; - margin-bottom: 6.5px; -} -@media (min-width: 768px) { - .navbar-form .form-group { - display: inline-block; - margin-bottom: 0; - vertical-align: middle; - } - .navbar-form .form-control { - display: inline-block; - width: auto; - vertical-align: middle; - } - .navbar-form .form-control-static { - display: inline-block; - } - .navbar-form .input-group { - display: inline-table; - vertical-align: middle; - } - .navbar-form .input-group .input-group-addon, - .navbar-form .input-group .form-control { - width: auto; - } - .navbar-form .input-group > .form-control { - width: 100%; - } - .navbar-form .control-label { - margin-bottom: 0; - vertical-align: middle; - } - .navbar-form .radio, - .navbar-form .checkbox { - display: inline-block; - margin-top: 0; - margin-bottom: 0; - vertical-align: middle; - } - .navbar-form .radio label, - .navbar-form .checkbox label { - padding-left: 0; - } - .navbar-form .radio input[type="radio"], - .navbar-form .checkbox input[type="checkbox"] { - position: relative; - margin-left: 0; - } - .navbar-form .has-feedback .form-control-feedback { - top: 0; - } -} -@media (max-width: -1) { - .navbar-form .form-group { - margin-bottom: 5px; - } - .navbar-form .form-group:last-child { - margin-bottom: 0; - } -} -@media (min-width: 0) { - .navbar-form { - width: auto; - border: 0; - margin-left: 0; - margin-right: 0; - padding-top: 0; - padding-bottom: 0; - -webkit-box-shadow: none; - box-shadow: none; - } -} -.navbar-nav > li > .dropdown-menu { - margin-top: 0; - border-top-right-radius: 0; - border-top-left-radius: 0; -} -.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { - margin-bottom: 0; - border-top-right-radius: 4px; - border-top-left-radius: 4px; - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; -} -.navbar-text { - margin-top: 12.5px; - margin-bottom: 12.5px; -} -@media (min-width: 0) { - .navbar-text { - float: left; - margin-left: 10px; - margin-right: 10px; - } -} -@media (min-width: 0) { - .navbar-left { - float: left !important; - } - .navbar-right { - float: right !important; - margin-right: -10px; - } - .navbar-right ~ .navbar-right { - margin-right: 0; - } -} -.navbar-default { - background-color: #F5F7FA; - border-color: transparent; -} -.navbar-default .navbar-brand { - color: #69707D; -} -.navbar-default .navbar-brand:hover, -.navbar-default .navbar-brand:focus { - color: #69707D; - background-color: transparent; -} -.navbar-default .navbar-text { - color: #69707D; -} -.navbar-default .navbar-nav > li > a { - color: #69707D; -} -.navbar-default .navbar-nav > li > a:hover, -.navbar-default .navbar-nav > li > a:focus { - color: #69707D; - background-color: transparent; -} -.navbar-default .navbar-nav > .active > a, -.navbar-default .navbar-nav > .active > a:hover, -.navbar-default .navbar-nav > .active > a:focus { - color: #343741; - background-color: transparent; -} -.navbar-default .navbar-nav > .disabled > a, -.navbar-default .navbar-nav > .disabled > a:hover, -.navbar-default .navbar-nav > .disabled > a:focus { - color: #69707D; - background-color: transparent; -} -.navbar-default .navbar-toggle { - border-color: #d3dce9; -} -.navbar-default .navbar-toggle:hover, -.navbar-default .navbar-toggle:focus { - background-color: #d3dce9; -} -.navbar-default .navbar-toggle .icon-bar { - background-color: #FFF; -} -.navbar-default .navbar-collapse, -.navbar-default .navbar-form { - border-color: transparent; -} -.navbar-default .navbar-nav > .open > a, -.navbar-default .navbar-nav > .open > a:hover, -.navbar-default .navbar-nav > .open > a:focus { - background-color: transparent; - color: #343741; -} -@media (max-width: -1) { - .navbar-default .navbar-nav .open .dropdown-menu > li > a { - color: #69707D; - } - .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, - .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { - color: #69707D; - background-color: transparent; - } - .navbar-default .navbar-nav .open .dropdown-menu > .active > a, - .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, - .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { - color: #343741; - background-color: transparent; - } - .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, - .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, - .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { - color: #69707D; - background-color: transparent; - } -} -.navbar-default .navbar-link { - color: #69707D; -} -.navbar-default .navbar-link:hover { - color: #69707D; -} -.navbar-inverse { - background-color: #343741; - border-color: #1d1f25; -} -.navbar-inverse .navbar-brand { - color: #FFF; -} -.navbar-inverse .navbar-brand:hover, -.navbar-inverse .navbar-brand:focus { - color: #FFF; - background-color: #4b4f5d; -} -.navbar-inverse .navbar-text { - color: #FFF; -} -.navbar-inverse .navbar-nav > li > a { - color: #D3DAE6; -} -.navbar-inverse .navbar-nav > li > a:hover, -.navbar-inverse .navbar-nav > li > a:focus { - color: #FFF; - background-color: #61677a; -} -.navbar-inverse .navbar-nav > .active > a, -.navbar-inverse .navbar-nav > .active > a:hover, -.navbar-inverse .navbar-nav > .active > a:focus { - color: #FFF; - background-color: #69707D; -} -.navbar-inverse .navbar-nav > .disabled > a, -.navbar-inverse .navbar-nav > .disabled > a:hover, -.navbar-inverse .navbar-nav > .disabled > a:focus { - color: #b2bac6; - background-color: transparent; -} -.navbar-inverse .navbar-toggle { - border-color: #1d1f25; -} -.navbar-inverse .navbar-toggle:hover, -.navbar-inverse .navbar-toggle:focus { - background-color: #1d1f25; -} -.navbar-inverse .navbar-toggle .icon-bar { - background-color: #FFF; -} -.navbar-inverse .navbar-collapse, -.navbar-inverse .navbar-form { - border-color: #24262d; -} -.navbar-inverse .navbar-nav > .open > a, -.navbar-inverse .navbar-nav > .open > a:hover, -.navbar-inverse .navbar-nav > .open > a:focus { - background-color: #69707D; - color: #FFF; -} -@media (max-width: -1) { - .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { - border-color: #1d1f25; - } - .navbar-inverse .navbar-nav .open .dropdown-menu .divider { - background-color: #1d1f25; - } - .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { - color: #D3DAE6; - } - .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, - .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { - color: #FFF; - background-color: #61677a; - } - .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, - .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, - .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { - color: #FFF; - background-color: #69707D; - } - .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, - .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, - .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { - color: #b2bac6; - background-color: transparent; - } -} -.navbar-inverse .navbar-link { - color: #D3DAE6; -} -.navbar-inverse .navbar-link:hover { - color: #FFF; -} -.close { - float: right; - font-size: 21px; - font-weight: bold; - line-height: 1; - color: #000; - text-shadow: none; - opacity: 0.2; - filter: alpha(opacity=20); -} -.close:hover, -.close:focus { - color: #000; - text-decoration: none; - cursor: pointer; - opacity: 0.5; - filter: alpha(opacity=50); -} -button.close { - padding: 0; - cursor: pointer; - background: transparent; - border: 0; - -webkit-appearance: none; -} -.modal-open { - overflow: hidden; -} -.modal { - display: none; - overflow: hidden; - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1070; - -webkit-overflow-scrolling: touch; - outline: 0; -} -.modal.fade .modal-dialog { - -webkit-transform: translate(0, -25%); - -ms-transform: translate(0, -25%); - -o-transform: translate(0, -25%); - transform: translate(0, -25%); - -webkit-transition: -webkit-transform 0.3s ease-out; - -moz-transition: -moz-transform 0.3s ease-out; - -o-transition: -o-transform 0.3s ease-out; - transition: transform 0.3s ease-out; -} -.modal.in .modal-dialog { - -webkit-transform: translate(0, 0); - -ms-transform: translate(0, 0); - -o-transform: translate(0, 0); - transform: translate(0, 0); -} -.modal-open .modal { - overflow-x: hidden; - overflow-y: auto; -} -.modal-dialog { - position: relative; - width: auto; - margin: 10px; -} -.modal-content { - position: relative; - background-color: #FFF; - border: 1px solid #98A2B3; - border: 1px solid rgba(0, 0, 0, 0.2); - border-radius: 4px; - -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); - box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); - background-clip: padding-box; - outline: 0; -} -.modal-backdrop { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1060; - background-color: #000; -} -.modal-backdrop.fade { - opacity: 0; - filter: alpha(opacity=0); -} -.modal-backdrop.in { - opacity: 0.5; - filter: alpha(opacity=50); -} -.modal-header { - padding: 15px; - border-bottom: 1px solid #e5e5e5; -} -.modal-header .close { - margin-top: -2px; -} -.modal-title { - margin: 0; - line-height: 1.42857143; -} -.modal-body { - position: relative; - padding: 15px; -} -.modal-footer { - padding: 15px; - text-align: right; - border-top: 1px solid #e5e5e5; -} -.modal-scrollbar-measure { - position: absolute; - top: -9999px; - width: 50px; - height: 50px; - overflow: scroll; -} -@media (min-width: 768px) { - .modal-dialog { - width: 600px; - margin: 30px auto; - } - .modal-content { - -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); - box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); - } - .modal-sm { - width: 300px; - } -} -@media (min-width: 992px) { - .modal-lg { - width: 900px; - } -} -@-webkit-keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} -@keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} -.progress { - overflow: hidden; - height: 20px; - margin-bottom: 20px; - background-color: #b8bec8; - border-radius: 4px; - -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -} -.progress-bar { - float: left; - width: 0%; - height: 100%; - font-size: 12px; - line-height: 20px; - color: #FFF; - text-align: center; - background-color: #54B399; - -webkit-transition: width 0.6s ease; - -o-transition: width 0.6s ease; - transition: width 0.6s ease; -} -.progress-striped .progress-bar, -.progress-bar-striped { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-size: 40px 40px; -} -.progress.active .progress-bar, -.progress-bar.active { - -webkit-animation: progress-bar-stripes 2s linear infinite; - -o-animation: progress-bar-stripes 2s linear infinite; - animation: progress-bar-stripes 2s linear infinite; -} -.progress-bar-success { - background-color: #017D73; -} -.progress-striped .progress-bar-success { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} -.progress-bar-info { - background-color: #006BB4; -} -.progress-striped .progress-bar-info { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} -.progress-bar-warning { - background-color: #F5A700; -} -.progress-striped .progress-bar-warning { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} -.progress-bar-danger { - background-color: #BD271E; -} -.progress-striped .progress-bar-danger { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} -.list-group { - margin-bottom: 20px; - padding-left: 0; -} -.list-group-item { - position: relative; - display: block; - padding: 10px 15px; - margin-bottom: -1px; - background-color: #FFF; - border: 1px solid #D3DAE6; -} -.list-group-item:first-child { - border-top-right-radius: 4px; - border-top-left-radius: 4px; -} -.list-group-item:last-child { - margin-bottom: 0; - border-bottom-right-radius: 4px; - border-bottom-left-radius: 4px; -} -.list-group-item--noBorder { - border-top: 0; -} -a.list-group-item, -button.list-group-item { - color: #69707D; -} -a.list-group-item .list-group-item-heading, -button.list-group-item .list-group-item-heading { - color: #343741; -} -a.list-group-item:hover, -button.list-group-item:hover, -a.list-group-item:focus, -button.list-group-item:focus { - text-decoration: none; - color: #69707D; - background-color: #F5F7FA; -} -button.list-group-item { - width: 100%; - text-align: left; -} -.list-group-item.disabled, -.list-group-item.disabled:hover, -.list-group-item.disabled:focus { - background-color: #D3DAE6; - color: #b2bac6; - cursor: not-allowed; -} -.list-group-item.disabled .list-group-item-heading, -.list-group-item.disabled:hover .list-group-item-heading, -.list-group-item.disabled:focus .list-group-item-heading { - color: inherit; -} -.list-group-item.disabled .list-group-item-text, -.list-group-item.disabled:hover .list-group-item-text, -.list-group-item.disabled:focus .list-group-item-text { - color: #b2bac6; -} -.list-group-item.active, -.list-group-item.active:hover, -.list-group-item.active:focus { - z-index: 2; - color: #343741; - background-color: #343741; - border-color: #343741; -} -.list-group-item.active .list-group-item-heading, -.list-group-item.active:hover .list-group-item-heading, -.list-group-item.active:focus .list-group-item-heading, -.list-group-item.active .list-group-item-heading > small, -.list-group-item.active:hover .list-group-item-heading > small, -.list-group-item.active:focus .list-group-item-heading > small, -.list-group-item.active .list-group-item-heading > .small, -.list-group-item.active:hover .list-group-item-heading > .small, -.list-group-item.active:focus .list-group-item-heading > .small { - color: inherit; -} -.list-group-item.active .list-group-item-text, -.list-group-item.active:hover .list-group-item-text, -.list-group-item.active:focus .list-group-item-text { - color: #969bab; -} -.list-group-item-success { - color: #FFF; - background-color: #017D73; -} -a.list-group-item-success, -button.list-group-item-success { - color: #FFF; -} -a.list-group-item-success .list-group-item-heading, -button.list-group-item-success .list-group-item-heading { - color: inherit; -} -a.list-group-item-success:hover, -button.list-group-item-success:hover, -a.list-group-item-success:focus, -button.list-group-item-success:focus { - color: #FFF; - background-color: #01645c; -} -a.list-group-item-success.active, -button.list-group-item-success.active, -a.list-group-item-success.active:hover, -button.list-group-item-success.active:hover, -a.list-group-item-success.active:focus, -button.list-group-item-success.active:focus { - color: #fff; - background-color: #FFF; - border-color: #FFF; -} -.list-group-item-info { - color: #FFF; - background-color: #006BB4; -} -a.list-group-item-info, -button.list-group-item-info { - color: #FFF; -} -a.list-group-item-info .list-group-item-heading, -button.list-group-item-info .list-group-item-heading { - color: inherit; -} -a.list-group-item-info:hover, -button.list-group-item-info:hover, -a.list-group-item-info:focus, -button.list-group-item-info:focus { - color: #FFF; - background-color: #005c9b; -} -a.list-group-item-info.active, -button.list-group-item-info.active, -a.list-group-item-info.active:hover, -button.list-group-item-info.active:hover, -a.list-group-item-info.active:focus, -button.list-group-item-info.active:focus { - color: #fff; - background-color: #FFF; - border-color: #FFF; -} -.list-group-item-warning { - color: #FFF; - background-color: #F5A700; -} -a.list-group-item-warning, -button.list-group-item-warning { - color: #FFF; -} -a.list-group-item-warning .list-group-item-heading, -button.list-group-item-warning .list-group-item-heading { - color: inherit; -} -a.list-group-item-warning:hover, -button.list-group-item-warning:hover, -a.list-group-item-warning:focus, -button.list-group-item-warning:focus { - color: #FFF; - background-color: #dc9600; -} -a.list-group-item-warning.active, -button.list-group-item-warning.active, -a.list-group-item-warning.active:hover, -button.list-group-item-warning.active:hover, -a.list-group-item-warning.active:focus, -button.list-group-item-warning.active:focus { - color: #fff; - background-color: #FFF; - border-color: #FFF; -} -.list-group-item-danger { - color: #FFF; - background-color: #BD271E; -} -a.list-group-item-danger, -button.list-group-item-danger { - color: #FFF; -} -a.list-group-item-danger .list-group-item-heading, -button.list-group-item-danger .list-group-item-heading { - color: inherit; -} -a.list-group-item-danger:hover, -button.list-group-item-danger:hover, -a.list-group-item-danger:focus, -button.list-group-item-danger:focus { - color: #FFF; - background-color: #a7221b; -} -a.list-group-item-danger.active, -button.list-group-item-danger.active, -a.list-group-item-danger.active:hover, -button.list-group-item-danger.active:hover, -a.list-group-item-danger.active:focus, -button.list-group-item-danger.active:focus { - color: #fff; - background-color: #FFF; - border-color: #FFF; -} -.list-group-item-heading { - margin-top: 0; - margin-bottom: 5px; -} -.list-group-item-text { - margin-bottom: 0; - line-height: 1.3; -} -.nav { - margin-bottom: 0; - padding-left: 0; - list-style: none; -} -.nav > li { - position: relative; - display: block; -} -.nav > li > a { - position: relative; - display: block; - padding: 10px 15px; -} -.nav > li > a:hover, -.nav > li > a:focus { - text-decoration: none; - background-color: #D3DAE6; -} -.nav > li.disabled > a { - color: #b2bac6; -} -.nav > li.disabled > a:hover, -.nav > li.disabled > a:focus { - color: #b2bac6; - text-decoration: none; - background-color: transparent; - cursor: not-allowed; -} -.nav .open > a, -.nav .open > a:hover, -.nav .open > a:focus { - background-color: #D3DAE6; - border-color: #006BB4; -} -.nav .nav-divider { - height: 1px; - margin: 9px 0; - overflow: hidden; - background-color: #e5e5e5; -} -.nav > li > a > img { - max-width: none; -} -.nav-tabs { - border-bottom: 1px solid #D3DAE6; -} -.nav-tabs > li { - float: left; - margin-bottom: -1px; -} -.nav-tabs > li > a { - margin-right: 2px; - line-height: 1.42857143; - border: 1px solid transparent; - border-radius: 4px 4px 0 0; -} -.nav-tabs > li > a:hover { - border-color: #D3DAE6; - background-color: #FFF; -} -.nav-tabs > li.active > a, -.nav-tabs > li.active > a:hover, -.nav-tabs > li.active > a:focus { - color: #343741; - background-color: #FFF; - border: 1px solid #D3DAE6; - border-bottom-color: transparent; - cursor: default; -} -.nav-tabs.nav-justified { - width: 100%; - border-bottom: 0; -} -.nav-tabs.nav-justified > li { - float: none; -} -.nav-tabs.nav-justified > li > a { - text-align: center; - margin-bottom: 5px; -} -.nav-tabs.nav-justified > .dropdown .dropdown-menu { - top: auto; - left: auto; -} -@media (min-width: 768px) { - .nav-tabs.nav-justified > li { - display: table-cell; - width: 1%; - } - .nav-tabs.nav-justified > li > a { - margin-bottom: 0; - } -} -.nav-tabs.nav-justified > li > a { - margin-right: 0; - border-radius: 4px; -} -.nav-tabs.nav-justified > .active > a, -.nav-tabs.nav-justified > .active > a:hover, -.nav-tabs.nav-justified > .active > a:focus { - border: 1px solid #FFF; -} -@media (min-width: 768px) { - .nav-tabs.nav-justified > li > a { - border-bottom: 1px solid #FFF; - border-radius: 4px 4px 0 0; - } - .nav-tabs.nav-justified > .active > a, - .nav-tabs.nav-justified > .active > a:hover, - .nav-tabs.nav-justified > .active > a:focus { - border-bottom-color: #FFF; - } -} -.nav-pills > li { - float: left; -} -.nav-pills > li > a { - border-radius: 4px; -} -.nav-pills > li + li { - margin-left: 2px; -} -.nav-pills > li.active > a, -.nav-pills > li.active > a:hover, -.nav-pills > li.active > a:focus { - color: #FFF; - background-color: #006BB4; -} -.nav-stacked > li { - float: none; -} -.nav-stacked > li + li { - margin-top: 2px; - margin-left: 0; -} -.nav-justified { - width: 100%; -} -.nav-justified > li { - float: none; -} -.nav-justified > li > a { - text-align: center; - margin-bottom: 5px; -} -.nav-justified > .dropdown .dropdown-menu { - top: auto; - left: auto; -} -@media (min-width: 768px) { - .nav-justified > li { - display: table-cell; - width: 1%; - } - .nav-justified > li > a { - margin-bottom: 0; - } -} -.nav-tabs-justified { - border-bottom: 0; -} -.nav-tabs-justified > li > a { - margin-right: 0; - border-radius: 4px; -} -.nav-tabs-justified > .active > a, -.nav-tabs-justified > .active > a:hover, -.nav-tabs-justified > .active > a:focus { - border: 1px solid #FFF; -} -@media (min-width: 768px) { - .nav-tabs-justified > li > a { - border-bottom: 1px solid #FFF; - border-radius: 4px 4px 0 0; - } - .nav-tabs-justified > .active > a, - .nav-tabs-justified > .active > a:hover, - .nav-tabs-justified > .active > a:focus { - border-bottom-color: #FFF; - } -} -.tab-content > .tab-pane { - display: none; -} -.tab-content > .active { - display: block; -} -.nav-tabs .dropdown-menu { - margin-top: -1px; - border-top-right-radius: 0; - border-top-left-radius: 0; -} -.alert { - padding: 15px; - margin-bottom: 20px; - border: 1px solid transparent; - border-radius: 4px; -} -.alert h4 { - margin-top: 0; - color: inherit; -} -.alert .alert-link { - font-weight: bold; -} -.alert > p, -.alert > ul { - margin-bottom: 0; -} -.alert > p + p { - margin-top: 5px; -} -.alert-dismissable, -.alert-dismissible { - padding-right: 35px; -} -.alert-dismissable .close, -.alert-dismissible .close { - position: relative; - top: -2px; - right: -21px; - color: inherit; -} -.alert-success { - background-color: #017D73; - border-color: #014a44; - color: #FFF; -} -.alert-success hr { - border-top-color: #00312d; -} -.alert-success .alert-link { - color: #e6e6e6; -} -.alert-info { - background-color: #006BB4; - border-color: #004d81; - color: #FFF; -} -.alert-info hr { - border-top-color: #003e68; -} -.alert-info .alert-link { - color: #e6e6e6; -} -.alert-warning { - background-color: #F5A700; - border-color: #c28400; - color: #FFF; -} -.alert-warning hr { - border-top-color: #a97300; -} -.alert-warning .alert-link { - color: #e6e6e6; -} -.alert-danger { - background-color: #BD271E; - border-color: #911e17; - color: #FFF; -} -.alert-danger hr { - border-top-color: #7b1914; -} -.alert-danger .alert-link { - color: #e6e6e6; -} -.bsTooltip { - position: absolute; - z-index: 1040; - display: block; - font-family: 'Open Sans', Helvetica, Arial, sans-serif; - font-style: normal; - font-weight: normal; - letter-spacing: normal; - line-break: auto; - line-height: 1.42857143; - text-align: left; - text-align: start; - text-decoration: none; - text-shadow: none; - text-transform: none; - white-space: normal; - word-break: normal; - word-spacing: normal; - word-wrap: normal; - font-size: 12px; - opacity: 0; - filter: alpha(opacity=0); -} -.bsTooltip.in { - opacity: 0.8; - filter: alpha(opacity=80); -} -.bsTooltip.top { - margin-top: -3px; - padding: 5px 0; -} -.bsTooltip.right { - margin-left: 3px; - padding: 0 5px; -} -.bsTooltip.bottom { - margin-top: 3px; - padding: 5px 0; -} -.bsTooltip.left { - margin-left: -3px; - padding: 0 5px; -} -.bsTooltip-inner { - max-width: 200px; - padding: 3px 8px; - color: #fff; - text-align: center; - background-color: #000; - border-radius: 4px; -} -.bsTooltip-arrow { - position: absolute; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; -} -.bsTooltip.top .bsTooltip-arrow { - bottom: 0; - left: 50%; - margin-left: -5px; - border-width: 5px 5px 0; - border-top-color: #000; -} -.bsTooltip.top-left .bsTooltip-arrow { - bottom: 0; - right: 5px; - margin-bottom: -5px; - border-width: 5px 5px 0; - border-top-color: #000; -} -.bsTooltip.top-right .bsTooltip-arrow { - bottom: 0; - left: 5px; - margin-bottom: -5px; - border-width: 5px 5px 0; - border-top-color: #000; -} -.bsTooltip.right .bsTooltip-arrow { - top: 50%; - left: 0; - margin-top: -5px; - border-width: 5px 5px 5px 0; - border-right-color: #000; -} -.bsTooltip.left .bsTooltip-arrow { - top: 50%; - right: 0; - margin-top: -5px; - border-width: 5px 0 5px 5px; - border-left-color: #000; -} -.bsTooltip.bottom .bsTooltip-arrow { - top: 0; - left: 50%; - margin-left: -5px; - border-width: 0 5px 5px; - border-bottom-color: #000; -} -.bsTooltip.bottom-left .bsTooltip-arrow { - top: 0; - right: 5px; - margin-top: -5px; - border-width: 0 5px 5px; - border-bottom-color: #000; -} -.bsTooltip.bottom-right .bsTooltip-arrow { - top: 0; - left: 5px; - margin-top: -5px; - border-width: 0 5px 5px; - border-bottom-color: #000; -} -.visible-xs, -.visible-sm, -.visible-md, -.visible-lg { - display: none !important; -} -.visible-xs-block, -.visible-xs-inline, -.visible-xs-inline-block, -.visible-sm-block, -.visible-sm-inline, -.visible-sm-inline-block, -.visible-md-block, -.visible-md-inline, -.visible-md-inline-block, -.visible-lg-block, -.visible-lg-inline, -.visible-lg-inline-block { - display: none !important; -} -@media (max-width: 767px) { - .visible-xs { - display: block !important; - } - table.visible-xs { - display: table !important; - } - tr.visible-xs { - display: table-row !important; - } - th.visible-xs, - td.visible-xs { - display: table-cell !important; - } -} -@media (max-width: 767px) { - .visible-xs-block { - display: block !important; - } -} -@media (max-width: 767px) { - .visible-xs-inline { - display: inline !important; - } -} -@media (max-width: 767px) { - .visible-xs-inline-block { - display: inline-block !important; - } -} -@media (min-width: 768px) and (max-width: 991px) { - .visible-sm { - display: block !important; - } - table.visible-sm { - display: table !important; - } - tr.visible-sm { - display: table-row !important; - } - th.visible-sm, - td.visible-sm { - display: table-cell !important; - } -} -@media (min-width: 768px) and (max-width: 991px) { - .visible-sm-block { - display: block !important; - } -} -@media (min-width: 768px) and (max-width: 991px) { - .visible-sm-inline { - display: inline !important; - } -} -@media (min-width: 768px) and (max-width: 991px) { - .visible-sm-inline-block { - display: inline-block !important; - } -} -@media (min-width: 992px) and (max-width: 1199px) { - .visible-md { - display: block !important; - } - table.visible-md { - display: table !important; - } - tr.visible-md { - display: table-row !important; - } - th.visible-md, - td.visible-md { - display: table-cell !important; - } -} -@media (min-width: 992px) and (max-width: 1199px) { - .visible-md-block { - display: block !important; - } -} -@media (min-width: 992px) and (max-width: 1199px) { - .visible-md-inline { - display: inline !important; - } -} -@media (min-width: 992px) and (max-width: 1199px) { - .visible-md-inline-block { - display: inline-block !important; - } -} -@media (min-width: 1200px) { - .visible-lg { - display: block !important; - } - table.visible-lg { - display: table !important; - } - tr.visible-lg { - display: table-row !important; - } - th.visible-lg, - td.visible-lg { - display: table-cell !important; - } -} -@media (min-width: 1200px) { - .visible-lg-block { - display: block !important; - } -} -@media (min-width: 1200px) { - .visible-lg-inline { - display: inline !important; - } -} -@media (min-width: 1200px) { - .visible-lg-inline-block { - display: inline-block !important; - } -} -@media (max-width: 767px) { - .hidden-xs { - display: none !important; - } -} -@media (min-width: 768px) and (max-width: 991px) { - .hidden-sm { - display: none !important; - } -} -@media (min-width: 992px) and (max-width: 1199px) { - .hidden-md { - display: none !important; - } -} -@media (min-width: 1200px) { - .hidden-lg { - display: none !important; - } -} -.visible-print { - display: none !important; -} -@media print { - .visible-print { - display: block !important; - } - table.visible-print { - display: table !important; - } - tr.visible-print { - display: table-row !important; - } - th.visible-print, - td.visible-print { - display: table-cell !important; - } -} -.visible-print-block { - display: none !important; -} -@media print { - .visible-print-block { - display: block !important; - } -} -.visible-print-inline { - display: none !important; -} -@media print { - .visible-print-inline { - display: inline !important; - } -} -.visible-print-inline-block { - display: none !important; -} -@media print { - .visible-print-inline-block { - display: inline-block !important; - } -} -@media print { - .hidden-print { - display: none !important; - } -} -.caret { - display: inline-block; - width: 0; - height: 0; - margin-left: 2px; - vertical-align: middle; - border-top: 4px dashed; - border-top: 4px solid \9; - border-right: 4px solid transparent; - border-left: 4px solid transparent; -} -.dropup, -.dropdown { - position: relative; -} -.dropdown-toggle:focus { - outline: 0; -} -.dropdown-menu { - position: absolute; - top: 100%; - left: 0; - z-index: 1000; - display: none; - float: left; - min-width: 160px; - padding: 5px 0; - margin: 2px 0 0; - list-style: none; - font-size: 14px; - text-align: left; - background-color: #FFF; - border: 1px solid #D3DAE6; - border-radius: 4px; - box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.1); - background-clip: padding-box; -} -.dropdown-menu.pull-right { - right: 0; - left: auto; -} -.dropdown-menu .divider { - height: 1px; - margin: 9px 0; - overflow: hidden; - background-color: #D3DAE6; -} -.dropdown-menu > li > a, -.dropdown-menu > li > button { - display: block; - padding: 3px 20px; - clear: both; - font-weight: normal; - line-height: 1.42857143; - color: #7b7b7b; - white-space: nowrap; -} -.dropdown-menu > li > button { - appearance: none; - background: none; - border: none; - width: 100%; - text-align: left; -} -.dropdown-menu > li > a:hover, -.dropdown-menu > li > button:hover, -.dropdown-menu > li > a:focus, -.dropdown-menu > li > button:focus { - text-decoration: none; - color: #FFF; - background-color: #343741; -} -.dropdown-menu > .active > button, -.dropdown-menu > .active > a, -.dropdown-menu > .active > button:hover, -.dropdown-menu > .active > a:hover, -.dropdown-menu > .active > button:focus, -.dropdown-menu > .active > a:focus { - color: #FFF; - text-decoration: none; - outline: 0; - background-color: #343741; -} -.dropdown-menu > .disabled > a, -.dropdown-menu > .disabled > a:hover, -.dropdown-menu > .disabled > a:focus { - color: #98A2B3; -} -.dropdown-menu > .disabled > a:hover, -.dropdown-menu > .disabled > a:focus { - text-decoration: none; - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); - cursor: not-allowed; -} -.open > .dropdown-menu { - display: block; -} -.open > a { - outline: 0; -} -.dropdown-menu-right { - left: auto; - right: 0; -} -.dropdown-menu-left { - left: 0; - right: auto; -} -.dropdown-header { - display: block; - padding: 3px 20px; - font-size: 12px; - line-height: 1.42857143; - color: #98A2B3; - white-space: nowrap; -} -.dropdown-backdrop { - position: fixed; - left: 0; - right: 0; - bottom: 0; - top: 0; - z-index: 990; -} -.pull-right > .dropdown-menu { - right: 0; - left: auto; -} -.dropup .caret, -.navbar-fixed-bottom .dropdown .caret { - border-top: 0; - border-bottom: 4px dashed; - border-bottom: 4px solid \9; - content: ""; -} -.dropup .dropdown-menu, -.navbar-fixed-bottom .dropdown .dropdown-menu { - top: auto; - bottom: 100%; - margin-bottom: 2px; -} -@media (min-width: 0) { - .navbar-right .dropdown-menu { - left: auto; - right: 0; - } - .navbar-right .dropdown-menu-left { - left: 0; - right: auto; - } -} -.input-group { - position: relative; - display: table; - border-collapse: separate; -} -.input-group[class*="col-"] { - float: none; - padding-left: 0; - padding-right: 0; -} -.input-group .form-control { - position: relative; - z-index: 2; - float: left; - width: 100%; - margin-bottom: 0; -} -.input-group .form-control:focus { - z-index: 3; -} -.input-group-lg > .form-control, -.input-group-lg > .input-group-addon { - height: 62px; - padding: 18px 27px; - font-size: 18px; - line-height: 1.3333333; - border-radius: 4px; -} -select.input-group-lg > .form-control, -select.input-group-lg > .input-group-addon { - height: 62px; - line-height: 62px; -} -textarea.input-group-lg > .form-control, -textarea.input-group-lg > .input-group-addon, -select[multiple].input-group-lg > .form-control, -select[multiple].input-group-lg > .input-group-addon { - height: auto; -} -.input-group-sm > .form-control, -.input-group-sm > .input-group-addon { - height: 32px; - padding: 6px 9px; - font-size: 12px; - line-height: 1.5; - border-radius: 4px; -} -select.input-group-sm > .form-control, -select.input-group-sm > .input-group-addon { - height: 32px; - line-height: 32px; -} -textarea.input-group-sm > .form-control, -textarea.input-group-sm > .input-group-addon, -select[multiple].input-group-sm > .form-control, -select[multiple].input-group-sm > .input-group-addon { - height: auto; -} -.input-group-addon, -.input-group .form-control { - display: table-cell; -} -.input-group-addon:not(:first-child):not(:last-child), -.input-group .form-control:not(:first-child):not(:last-child) { - border-radius: 0; -} -.input-group-addon { - width: 1%; - white-space: nowrap; - vertical-align: middle; -} -.input-group-addon { - padding: 5px 15px; - font-size: 14px; - font-weight: normal; - line-height: 1; - color: #343741; - text-align: center; - background-color: #D3DAE6; - border: 1px solid #D3DAE6; - border-radius: 4px; -} -.input-group-addon.input-sm { - padding: 6px 9px; - font-size: 12px; - border-radius: 4px; -} -.input-group-addon.input-lg { - padding: 18px 27px; - font-size: 18px; - border-radius: 4px; -} -.input-group-addon input[type="radio"], -.input-group-addon input[type="checkbox"] { - margin-top: 0; -} -.input-group .form-control:first-child, -.input-group-addon:first-child { - border-bottom-right-radius: 0; - border-top-right-radius: 0; -} -.input-group-addon:first-child { - border-right: 0; -} -.input-group .form-control:last-child, -.input-group-addon:last-child { - border-bottom-left-radius: 0; - border-top-left-radius: 0; -} -.input-group-addon:last-child { - border-left: 0; -} -.pagination { - display: inline-block; - padding-left: 0; - margin: 20px 0; - border-radius: 4px; -} -.pagination > li { - display: inline; -} -.pagination > li > a, -.pagination > li > span { - position: relative; - float: left; - padding: 5px 15px; - line-height: 1.42857143; - text-decoration: none; - color: #006BB4; - background-color: transparent; - border: 1px solid transparent; - margin-left: -1px; -} -.pagination > li:first-child > a, -.pagination > li:first-child > span { - margin-left: 0; - border-bottom-left-radius: 4px; - border-top-left-radius: 4px; -} -.pagination > li:last-child > a, -.pagination > li:last-child > span { - border-bottom-right-radius: 4px; - border-top-right-radius: 4px; -} -.pagination > li > a:hover, -.pagination > li > span:hover, -.pagination > li > a:focus, -.pagination > li > span:focus { - z-index: 2; - color: #006BB4; - background-color: rgba(0, 0, 0, 0); - border-color: transparent; -} -.pagination > .active > a, -.pagination > .active > span, -.pagination > .active > a:hover, -.pagination > .active > span:hover, -.pagination > .active > a:focus, -.pagination > .active > span:focus { - z-index: 3; - color: #343741; - background-color: rgba(0, 0, 0, 0); - border-color: transparent; - cursor: default; -} -.pagination > .disabled > span, -.pagination > .disabled > span:hover, -.pagination > .disabled > span:focus, -.pagination > .disabled > a, -.pagination > .disabled > a:hover, -.pagination > .disabled > a:focus { - color: #343741; - background-color: rgba(38, 38, 38, 0); - border-color: transparent; - cursor: not-allowed; -} -.pagination-lg > li > a, -.pagination-lg > li > span { - padding: 18px 27px; - font-size: 18px; - line-height: 1.3333333; -} -.pagination-lg > li:first-child > a, -.pagination-lg > li:first-child > span { - border-bottom-left-radius: 4px; - border-top-left-radius: 4px; -} -.pagination-lg > li:last-child > a, -.pagination-lg > li:last-child > span { - border-bottom-right-radius: 4px; - border-top-right-radius: 4px; -} -.pagination-sm > li > a, -.pagination-sm > li > span { - padding: 6px 9px; - font-size: 12px; - line-height: 1.5; -} -.pagination-sm > li:first-child > a, -.pagination-sm > li:first-child > span { - border-bottom-left-radius: 4px; - border-top-left-radius: 4px; -} -.pagination-sm > li:last-child > a, -.pagination-sm > li:last-child > span { - border-bottom-right-radius: 4px; - border-top-right-radius: 4px; -} -.pager { - padding-left: 0; - margin: 20px 0; - list-style: none; - text-align: center; -} -.pager li { - display: inline; -} -.pager li > a, -.pager li > span { - display: inline-block; - padding: 5px 14px; - background-color: transparent; - border: 1px solid transparent; - border-radius: 0; -} -.pager li > a:hover, -.pager li > a:focus { - text-decoration: none; - background-color: rgba(0, 0, 0, 0); -} -.pager .next > a, -.pager .next > span { - float: right; -} -.pager .previous > a, -.pager .previous > span { - float: left; -} -.pager .disabled > a, -.pager .disabled > a:hover, -.pager .disabled > a:focus, -.pager .disabled > span { - color: #FFF; - background-color: transparent; - cursor: not-allowed; -} -.label { - display: inline; - padding: 0.2em 0.6em 0.3em; - font-size: 75%; - font-weight: bold; - line-height: 1; - color: #FFF; - text-align: center; - white-space: nowrap; - vertical-align: baseline; - border-radius: 0.25em; -} -a.label:hover, -a.label:focus { - color: #FFF; - text-decoration: none; - cursor: pointer; -} -.label:empty { - display: none; -} -.label-default { - background-color: #006BB4; -} -.label-default[href]:hover, -.label-default[href]:focus { - background-color: #004d81; -} -.label-primary { - background-color: #343741; -} -.label-primary[href]:hover, -.label-primary[href]:focus { - background-color: #1d1f25; -} -.label-success { - background-color: #017D73; -} -.label-success[href]:hover, -.label-success[href]:focus { - background-color: #014a44; -} -.label-info { - background-color: #006BB4; -} -.label-info[href]:hover, -.label-info[href]:focus { - background-color: #004d81; -} -.label-warning { - background-color: #F5A700; -} -.label-warning[href]:hover, -.label-warning[href]:focus { - background-color: #c28400; -} -.label-danger { - background-color: #BD271E; -} -.label-danger[href]:hover, -.label-danger[href]:focus { - background-color: #911e17; -} -.panel { - margin-bottom: 20px; - background-color: #FFF; - border: 1px solid transparent; - border-radius: 4px; - -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); -} -.panel-body { - padding: 15px; -} -.panel-heading { - padding: 10px 15px; - border-bottom: 1px solid transparent; - border-top-right-radius: 3px; - border-top-left-radius: 3px; -} -.panel-heading > .dropdown .dropdown-toggle { - color: inherit; -} -.panel-title { - margin-top: 0; - margin-bottom: 0; - font-size: 16px; - color: inherit; -} -.panel-title > a, -.panel-title > small, -.panel-title > .small, -.panel-title > small > a, -.panel-title > .small > a { - color: inherit; -} -.panel-footer { - padding: 10px 15px; - background-color: #F5F7FA; - border-top: 1px solid #D3DAE6; - border-bottom-right-radius: 3px; - border-bottom-left-radius: 3px; -} -.panel > .list-group, -.panel > .panel-collapse > .list-group { - margin-bottom: 0; -} -.panel > .list-group .list-group-item, -.panel > .panel-collapse > .list-group .list-group-item { - border-width: 1px 0; - border-radius: 0; -} -.panel > .list-group:first-child .list-group-item:first-child, -.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child { - border-top: 0; - border-top-right-radius: 3px; - border-top-left-radius: 3px; -} -.panel > .list-group:last-child .list-group-item:last-child, -.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child { - border-bottom: 0; - border-bottom-right-radius: 3px; - border-bottom-left-radius: 3px; -} -.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child { - border-top-right-radius: 0; - border-top-left-radius: 0; -} -.panel-heading + .list-group .list-group-item:first-child { - border-top-width: 0; -} -.list-group + .panel-footer { - border-top-width: 0; -} -.panel > .table, -.panel > .table-responsive > .table, -.panel > .panel-collapse > .table { - margin-bottom: 0; -} -.panel > .table caption, -.panel > .table-responsive > .table caption, -.panel > .panel-collapse > .table caption { - padding-left: 15px; - padding-right: 15px; -} -.panel > .table:first-child, -.panel > .table-responsive:first-child > .table:first-child { - border-top-right-radius: 3px; - border-top-left-radius: 3px; -} -.panel > .table:first-child > thead:first-child > tr:first-child, -.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child, -.panel > .table:first-child > tbody:first-child > tr:first-child, -.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child { - border-top-left-radius: 3px; - border-top-right-radius: 3px; -} -.panel > .table:first-child > thead:first-child > tr:first-child td:first-child, -.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child, -.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child, -.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child, -.panel > .table:first-child > thead:first-child > tr:first-child th:first-child, -.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child, -.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child, -.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child { - border-top-left-radius: 3px; -} -.panel > .table:first-child > thead:first-child > tr:first-child td:last-child, -.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child, -.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child, -.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child, -.panel > .table:first-child > thead:first-child > tr:first-child th:last-child, -.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child, -.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child, -.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child { - border-top-right-radius: 3px; -} -.panel > .table:last-child, -.panel > .table-responsive:last-child > .table:last-child { - border-bottom-right-radius: 3px; - border-bottom-left-radius: 3px; -} -.panel > .table:last-child > tbody:last-child > tr:last-child, -.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child, -.panel > .table:last-child > tfoot:last-child > tr:last-child, -.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child { - border-bottom-left-radius: 3px; - border-bottom-right-radius: 3px; -} -.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child, -.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child, -.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child, -.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child, -.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child, -.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child, -.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child, -.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child { - border-bottom-left-radius: 3px; -} -.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child, -.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child, -.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child, -.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child, -.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child, -.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child, -.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child, -.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child { - border-bottom-right-radius: 3px; -} -.panel > .panel-body + .table, -.panel > .panel-body + .table-responsive, -.panel > .table + .panel-body, -.panel > .table-responsive + .panel-body { - border-top: 1px solid #D3DAE6; -} -.panel > .table > tbody:first-child > tr:first-child th, -.panel > .table > tbody:first-child > tr:first-child td { - border-top: 0; -} -.panel > .table-bordered, -.panel > .table-responsive > .table-bordered { - border: 0; -} -.panel > .table-bordered > thead > tr > th:first-child, -.panel > .table-responsive > .table-bordered > thead > tr > th:first-child, -.panel > .table-bordered > tbody > tr > th:first-child, -.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child, -.panel > .table-bordered > tfoot > tr > th:first-child, -.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child, -.panel > .table-bordered > thead > tr > td:first-child, -.panel > .table-responsive > .table-bordered > thead > tr > td:first-child, -.panel > .table-bordered > tbody > tr > td:first-child, -.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child, -.panel > .table-bordered > tfoot > tr > td:first-child, -.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child { - border-left: 0; -} -.panel > .table-bordered > thead > tr > th:last-child, -.panel > .table-responsive > .table-bordered > thead > tr > th:last-child, -.panel > .table-bordered > tbody > tr > th:last-child, -.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child, -.panel > .table-bordered > tfoot > tr > th:last-child, -.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child, -.panel > .table-bordered > thead > tr > td:last-child, -.panel > .table-responsive > .table-bordered > thead > tr > td:last-child, -.panel > .table-bordered > tbody > tr > td:last-child, -.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child, -.panel > .table-bordered > tfoot > tr > td:last-child, -.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child { - border-right: 0; -} -.panel > .table-bordered > thead > tr:first-child > td, -.panel > .table-responsive > .table-bordered > thead > tr:first-child > td, -.panel > .table-bordered > tbody > tr:first-child > td, -.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td, -.panel > .table-bordered > thead > tr:first-child > th, -.panel > .table-responsive > .table-bordered > thead > tr:first-child > th, -.panel > .table-bordered > tbody > tr:first-child > th, -.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th { - border-bottom: 0; -} -.panel > .table-bordered > tbody > tr:last-child > td, -.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td, -.panel > .table-bordered > tfoot > tr:last-child > td, -.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td, -.panel > .table-bordered > tbody > tr:last-child > th, -.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th, -.panel > .table-bordered > tfoot > tr:last-child > th, -.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th { - border-bottom: 0; -} -.panel > .table-responsive { - border: 0; - margin-bottom: 0; -} -.panel-group { - margin-bottom: 20px; -} -.panel-group .panel { - margin-bottom: 0; - border-radius: 4px; -} -.panel-group .panel + .panel { - margin-top: 5px; -} -.panel-group .panel-heading { - border-bottom: 0; -} -.panel-group .panel-heading + .panel-collapse > .panel-body, -.panel-group .panel-heading + .panel-collapse > .list-group { - border-top: 1px solid #D3DAE6; -} -.panel-group .panel-footer { - border-top: 0; -} -.panel-group .panel-footer + .panel-collapse .panel-body { - border-bottom: 1px solid #D3DAE6; -} -.panel-default { - border-color: #D3DAE6; -} -.panel-default > .panel-heading { - color: #7b7b7b; - background-color: #F5F7FA; - border-color: #D3DAE6; -} -.panel-default > .panel-heading + .panel-collapse > .panel-body { - border-top-color: #D3DAE6; -} -.panel-default > .panel-heading .badge { - color: #F5F7FA; - background-color: #7b7b7b; -} -.panel-default > .panel-footer + .panel-collapse > .panel-body { - border-bottom-color: #D3DAE6; -} -.panel-primary { - border-color: #343741; -} -.panel-primary > .panel-heading { - color: #FFF; - background-color: #343741; - border-color: #343741; -} -.panel-primary > .panel-heading + .panel-collapse > .panel-body { - border-top-color: #343741; -} -.panel-primary > .panel-heading .badge { - color: #343741; - background-color: #FFF; -} -.panel-primary > .panel-footer + .panel-collapse > .panel-body { - border-bottom-color: #343741; -} -.panel-success { - border-color: #014a44; -} -.panel-success > .panel-heading { - color: #FFF; - background-color: #017D73; - border-color: #014a44; -} -.panel-success > .panel-heading + .panel-collapse > .panel-body { - border-top-color: #014a44; -} -.panel-success > .panel-heading .badge { - color: #017D73; - background-color: #FFF; -} -.panel-success > .panel-footer + .panel-collapse > .panel-body { - border-bottom-color: #014a44; -} -.panel-info { - border-color: #004d81; -} -.panel-info > .panel-heading { - color: #FFF; - background-color: #006BB4; - border-color: #004d81; -} -.panel-info > .panel-heading + .panel-collapse > .panel-body { - border-top-color: #004d81; -} -.panel-info > .panel-heading .badge { - color: #006BB4; - background-color: #FFF; -} -.panel-info > .panel-footer + .panel-collapse > .panel-body { - border-bottom-color: #004d81; -} -.panel-warning { - border-color: #c28400; -} -.panel-warning > .panel-heading { - color: #FFF; - background-color: #F5A700; - border-color: #c28400; -} -.panel-warning > .panel-heading + .panel-collapse > .panel-body { - border-top-color: #c28400; -} -.panel-warning > .panel-heading .badge { - color: #F5A700; - background-color: #FFF; -} -.panel-warning > .panel-footer + .panel-collapse > .panel-body { - border-bottom-color: #c28400; -} -.panel-danger { - border-color: #911e17; -} -.panel-danger > .panel-heading { - color: #FFF; - background-color: #BD271E; - border-color: #911e17; -} -.panel-danger > .panel-heading + .panel-collapse > .panel-body { - border-top-color: #911e17; -} -.panel-danger > .panel-heading .badge { - color: #BD271E; - background-color: #FFF; -} -.panel-danger > .panel-footer + .panel-collapse > .panel-body { - border-bottom-color: #911e17; -} -.popover { - position: absolute; - top: 0; - left: 0; - z-index: 1010; - display: none; - max-width: 276px; - padding: 1px; - font-family: 'Open Sans', Helvetica, Arial, sans-serif; - font-style: normal; - font-weight: normal; - letter-spacing: normal; - line-break: auto; - line-height: 1.42857143; - text-align: left; - text-align: start; - text-decoration: none; - text-shadow: none; - text-transform: none; - white-space: normal; - word-break: normal; - word-spacing: normal; - word-wrap: normal; - font-size: 14px; - background-color: #FFF; - background-clip: padding-box; - border: 1px solid #D3DAE6; - border-radius: 4px; - box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.1); -} -.popover.top { - margin-top: -10px; -} -.popover.right { - margin-left: 10px; -} -.popover.bottom { - margin-top: 10px; -} -.popover.left { - margin-left: -10px; -} -.popover-title { - margin: 0; - padding: 8px 14px; - font-size: 14px; - background-color: #f7f7f7; - border-bottom: 1px solid #ebebeb; - border-radius: 3px 3px 0 0; -} -.popover-content { - padding: 9px 14px; -} -.popover > .arrow, -.popover > .arrow:after { - position: absolute; - display: block; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; -} -.popover > .arrow { - border-width: 11px; -} -.popover > .arrow:after { - border-width: 10px; - content: ""; -} -.popover.top > .arrow { - left: 50%; - margin-left: -11px; - border-bottom-width: 0; - border-top-color: #92a3c1; - border-top-color: #d3dae6; - bottom: -11px; -} -.popover.top > .arrow:after { - content: " "; - bottom: 1px; - margin-left: -10px; - border-bottom-width: 0; - border-top-color: #FFF; -} -.popover.right > .arrow { - top: 50%; - left: -11px; - margin-top: -11px; - border-left-width: 0; - border-right-color: #92a3c1; - border-right-color: #d3dae6; -} -.popover.right > .arrow:after { - content: " "; - left: 1px; - bottom: -10px; - border-left-width: 0; - border-right-color: #FFF; -} -.popover.bottom > .arrow { - left: 50%; - margin-left: -11px; - border-top-width: 0; - border-bottom-color: #92a3c1; - border-bottom-color: #d3dae6; - top: -11px; -} -.popover.bottom > .arrow:after { - content: " "; - top: 1px; - margin-left: -10px; - border-top-width: 0; - border-bottom-color: #FFF; -} -.popover.left > .arrow { - top: 50%; - right: -11px; - margin-top: -11px; - border-right-width: 0; - border-left-color: #92a3c1; - border-left-color: #d3dae6; -} -.popover.left > .arrow:after { - content: " "; - right: 1px; - border-right-width: 0; - border-left-color: #FFF; - bottom: -10px; -} -.clearfix:before, -.clearfix:after, -.container:before, -.container:after, -.container-fluid:before, -.container-fluid:after, -.row:before, -.row:after, -.form-horizontal .form-group:before, -.form-horizontal .form-group:after, -.dl-horizontal dd:before, -.dl-horizontal dd:after, -.navbar:before, -.navbar:after, -.navbar-header:before, -.navbar-header:after, -.navbar-collapse:before, -.navbar-collapse:after, -.modal-header:before, -.modal-header:after, -.modal-footer:before, -.modal-footer:after, -.nav:before, -.nav:after, -.pager:before, -.pager:after, -.panel-body:before, -.panel-body:after { - content: " "; - display: table; -} -.clearfix:after, -.container:after, -.container-fluid:after, -.row:after, -.form-horizontal .form-group:after, -.dl-horizontal dd:after, -.navbar:after, -.navbar-header:after, -.navbar-collapse:after, -.modal-header:after, -.modal-footer:after, -.nav:after, -.pager:after, -.panel-body:after { - clear: both; -} -.center-block { - display: block; - margin-left: auto; - margin-right: auto; -} -.pull-right { - float: right !important; -} -.pull-left { - float: left !important; -} -.hide { - display: none !important; -} -.show { - display: block !important; -} -.invisible { - visibility: hidden; -} -.text-hide { - font: 0/0 a; - color: transparent; - text-shadow: none; - background-color: transparent; - border: 0; -} -.hidden { - display: none !important; -} -.affix { - position: fixed; -} -.navbar > .container-fluid > .navbar-nav:not(.pull-right):first-child, -.navbar > .container-fluid > .navbar-form:not(.pull-right):first-child { - margin-left: -15px; - margin-top: 4px; -} -.navbar { - border-width: 0; -} -.navbar-btn-link { - margin: 0; - border-radius: 0; -} -@media (max-width: 768px) { - .navbar-btn-link { - width: 100%; - text-align: left; - } -} -.navbar-default .badge { - background-color: #FFF; - color: #F5F7FA; -} -.navbar-inverse .kbnGlobalNav__logoBrand { - height: 45px; - width: 252px; - background-color: #4b4f5d; -} -.navbar-inverse .kbnGlobalNav__smallLogoBrand { - height: 45px; - width: 45px; - background-color: #4b4f5d; -} -.navbar-inverse .badge { - background-color: #FFF; - color: #4b4f5d; -} -.navbar-brand { - cursor: default; - font-size: 1.8em; - user-select: none; -} -.navbar-nav { - font-size: 12px; -} -.navbar-nav > .active > a { - border-bottom-color: #7b7b7b; - background-color: transparent; -} -.navbar-toggle { - margin-top: 4px; -} -.text-primary, -.text-primary:hover { - color: #343741; -} -.text-success, -.text-success:hover { - color: #017D73; -} -.text-danger, -.text-danger:hover { - color: #BD271E; -} -.text-warning, -.text-warning:hover { - color: #F5A700; -} -.text-info, -.text-info:hover { - color: #006BB4; -} -table .success, -.table .success, -table .warning, -.table .warning, -table .danger, -.table .danger, -table .info, -.table .info { - color: #FFF; -} -table .success a, -.table .success a, -table .warning a, -.table .warning a, -table .danger a, -.table .danger a, -table .info a, -.table .info a { - color: #FFF; -} -.table-bordered > thead > tr > th, -.table-bordered > tbody > tr > th, -.table-bordered > tfoot > tr > th, -.table-bordered > thead > tr > td, -.table-bordered > tbody > tr > td, -.table-bordered > tfoot > tr > td { - border: 1px solid #D3DAE6; -} -.form-control, -input { - border-width: 1px; - -webkit-box-shadow: none; - box-shadow: none; -} -.form-control:focus, -input:focus { - -webkit-box-shadow: none; - box-shadow: none; -} -.has-warning .help-block, -.has-warning .control-label, -.has-warning .radio, -.has-warning .checkbox, -.has-warning .radio-inline, -.has-warning .checkbox-inline, -.has-warning .form-control-feedback { - color: #F5A700; -} -.has-warning .form-control, -.has-warning .form-control:focus { - border: 1px solid; - border-color: #F5A700; -} -.has-warning .input-group-addon { - border-color: #F5A700; -} -.has-error .help-block, -.has-error .control-label, -.has-error .radio, -.has-error .checkbox, -.has-error .radio-inline, -.has-error .checkbox-inline, -.has-error .form-control-feedback { - color: #BD271E; -} -.has-error .form-control, -.has-error .form-control:focus { - border: 1px solid; - border-color: #BD271E; -} -.has-error .input-group-addon { - border-color: #BD271E; -} -.has-success .help-block, -.has-success .control-label, -.has-success .radio, -.has-success .checkbox, -.has-success .radio-inline, -.has-success .checkbox-inline, -.has-success .form-control-feedback { - color: #017D73; -} -.has-success .form-control, -.has-success .form-control:focus { - border: solid #017D73; -} -.has-success .input-group-addon { - border-color: #017D73; -} -.nav .open > a, -.nav .open > a:hover, -.nav .open > a:focus { - border-color: transparent; -} -.pager a, -.pager a:hover { - color: #FFF; -} -.pager .disabled > a, -.pager .disabled > a:hover, -.pager .disabled > a:focus, -.pager .disabled > span { - background-color: rgba(38, 38, 38, 0); -} -.panel { - border-radius: 0; - -webkit-box-shadow: 0 0 0 rgba(0, 0, 0, 0); - box-shadow: 0 0 0 rgba(0, 0, 0, 0); -} -.progress { - -webkit-box-shadow: none; - box-shadow: none; -} -.progress .progress-bar { - font-size: 10px; - line-height: 10px; -} -.well { - -webkit-box-shadow: none; - box-shadow: none; -} diff --git a/src/dev/build/build_distributables.ts b/src/dev/build/build_distributables.ts index 40a1afa51add6..ae8953dd25bb0 100644 --- a/src/dev/build/build_distributables.ts +++ b/src/dev/build/build_distributables.ts @@ -64,10 +64,11 @@ export async function buildDistributables(log: ToolingLog, options: BuildOptions if (options.createGenericFolders) { await run(Tasks.CopySource); await run(Tasks.CopyBinScripts); - await run(Tasks.ReplaceFavicon); + await run(Tasks.CreateEmptyDirsAndFiles); await run(Tasks.CreateReadme); await run(Tasks.BuildBazelPackages); + await run(Tasks.ReplaceFavicon); if (options.buildCanvasShareableRuntime) { await run(Tasks.BuildCanvasShareableRuntime); } diff --git a/src/dev/build/tasks/copy_source_task.ts b/src/dev/build/tasks/copy_source_task.ts index 27426f25b90f8..536b59e663a3d 100644 --- a/src/dev/build/tasks/copy_source_task.ts +++ b/src/dev/build/tasks/copy_source_task.ts @@ -33,7 +33,6 @@ export const CopySource: Task = { '!src/**/mocks.{js,ts}', '!src/cli*/dev.js', '!src/plugins/telemetry/schema/**', - '!src/core/server/core_app/assets/favicons/favicon.distribution.{ico,png,svg}', '!src/setup_node_env/index.js', '!x-pack/plugins/telemetry_collection_xpack/schema/**', diff --git a/src/dev/build/tasks/replace_favicon.ts b/src/dev/build/tasks/replace_favicon.ts index 0d1602f324a2a..0c9c3afa1f96d 100644 --- a/src/dev/build/tasks/replace_favicon.ts +++ b/src/dev/build/tasks/replace_favicon.ts @@ -13,18 +13,24 @@ export const ReplaceFavicon: Task = { async run(config, log, build) { await copy( - config.resolveFromRepo('src/core/server/core_app/assets/favicons/favicon.distribution.ico'), - build.resolvePath('src/core/server/core_app/assets/favicons/favicon.ico') + config.resolveFromRepo( + 'packages/core/apps/core-apps-server-internal/assets/favicons/favicon.distribution.ico' + ), + build.resolvePath('packages/core/apps/core-apps-server-internal/assets/favicons/favicon.ico') ); await copy( - config.resolveFromRepo('src/core/server/core_app/assets/favicons/favicon.distribution.png'), - build.resolvePath('src/core/server/core_app/assets/favicons/favicon.png') + config.resolveFromRepo( + 'packages/core/apps/core-apps-server-internal/assets/favicons/favicon.distribution.png' + ), + build.resolvePath('packages/core/apps/core-apps-server-internal/assets/favicons/favicon.png') ); await copy( - config.resolveFromRepo('src/core/server/core_app/assets/favicons/favicon.distribution.svg'), - build.resolvePath('src/core/server/core_app/assets/favicons/favicon.svg') + config.resolveFromRepo( + 'packages/core/apps/core-apps-server-internal/assets/favicons/favicon.distribution.svg' + ), + build.resolvePath('packages/core/apps/core-apps-server-internal/assets/favicons/favicon.svg') ); }, }; diff --git a/src/dev/precommit_hook/casing_check_config.js b/src/dev/precommit_hook/casing_check_config.js index 1289768bfbcd9..2cfa9b0299c3f 100644 --- a/src/dev/precommit_hook/casing_check_config.js +++ b/src/dev/precommit_hook/casing_check_config.js @@ -31,7 +31,7 @@ export const IGNORE_FILE_GLOBS = [ '**/.*', '**/__mocks__/**/*', 'x-pack/docs/**/*', - 'packages/core/apps/core-apps-server-internal/src/assets/fonts/**/*', + 'packages/core/apps/core-apps-server-internal/assets/fonts/**/*', 'src/dev/code_coverage/ingest_coverage/integration_tests/mocks/**/*', 'packages/kbn-utility-types/test-d/**/*', '**/Jenkinsfile*', diff --git a/x-pack/plugins/canvas/shareable_runtime/index.ts b/x-pack/plugins/canvas/shareable_runtime/index.ts index 41ecd875c4326..aee57c3780503 100644 --- a/x-pack/plugins/canvas/shareable_runtime/index.ts +++ b/x-pack/plugins/canvas/shareable_runtime/index.ts @@ -6,7 +6,7 @@ */ export * from './api'; -import '@kbn/core/server/core_app/assets/legacy_light_theme.css'; +import '@kbn/core-apps-server-internal/assets/legacy_light_theme.css'; import '../public/style/index.scss'; import '@elastic/eui/dist/eui_theme_light.css'; import '@kbn/ui-framework/dist/kui_light.css'; From 4b617042f3155ec2d63cb6e97b0e11062fd18f83 Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Fri, 4 Nov 2022 16:19:08 +0100 Subject: [PATCH 25/31] [ML] Explain Log Rate Spikes: Replace chunks of queries with concurrent queue. (#144220) The queries for p-values and histograms were done in chunks of 10 parallel queries. The drawback with this approach was that if just one of these 10 queries was a lot slower, we'd still have to wait for it to finish before we could start the next chunk. This PR replaces the chunking approach with an async concurrent queue of up to 10 queries. The difference is that as soon as the first of the 10 first queries finishes, we can start another query and don't have to wait for the slower ones to finish. For this PR the `async` library is added to `package.json`, however it's not a completely new library being added since it was already used as a dependency of other packages we use in Kibana. --- package.json | 2 + .../server/routes/explain_log_rate_spikes.ts | 341 +++++++++--------- .../apis/aiops/explain_log_rate_spikes.ts | 4 +- yarn.lock | 5 + 4 files changed, 180 insertions(+), 172 deletions(-) diff --git a/package.json b/package.json index e95bd6e7d8116..1be185c0ea385 100644 --- a/package.json +++ b/package.json @@ -459,6 +459,7 @@ "adm-zip": "^0.5.9", "antlr4ts": "^0.5.0-alpha.3", "archiver": "^5.3.1", + "async": "^3.2.3", "axios": "^0.27.2", "base64-js": "^1.3.1", "bitmap-sdf": "^1.0.3", @@ -804,6 +805,7 @@ "@testing-library/user-event": "^13.5.0", "@types/apidoc": "^0.22.3", "@types/archiver": "^5.3.1", + "@types/async": "^3.2.3", "@types/babel__core": "^7.1.19", "@types/babel__generator": "^7.6.4", "@types/babel__helper-plugin-utils": "^7.10.0", diff --git a/x-pack/plugins/aiops/server/routes/explain_log_rate_spikes.ts b/x-pack/plugins/aiops/server/routes/explain_log_rate_spikes.ts index 1e1c85d5e4b30..9324b70d7225b 100644 --- a/x-pack/plugins/aiops/server/routes/explain_log_rate_spikes.ts +++ b/x-pack/plugins/aiops/server/routes/explain_log_rate_spikes.ts @@ -5,18 +5,22 @@ * 2.0. */ -import { chunk } from 'lodash'; +import { queue } from 'async'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { i18n } from '@kbn/i18n'; -import { asyncForEach } from '@kbn/std'; import type { IRouter } from '@kbn/core/server'; import { KBN_FIELD_TYPES } from '@kbn/field-types'; import type { Logger } from '@kbn/logging'; import type { DataRequestHandlerContext } from '@kbn/data-plugin/server'; import { streamFactory } from '@kbn/aiops-utils'; -import type { ChangePoint, NumericChartData, NumericHistogramField } from '@kbn/ml-agg-utils'; +import type { + ChangePoint, + ChangePointGroup, + NumericChartData, + NumericHistogramField, +} from '@kbn/ml-agg-utils'; import { fetchHistogramsForFields } from '@kbn/ml-agg-utils'; import { stringHash } from '@kbn/ml-string-hash'; @@ -209,6 +213,8 @@ export const defineExplainLogRateSpikesRoute = ( loaded += LOADED_FIELD_CANDIDATES; + const fieldCandidatesCount = fieldCandidates.length; + push( updateLoadingStateAction({ ccsWarning: false, @@ -219,14 +225,14 @@ export const defineExplainLogRateSpikesRoute = ( defaultMessage: 'Identified {fieldCandidatesCount, plural, one {# field candidate} other {# field candidates}}.', values: { - fieldCandidatesCount: fieldCandidates.length, + fieldCandidatesCount, }, } ), }) ); - if (fieldCandidates.length === 0) { + if (fieldCandidatesCount === 0) { endWithUpdatedLoadingState(); } else if (shouldStop) { logDebugMessage('shouldStop after fetching field candidates.'); @@ -239,24 +245,20 @@ export const defineExplainLogRateSpikesRoute = ( // Don't use more than 10 here otherwise Kibana will emit an error // regarding a limit of abort signal listeners of more than 10. - const CHUNK_SIZE = 10; - let chunkCount = 0; - - const fieldCandidatesChunks = chunk(fieldCandidates, CHUNK_SIZE); + const MAX_CONCURRENT_QUERIES = 10; logDebugMessage('Fetch p-values.'); - for (const fieldCandidatesChunk of fieldCandidatesChunks) { - chunkCount++; - logDebugMessage( - `Fetch p-values. Chunk ${chunkCount} of ${fieldCandidatesChunks.length}` - ); + const pValuesQueue = queue(async function (fieldCandidate: string) { + loaded += (1 / fieldCandidatesCount) * PROGRESS_STEP_P_VALUES; + let pValues: Awaited>; + try { pValues = await fetchChangePointPValues( client, request.body, - fieldCandidatesChunk, + [fieldCandidate], logger, sampleProbability, pushError, @@ -265,13 +267,11 @@ export const defineExplainLogRateSpikesRoute = ( } catch (e) { if (!isRequestAbortedError(e)) { logger.error( - `Failed to fetch p-values for ${JSON.stringify( - fieldCandidatesChunk - )}, got: \n${e.toString()}` + `Failed to fetch p-values for '${fieldCandidate}', got: \n${e.toString()}` ); - pushError(`Failed to fetch p-values for ${JSON.stringify(fieldCandidatesChunk)}.`); - } // Still continue the analysis even if chunks of p-value queries fail. - continue; + pushError(`Failed to fetch p-values for '${fieldCandidate}'.`); + } + return; } if (pValues.length > 0) { @@ -279,12 +279,10 @@ export const defineExplainLogRateSpikesRoute = ( fieldsToSample.add(d.fieldName); }); changePoints.push(...pValues); - } - loaded += (1 / fieldCandidatesChunks.length) * PROGRESS_STEP_P_VALUES; - if (pValues.length > 0) { push(addChangePointsAction(pValues)); } + push( updateLoadingStateAction({ ccsWarning: false, @@ -304,10 +302,13 @@ export const defineExplainLogRateSpikesRoute = ( if (shouldStop) { logDebugMessage('shouldStop fetching p-values.'); + pValuesQueue.kill(); end(); - return; } - } + }, MAX_CONCURRENT_QUERIES); + + pValuesQueue.push(fieldCandidates); + await pValuesQueue.drain(); if (changePoints.length === 0) { logDebugMessage('Stopping analysis, did not find change points.'); @@ -572,84 +573,84 @@ export const defineExplainLogRateSpikesRoute = ( logDebugMessage(`Fetch ${changePointGroups.length} group histograms.`); - const changePointGroupsChunks = chunk(changePointGroups, CHUNK_SIZE); - - for (const changePointGroupsChunk of changePointGroupsChunks) { + const groupHistogramQueue = queue(async function (cpg: ChangePointGroup) { if (shouldStop) { logDebugMessage('shouldStop abort fetching group histograms.'); + groupHistogramQueue.kill(); end(); return; } - await asyncForEach(changePointGroupsChunk, async (cpg) => { - if (overallTimeSeries !== undefined) { - const histogramQuery = getHistogramQuery( - request.body, - cpg.group.map((d) => ({ - term: { [d.fieldName]: d.fieldValue }, - })) - ); + if (overallTimeSeries !== undefined) { + const histogramQuery = getHistogramQuery( + request.body, + cpg.group.map((d) => ({ + term: { [d.fieldName]: d.fieldValue }, + })) + ); - let cpgTimeSeries: NumericChartData; - try { - cpgTimeSeries = ( - (await fetchHistogramsForFields( - client, - request.body.index, - histogramQuery, - // fields - [ - { - fieldName: request.body.timeFieldName, - type: KBN_FIELD_TYPES.DATE, - interval: overallTimeSeries.interval, - min: overallTimeSeries.stats[0], - max: overallTimeSeries.stats[1], - }, - ], - // samplerShardSize - -1, - undefined, - abortSignal - )) as [NumericChartData] - )[0]; - } catch (e) { - if (!isRequestAbortedError(e)) { - logger.error( - `Failed to fetch the histogram data for group #${ - cpg.id - }, got: \n${e.toString()}` - ); - pushError(`Failed to fetch the histogram data for group #${cpg.id}.`); - } - return; + let cpgTimeSeries: NumericChartData; + try { + cpgTimeSeries = ( + (await fetchHistogramsForFields( + client, + request.body.index, + histogramQuery, + // fields + [ + { + fieldName: request.body.timeFieldName, + type: KBN_FIELD_TYPES.DATE, + interval: overallTimeSeries.interval, + min: overallTimeSeries.stats[0], + max: overallTimeSeries.stats[1], + }, + ], + // samplerShardSize + -1, + undefined, + abortSignal + )) as [NumericChartData] + )[0]; + } catch (e) { + if (!isRequestAbortedError(e)) { + logger.error( + `Failed to fetch the histogram data for group #${ + cpg.id + }, got: \n${e.toString()}` + ); + pushError(`Failed to fetch the histogram data for group #${cpg.id}.`); } - const histogram = - overallTimeSeries.data.map((o, i) => { - const current = cpgTimeSeries.data.find( - (d1) => d1.key_as_string === o.key_as_string - ) ?? { - doc_count: 0, - }; - return { - key: o.key, - key_as_string: o.key_as_string ?? '', - doc_count_change_point: current.doc_count, - doc_count_overall: Math.max(0, o.doc_count - current.doc_count), - }; - }) ?? []; - - push( - addChangePointsGroupHistogramAction([ - { - id: cpg.id, - histogram, - }, - ]) - ); + return; } - }); - } + const histogram = + overallTimeSeries.data.map((o, i) => { + const current = cpgTimeSeries.data.find( + (d1) => d1.key_as_string === o.key_as_string + ) ?? { + doc_count: 0, + }; + return { + key: o.key, + key_as_string: o.key_as_string ?? '', + doc_count_change_point: current.doc_count, + doc_count_overall: Math.max(0, o.doc_count - current.doc_count), + }; + }) ?? []; + + push( + addChangePointsGroupHistogramAction([ + { + id: cpg.id, + histogram, + }, + ]) + ); + } + }, MAX_CONCURRENT_QUERIES); + + groupHistogramQueue.push(changePointGroups); + await groupHistogramQueue.drain(); } } catch (e) { if (!isRequestAbortedError(e)) { @@ -667,90 +668,90 @@ export const defineExplainLogRateSpikesRoute = ( // time series filtered by fields if (changePoints.length > 0 && overallTimeSeries !== undefined) { - const changePointsChunks = chunk(changePoints, CHUNK_SIZE); - - for (const changePointsChunk of changePointsChunks) { + const fieldValueHistogramQueue = queue(async function (cp: ChangePoint) { if (shouldStop) { logDebugMessage('shouldStop abort fetching field/value histograms.'); + fieldValueHistogramQueue.kill(); end(); return; } - await asyncForEach(changePointsChunk, async (cp) => { - if (overallTimeSeries !== undefined) { - const histogramQuery = getHistogramQuery(request.body, [ + if (overallTimeSeries !== undefined) { + const histogramQuery = getHistogramQuery(request.body, [ + { + term: { [cp.fieldName]: cp.fieldValue }, + }, + ]); + + let cpTimeSeries: NumericChartData; + + try { + cpTimeSeries = ( + (await fetchHistogramsForFields( + client, + request.body.index, + histogramQuery, + // fields + [ + { + fieldName: request.body.timeFieldName, + type: KBN_FIELD_TYPES.DATE, + interval: overallTimeSeries.interval, + min: overallTimeSeries.stats[0], + max: overallTimeSeries.stats[1], + }, + ], + // samplerShardSize + -1, + undefined, + abortSignal + )) as [NumericChartData] + )[0]; + } catch (e) { + logger.error( + `Failed to fetch the histogram data for field/value pair "${cp.fieldName}:${ + cp.fieldValue + }", got: \n${e.toString()}` + ); + pushError( + `Failed to fetch the histogram data for field/value pair "${cp.fieldName}:${cp.fieldValue}".` + ); + return; + } + + const histogram = + overallTimeSeries.data.map((o, i) => { + const current = cpTimeSeries.data.find( + (d1) => d1.key_as_string === o.key_as_string + ) ?? { + doc_count: 0, + }; + return { + key: o.key, + key_as_string: o.key_as_string ?? '', + doc_count_change_point: current.doc_count, + doc_count_overall: Math.max(0, o.doc_count - current.doc_count), + }; + }) ?? []; + + const { fieldName, fieldValue } = cp; + + loaded += (1 / changePoints.length) * PROGRESS_STEP_HISTOGRAMS; + pushHistogramDataLoadingState(); + push( + addChangePointsHistogramAction([ { - term: { [cp.fieldName]: cp.fieldValue }, + fieldName, + fieldValue, + histogram, }, - ]); - - let cpTimeSeries: NumericChartData; - - try { - cpTimeSeries = ( - (await fetchHistogramsForFields( - client, - request.body.index, - histogramQuery, - // fields - [ - { - fieldName: request.body.timeFieldName, - type: KBN_FIELD_TYPES.DATE, - interval: overallTimeSeries.interval, - min: overallTimeSeries.stats[0], - max: overallTimeSeries.stats[1], - }, - ], - // samplerShardSize - -1, - undefined, - abortSignal - )) as [NumericChartData] - )[0]; - } catch (e) { - logger.error( - `Failed to fetch the histogram data for field/value pair "${cp.fieldName}:${ - cp.fieldValue - }", got: \n${e.toString()}` - ); - pushError( - `Failed to fetch the histogram data for field/value pair "${cp.fieldName}:${cp.fieldValue}".` - ); - return; - } + ]) + ); + } + }, MAX_CONCURRENT_QUERIES); - const histogram = - overallTimeSeries.data.map((o, i) => { - const current = cpTimeSeries.data.find( - (d1) => d1.key_as_string === o.key_as_string - ) ?? { - doc_count: 0, - }; - return { - key: o.key, - key_as_string: o.key_as_string ?? '', - doc_count_change_point: current.doc_count, - doc_count_overall: Math.max(0, o.doc_count - current.doc_count), - }; - }) ?? []; - - const { fieldName, fieldValue } = cp; - - loaded += (1 / changePoints.length) * PROGRESS_STEP_HISTOGRAMS; - pushHistogramDataLoadingState(); - push( - addChangePointsHistogramAction([ - { - fieldName, - fieldValue, - histogram, - }, - ]) - ); - } - }); - } + fieldValueHistogramQueue.push(changePoints); + await fieldValueHistogramQueue.drain(); } endWithUpdatedLoadingState(); diff --git a/x-pack/test/api_integration/apis/aiops/explain_log_rate_spikes.ts b/x-pack/test/api_integration/apis/aiops/explain_log_rate_spikes.ts index 58fe4a3c67fd3..79c5be4a93a34 100644 --- a/x-pack/test/api_integration/apis/aiops/explain_log_rate_spikes.ts +++ b/x-pack/test/api_integration/apis/aiops/explain_log_rate_spikes.ts @@ -34,8 +34,8 @@ export default ({ getService }: FtrProviderContext) => { }; const expected = { - chunksLength: 13, - actionsLength: 12, + chunksLength: 34, + actionsLength: 33, noIndexChunksLength: 4, noIndexActionsLength: 3, changePointFilter: 'add_change_points', diff --git a/yarn.lock b/yarn.lock index ca156c451e3c2..cbed8a4c3432c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6140,6 +6140,11 @@ resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.0.tgz#14264692a9d6e2fa4db3df5e56e94b5e25647ac0" integrity sha512-iIgQNzCm0v7QMhhe4Jjn9uRh+I6GoPmt03CbEtwx3ao8/EfoQcmgtqH4vQ5Db/lxiIGaWDv6nwvunuh0RyX0+A== +"@types/async@^3.2.3": + version "3.2.15" + resolved "https://registry.yarnpkg.com/@types/async/-/async-3.2.15.tgz#26d4768fdda0e466f18d6c9918ca28cc89a4e1fe" + integrity sha512-PAmPfzvFA31mRoqZyTVsgJMsvbynR429UTTxhmfsUCrWGh3/fxOrzqBtaTPJsn4UtzTv4Vb0+/O7CARWb69N4g== + "@types/babel__core@*", "@types/babel__core@^7.1.14", "@types/babel__core@^7.1.19": version "7.1.19" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.19.tgz#7b497495b7d1b4812bdb9d02804d0576f43ee460" From 0a72c678386a9cab554575a10ddebe6fd08acda2 Mon Sep 17 00:00:00 2001 From: Michael Dokolin Date: Fri, 4 Nov 2022 16:46:32 +0100 Subject: [PATCH 26/31] [Embeddable] Add unified error UI (#143367) * Refactor embeddable error handler * Remove embeddable error handler from the visualization embeddable * Update Lens embeddable to handle errors correctly --- .../embeddables/embeddable_error_handler.tsx | 57 ++++++++++++++ .../lib/embeddables/embeddable_root.tsx | 7 +- .../lib/embeddables/error_embeddable.tsx | 21 +---- .../public/lib/embeddables/index.ts | 1 + .../public/lib/panel/_embeddable_panel.scss | 18 ++--- .../public/lib/panel/embeddable_panel.tsx | 41 +++++++--- .../lib/panel/embeddable_panel_error.tsx | 76 ++++++++----------- ...isualization_missed_saved_object_error.tsx | 35 +-------- .../embeddable/visualize_embeddable.tsx | 27 +++++-- .../visualize_embeddable_factory.tsx | 2 +- .../group6/dashboard_error_handling.ts | 9 ++- .../lens/public/embeddable/embeddable.tsx | 24 +++++- .../public/embeddable/embeddable_factory.ts | 2 +- .../public/embeddable/expression_wrapper.tsx | 8 +- .../translations/translations/fr-FR.json | 5 +- .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 3 +- 17 files changed, 196 insertions(+), 141 deletions(-) create mode 100644 src/plugins/embeddable/public/lib/embeddables/embeddable_error_handler.tsx diff --git a/src/plugins/embeddable/public/lib/embeddables/embeddable_error_handler.tsx b/src/plugins/embeddable/public/lib/embeddables/embeddable_error_handler.tsx new file mode 100644 index 0000000000000..a0ebfdbcbdc86 --- /dev/null +++ b/src/plugins/embeddable/public/lib/embeddables/embeddable_error_handler.tsx @@ -0,0 +1,57 @@ +/* + * 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 { isFunction } from 'lodash'; +import React, { ReactNode, useEffect, useRef, useState } from 'react'; +import { isPromise } from '@kbn/std'; +import type { MaybePromise } from '@kbn/utility-types'; +import type { ErrorLike } from '@kbn/expressions-plugin/common'; +import type { EmbeddableInput, EmbeddableOutput, IEmbeddable } from './i_embeddable'; + +type IReactEmbeddable = IEmbeddable>; + +interface EmbeddableErrorHandlerProps { + children: IReactEmbeddable['catchError']; + embeddable?: IReactEmbeddable; + error: ErrorLike | string; +} + +export function EmbeddableErrorHandler({ + children, + embeddable, + error, +}: EmbeddableErrorHandlerProps) { + const [node, setNode] = useState(); + const ref = useRef(null); + + useEffect(() => { + if (!ref.current) { + return; + } + + const handler = embeddable?.catchError?.bind(embeddable) ?? children; + if (!handler) { + return; + } + + const renderedNode = handler( + typeof error === 'string' ? { message: error, name: '' } : error, + ref.current + ); + if (isFunction(renderedNode)) { + return renderedNode; + } + if (isPromise(renderedNode)) { + renderedNode.then(setNode); + } else { + setNode(renderedNode); + } + }, [children, embeddable, error]); + + return
{node}
; +} diff --git a/src/plugins/embeddable/public/lib/embeddables/embeddable_root.tsx b/src/plugins/embeddable/public/lib/embeddables/embeddable_root.tsx index bfaefe09b5e6b..f94bb99ada83c 100644 --- a/src/plugins/embeddable/public/lib/embeddables/embeddable_root.tsx +++ b/src/plugins/embeddable/public/lib/embeddables/embeddable_root.tsx @@ -12,6 +12,7 @@ import { EuiText } from '@elastic/eui'; import { isPromise } from '@kbn/std'; import { MaybePromise } from '@kbn/utility-types'; import { EmbeddableInput, EmbeddableOutput, IEmbeddable } from './i_embeddable'; +import { EmbeddableErrorHandler } from './embeddable_error_handler'; interface Props { embeddable?: IEmbeddable>; @@ -91,7 +92,11 @@ export class EmbeddableRoot extends React.Component {
{this.state.node}
{this.props.loading && } - {this.props.error && {this.props.error}} + {this.props.error && ( + + {({ message }) => {message}} + + )}
); } diff --git a/src/plugins/embeddable/public/lib/embeddables/error_embeddable.tsx b/src/plugins/embeddable/public/lib/embeddables/error_embeddable.tsx index 8dff4ecee8976..1ccaf61064a8a 100644 --- a/src/plugins/embeddable/public/lib/embeddables/error_embeddable.tsx +++ b/src/plugins/embeddable/public/lib/embeddables/error_embeddable.tsx @@ -6,9 +6,8 @@ * Side Public License, v 1. */ -import { EuiEmptyPrompt } from '@elastic/eui'; import React, { ReactNode } from 'react'; -import { Markdown } from '@kbn/kibana-react-plugin/public'; +import { EmbeddablePanelError } from '../panel/embeddable_panel_error'; import { Embeddable } from './embeddable'; import { EmbeddableInput, EmbeddableOutput, IEmbeddable } from './i_embeddable'; import { IContainer } from '../containers'; @@ -33,20 +32,8 @@ export class ErrorEmbeddable extends Embeddable - ); - - return ( -
- -
- ); + const error = typeof this.error === 'string' ? { message: this.error, name: '' } : this.error; + + return ; } } diff --git a/src/plugins/embeddable/public/lib/embeddables/index.ts b/src/plugins/embeddable/public/lib/embeddables/index.ts index 0c1048af9182c..9f88e6b3053b5 100644 --- a/src/plugins/embeddable/public/lib/embeddables/index.ts +++ b/src/plugins/embeddable/public/lib/embeddables/index.ts @@ -9,6 +9,7 @@ export type { EmbeddableOutput, EmbeddableInput, IEmbeddable } from './i_embeddable'; export { isEmbeddable } from './is_embeddable'; export { Embeddable } from './embeddable'; +export { EmbeddableErrorHandler } from './embeddable_error_handler'; export * from './embeddable_factory'; export * from './embeddable_factory_definition'; export * from './default_embeddable_factory_provider'; diff --git a/src/plugins/embeddable/public/lib/panel/_embeddable_panel.scss b/src/plugins/embeddable/public/lib/panel/_embeddable_panel.scss index 3044a3896fa35..789b9f7227a3c 100644 --- a/src/plugins/embeddable/public/lib/panel/_embeddable_panel.scss +++ b/src/plugins/embeddable/public/lib/panel/_embeddable_panel.scss @@ -29,13 +29,6 @@ .embPanel__content--fullWidth { width: 100%; } - - .embPanel__content--error { - &:hover { - box-shadow: none; - transform: none; - } - } } // HEADER @@ -165,11 +158,12 @@ } .embPanel__error { - text-align: center; - justify-content: center; - flex-direction: column; - overflow: auto; - padding: $euiSizeS; + padding: $euiSizeL; + + & > * { + max-height: 100%; + overflow: auto; + } } .embPanel__label { diff --git a/src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx b/src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx index f5b072a591225..cf014c2af98b6 100644 --- a/src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx +++ b/src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx @@ -6,7 +6,13 @@ * Side Public License, v 1. */ -import { EuiContextMenuPanelDescriptor, EuiPanel, htmlIdGenerator } from '@elastic/eui'; +import { + EuiContextMenuPanelDescriptor, + EuiFlexGroup, + EuiFlexItem, + EuiPanel, + htmlIdGenerator, +} from '@elastic/eui'; import classNames from 'classnames'; import React, { ReactNode } from 'react'; import { Subscription } from 'rxjs'; @@ -27,11 +33,11 @@ import { contextMenuTrigger, } from '../triggers'; import { - IEmbeddable, - EmbeddableOutput, - EmbeddableError, + EmbeddableErrorHandler, EmbeddableInput, -} from '../embeddables/i_embeddable'; + EmbeddableOutput, + IEmbeddable, +} from '../embeddables'; import { ViewMode } from '../types'; import { EmbeddablePanelError } from './embeddable_panel_error'; @@ -105,7 +111,7 @@ interface State { badges: Array>; notifications: Array>; loading?: boolean; - error?: EmbeddableError; + error?: Error; destroyError?(): void; node?: ReactNode; } @@ -301,11 +307,24 @@ export class EmbeddablePanel extends React.Component { /> )} {this.state.error && ( - + + + + {(error) => ( + + )} + + + )}
{this.state.node} diff --git a/src/plugins/embeddable/public/lib/panel/embeddable_panel_error.tsx b/src/plugins/embeddable/public/lib/panel/embeddable_panel_error.tsx index 69af8e7220e62..4aba5ed105154 100644 --- a/src/plugins/embeddable/public/lib/panel/embeddable_panel_error.tsx +++ b/src/plugins/embeddable/public/lib/panel/embeddable_panel_error.tsx @@ -6,16 +6,15 @@ * Side Public License, v 1. */ -import { isFunction } from 'lodash'; -import React, { ReactNode, useEffect, useMemo, useRef, useState } from 'react'; -import { EuiPanel } from '@elastic/eui'; +import React, { ReactNode, useEffect, useMemo, useState } from 'react'; +import { EuiButtonEmpty, EuiEmptyPrompt, EuiText } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { isPromise } from '@kbn/std'; +import { Markdown } from '@kbn/kibana-react-plugin/public'; import type { MaybePromise } from '@kbn/utility-types'; import { ErrorLike } from '@kbn/expressions-plugin/common'; import { distinctUntilChanged, merge, of, switchMap } from 'rxjs'; import { EditPanelAction } from '../actions'; -import { EmbeddableInput, EmbeddableOutput, ErrorEmbeddable, IEmbeddable } from '../embeddables'; +import { EmbeddableInput, EmbeddableOutput, IEmbeddable } from '../embeddables'; interface EmbeddablePanelErrorProps { editPanelAction?: EditPanelAction; @@ -29,27 +28,25 @@ export function EmbeddablePanelError({ error, }: EmbeddablePanelErrorProps) { const [isEditable, setEditable] = useState(false); - const [node, setNode] = useState(); - const ref = useRef(null); const handleErrorClick = useMemo( () => (isEditable ? () => editPanelAction?.execute({ embeddable }) : undefined), [editPanelAction, embeddable, isEditable] ); - const title = embeddable.getTitle(); - const actionDisplayName = useMemo( + const label = useMemo( () => editPanelAction?.getDisplayName({ embeddable }), [editPanelAction, embeddable] ); + const title = useMemo(() => embeddable.getTitle(), [embeddable]); const ariaLabel = useMemo( () => !title - ? actionDisplayName + ? label : i18n.translate('embeddableApi.panel.editPanel.displayName', { defaultMessage: 'Edit {value}', values: { value: title }, }), - [title, actionDisplayName] + [label, title] ); useEffect(() => { @@ -62,42 +59,29 @@ export function EmbeddablePanelError({ return () => subscription.unsubscribe(); }, [editPanelAction, embeddable]); - useEffect(() => { - if (!ref.current) { - return; - } - - if (!embeddable.catchError) { - const errorEmbeddable = new ErrorEmbeddable(error, { id: embeddable.id }); - setNode(errorEmbeddable.render()); - - return () => errorEmbeddable.destroy(); - } - - const renderedNode = embeddable.catchError(error, ref.current); - if (isFunction(renderedNode)) { - return renderedNode; - } - if (isPromise(renderedNode)) { - renderedNode.then(setNode); - } else { - setNode(renderedNode); - } - }, [embeddable, error]); return ( - - {node} - + + + + } + data-test-subj="embeddableStackError" + iconType="alert" + iconColor="danger" + layout="vertical" + actions={ + isEditable && ( + + {label} + + ) + } + /> ); } diff --git a/src/plugins/visualizations/public/components/visualization_missed_saved_object_error.tsx b/src/plugins/visualizations/public/components/visualization_missed_saved_object_error.tsx index 767a2d38f8581..338a8f6fe7201 100644 --- a/src/plugins/visualizations/public/components/visualization_missed_saved_object_error.tsx +++ b/src/plugins/visualizations/public/components/visualization_missed_saved_object_error.tsx @@ -12,28 +12,25 @@ import React from 'react'; import { RedirectAppLinks } from '@kbn/shared-ux-link-redirect-app'; import type { ApplicationStart } from '@kbn/core/public'; import { DATA_VIEW_SAVED_OBJECT_TYPE } from '@kbn/data-plugin/common'; -import type { ViewMode } from '@kbn/embeddable-plugin/common'; import type { RenderMode } from '@kbn/expressions-plugin/common'; interface VisualizationMissedSavedObjectErrorProps { savedObjectMeta: { savedObjectType: typeof DATA_VIEW_SAVED_OBJECT_TYPE | 'search'; - savedObjectId?: string; }; application: ApplicationStart; - viewMode: ViewMode; + message: string; renderMode: RenderMode; } export const VisualizationMissedSavedObjectError = ({ savedObjectMeta, application, - viewMode, + message, renderMode, }: VisualizationMissedSavedObjectErrorProps) => { const { management: isManagementEnabled } = application.capabilities.navLinks; const isIndexPatternManagementEnabled = application.capabilities.management.kibana.indexPatterns; - const isEditVisEnabled = application.capabilities.visualize?.save; return ( ) : null } - body={ - <> -

- {i18n.translate('visualizations.missedDataView.errorMessage', { - defaultMessage: `Could not find the {type}: {id}`, - values: { - id: savedObjectMeta.savedObjectId ?? '-', - type: - savedObjectMeta.savedObjectType === 'search' - ? i18n.translate('visualizations.noSearch.label', { - defaultMessage: 'search', - }) - : i18n.translate('visualizations.noDataView.label', { - defaultMessage: 'data view', - }), - }, - })} -

- {viewMode === 'edit' && renderMode !== 'edit' && isEditVisEnabled ? ( -

- {i18n.translate('visualizations.missedDataView.editInVisualizeEditor', { - defaultMessage: `Edit in Visualize editor to fix the error`, - })} -

- ) : null} - - } + body={

{message}

} /> ); }; diff --git a/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx b/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx index f2a2a7f8ae000..663d015c429de 100644 --- a/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx +++ b/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx @@ -29,7 +29,6 @@ import { IContainer, ReferenceOrValueEmbeddable, SavedObjectEmbeddableInput, - ViewMode, } from '@kbn/embeddable-plugin/public'; import { ExpressionAstExpression, @@ -401,6 +400,25 @@ export class VisualizeEmbeddable this.abortController.abort(); } this.renderComplete.dispatchError(); + + if (isFallbackDataView(this.vis.data.indexPattern)) { + error = new Error( + i18n.translate('visualizations.missedDataView.errorMessage', { + defaultMessage: `Could not find the {type}: {id}`, + values: { + id: this.vis.data.indexPattern.id ?? '-', + type: this.vis.data.savedSearchId + ? i18n.translate('visualizations.noSearch.label', { + defaultMessage: 'search', + }) + : i18n.translate('visualizations.noDataView.label', { + defaultMessage: 'data view', + }), + }, + }) + ); + } + this.updateOutput({ ...this.getOutput(), rendered: true, @@ -503,7 +521,7 @@ export class VisualizeEmbeddable const { error } = this.getOutput(); if (error) { - render(this.catchError(error), this.domNode); + render(this.renderError(error), this.domNode); } }) ); @@ -511,17 +529,16 @@ export class VisualizeEmbeddable await this.updateHandler(); } - public catchError(error: ErrorLike | string) { + private renderError(error: ErrorLike | string) { if (isFallbackDataView(this.vis.data.indexPattern)) { return ( ); } diff --git a/src/plugins/visualizations/public/embeddable/visualize_embeddable_factory.tsx b/src/plugins/visualizations/public/embeddable/visualize_embeddable_factory.tsx index 4dcaa582511c3..93b19953b9b91 100644 --- a/src/plugins/visualizations/public/embeddable/visualize_embeddable_factory.tsx +++ b/src/plugins/visualizations/public/embeddable/visualize_embeddable_factory.tsx @@ -134,7 +134,7 @@ export class VisualizeEmbeddableFactory public getDisplayName() { return i18n.translate('visualizations.displayName', { - defaultMessage: 'Visualization', + defaultMessage: 'visualization', }); } diff --git a/test/functional/apps/dashboard/group6/dashboard_error_handling.ts b/test/functional/apps/dashboard/group6/dashboard_error_handling.ts index 7e1956b82daf2..b00aec24809cc 100644 --- a/test/functional/apps/dashboard/group6/dashboard_error_handling.ts +++ b/test/functional/apps/dashboard/group6/dashboard_error_handling.ts @@ -51,14 +51,15 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { // wrapping into own describe to make sure new tab is cleaned up even if test failed // see: https://github.com/elastic/kibana/pull/67280#discussion_r430528122 - describe('recreate index pattern link works', () => { - it('recreate index pattern link works', async () => { + describe('when the saved object is missing', () => { + it('shows the missing data view error message', async () => { await PageObjects.dashboard.gotoDashboardLandingPage(); await PageObjects.dashboard.loadSavedDashboard('dashboard with missing index pattern'); await PageObjects.header.waitUntilLoadingHasFinished(); - const errorEmbeddable = await testSubjects.find('visualization-missed-data-view-error'); + const embeddableError = await testSubjects.find('embeddableError'); + const errorMessage = await embeddableError.getVisibleText(); - expect(await errorEmbeddable.isDisplayed()).to.be(true); + expect(errorMessage).to.contain('Could not find the data view'); }); }); }); diff --git a/x-pack/plugins/lens/public/embeddable/embeddable.tsx b/x-pack/plugins/lens/public/embeddable/embeddable.tsx index 65c91b115ce70..aa5c5bba4741c 100644 --- a/x-pack/plugins/lens/public/embeddable/embeddable.tsx +++ b/x-pack/plugins/lens/public/embeddable/embeddable.tsx @@ -645,6 +645,25 @@ export class Embeddable } } + private getError(): Error | undefined { + const message = + typeof this.errors?.[0]?.longMessage === 'string' + ? this.errors[0].longMessage + : this.errors?.[0]?.shortMessage; + + if (message != null) { + return new Error(message); + } + + if (!this.expression) { + return new Error( + i18n.translate('xpack.lens.embeddable.failure', { + defaultMessage: "Visualization couldn't be displayed", + }) + ); + } + } + /** * * @param {HTMLElement} domNode @@ -665,7 +684,7 @@ export class Embeddable this.updateOutput({ ...this.getOutput(), loading: true, - error: undefined, + error: this.getError(), }); this.renderComplete.dispatchInProgress(); @@ -697,7 +716,8 @@ export class Embeddable style={input.style} executionContext={this.getExecutionContext()} canEdit={this.getIsEditable() && input.viewMode === 'edit'} - onRuntimeError={() => { + onRuntimeError={(message) => { + this.updateOutput({ error: new Error(message) }); this.logError('runtime'); }} noPadding={this.visDisplayOptions?.noPadding} diff --git a/x-pack/plugins/lens/public/embeddable/embeddable_factory.ts b/x-pack/plugins/lens/public/embeddable/embeddable_factory.ts index cef9e7d698faa..7904ba4c38f14 100644 --- a/x-pack/plugins/lens/public/embeddable/embeddable_factory.ts +++ b/x-pack/plugins/lens/public/embeddable/embeddable_factory.ts @@ -79,7 +79,7 @@ export class EmbeddableFactory implements EmbeddableFactoryDefinition { getDisplayName() { return i18n.translate('xpack.lens.embeddableDisplayName', { - defaultMessage: 'lens', + defaultMessage: 'Lens', }); } diff --git a/x-pack/plugins/lens/public/embeddable/expression_wrapper.tsx b/x-pack/plugins/lens/public/embeddable/expression_wrapper.tsx index 3f10fba310b0c..cbb1fedf75497 100644 --- a/x-pack/plugins/lens/public/embeddable/expression_wrapper.tsx +++ b/x-pack/plugins/lens/public/embeddable/expression_wrapper.tsx @@ -44,7 +44,7 @@ export interface ExpressionWrapperProps { style?: React.CSSProperties; className?: string; canEdit: boolean; - onRuntimeError: () => void; + onRuntimeError: (message?: string) => void; executionContext?: KibanaExecutionContext; lensInspector: LensInspector; noPadding?: boolean; @@ -148,7 +148,9 @@ export function ExpressionWrapper({ syncCursor={syncCursor} executionContext={executionContext} renderError={(errorMessage, error) => { - onRuntimeError(); + const messages = getOriginalRequestErrorMessages(error); + onRuntimeError(messages[0] ?? errorMessage); + return (
@@ -156,7 +158,7 @@ export function ExpressionWrapper({ - {(getOriginalRequestErrorMessages(error) || [errorMessage]).map((message) => ( + {messages.map((message) => ( {message} ))} diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 9e334bb8ec7f8..0a57b7c651d19 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -6140,7 +6140,7 @@ "visualizations.deprecatedTag": "Déclassé", "visualizations.disabledLabVisualizationLink": "Lire la documentation", "visualizations.disabledLabVisualizationMessage": "Veuillez activer le mode lab dans les paramètres avancés pour consulter les visualisations lab.", - "visualizations.displayName": "Visualisation", + "visualizations.displayName": "visualisation", "visualizations.editor.createBreadcrumb": "Créer", "visualizations.editor.defaultEditBreadcrumbText": "Modifier la visualisation", "visualizations.embeddable.inspectorTitle": "Inspecteur", @@ -6175,7 +6175,6 @@ "visualizations.listing.table.typeColumnName": "Type", "visualizations.listingPageTitle": "Bibliothèque Visualize", "visualizations.missedDataView.dataViewReconfigure": "Recréez-la dans la page de gestion des vues de données.", - "visualizations.missedDataView.editInVisualizeEditor": "Effectuer des modifications dans l'éditeur Visualize pour corriger l'erreur", "visualizations.newChart.conditionalMessage.advancedSettingsLink": "Paramètres avancés.", "visualizations.newChart.libraryMode.new": "nouveau", "visualizations.newChart.libraryMode.old": "âge", @@ -17450,7 +17449,7 @@ "xpack.lens.embeddable.missingTimeRangeParam.longMessage": "La propriété timeRange est requise pour cette configuration.", "xpack.lens.embeddable.missingTimeRangeParam.shortMessage": "Propriété timeRange manquante", "xpack.lens.embeddable.moreErrors": "Effectuez des modifications dans l'éditeur Lens pour afficher plus d'erreurs", - "xpack.lens.embeddableDisplayName": "lens", + "xpack.lens.embeddableDisplayName": "Lens", "xpack.lens.endValue.nearest": "La plus proche", "xpack.lens.endValue.none": "Masquer", "xpack.lens.endValue.zero": "Zéro", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 3ed2387f36680..0b4d191d99bcf 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -6169,7 +6169,6 @@ "visualizations.listing.table.typeColumnName": "型", "visualizations.listingPageTitle": "Visualizeライブラリ", "visualizations.missedDataView.dataViewReconfigure": "データビュー管理ページで再作成", - "visualizations.missedDataView.editInVisualizeEditor": "Visualizeエディターで編集し、エラーを修正", "visualizations.newChart.conditionalMessage.advancedSettingsLink": "高度な設定", "visualizations.newChart.libraryMode.new": "新規", "visualizations.newChart.libraryMode.old": "古", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index e7194fc92904e..a44380c72b813 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -6176,7 +6176,6 @@ "visualizations.listing.table.typeColumnName": "类型", "visualizations.listingPageTitle": "Visualize 库", "visualizations.missedDataView.dataViewReconfigure": "在数据视图管理页面中重新创建", - "visualizations.missedDataView.editInVisualizeEditor": "在 Visualize 编辑器中编辑以修复该错误", "visualizations.newChart.conditionalMessage.advancedSettingsLink": "免费的 API 密钥。", "visualizations.newChart.libraryMode.new": "新", "visualizations.newChart.libraryMode.old": "以前", @@ -17458,7 +17457,7 @@ "xpack.lens.embeddable.missingTimeRangeParam.longMessage": "给定配置需要包含 timeRange 属性", "xpack.lens.embeddable.missingTimeRangeParam.shortMessage": "缺少 timeRange 属性", "xpack.lens.embeddable.moreErrors": "在 Lens 编辑器中编辑以查看更多错误", - "xpack.lens.embeddableDisplayName": "lens", + "xpack.lens.embeddableDisplayName": "Lens", "xpack.lens.endValue.nearest": "最近", "xpack.lens.endValue.none": "隐藏", "xpack.lens.endValue.zero": "零", From fd00a514e3b830eb10109506f187526e73565c91 Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Fri, 4 Nov 2022 16:08:59 +0000 Subject: [PATCH 27/31] [Fleet] Fix all test package data streams + validation script (#144569) * add ability to override data stream path * fix ingest_pipeline validation * fix all test package data streans * lint + refactor --- .../server/services/epm/archive/parse.test.ts | 44 ++++++---------- .../server/services/epm/archive/parse.ts | 50 ++++++++++--------- .../data_stream/test_stream/manifest.yml | 1 + .../data_stream/test_stream/manifest.yml | 1 + .../data_stream/test_stream/manifest.yml | 1 + .../data_stream/test_stream/manifest.yml | 8 +-- .../data_stream/test_stream/manifest.yml | 1 + .../data_stream/test_stream_new/manifest.yml | 1 + .../test_stream_new_2/manifest.yml | 1 + .../data_stream/test_stream_new/manifest.yml | 1 + .../test_stream_new_2/manifest.yml | 1 + .../data_stream/test_stream/manifest.yml | 1 + .../data_stream/test_stream/manifest.yml | 1 + .../0.1.0/data_stream/log/manifest.yml | 1 + 14 files changed, 53 insertions(+), 60 deletions(-) diff --git a/x-pack/plugins/fleet/server/services/epm/archive/parse.test.ts b/x-pack/plugins/fleet/server/services/epm/archive/parse.test.ts index 38a070e7eca8f..73e36575cddc2 100644 --- a/x-pack/plugins/fleet/server/services/epm/archive/parse.test.ts +++ b/x-pack/plugins/fleet/server/services/epm/archive/parse.test.ts @@ -8,47 +8,33 @@ import { parseDefaultIngestPipeline, parseDataStreamElasticsearchEntry } from '. describe('parseDefaultIngestPipeline', () => { it('Should return undefined for stream without any elasticsearch dir', () => { expect( - parseDefaultIngestPipeline({ - pkgKey: 'pkg-1.0.0', - paths: ['pkg-1.0.0/data_stream/stream1/manifest.yml'], - dataStreamPath: 'stream1', - }) + parseDefaultIngestPipeline('pkg-1.0.0/data_stream/stream1/', [ + 'pkg-1.0.0/data_stream/stream1/manifest.yml', + ]) ).toEqual(undefined); }); it('Should return undefined for stream with non default ingest pipeline', () => { expect( - parseDefaultIngestPipeline({ - pkgKey: 'pkg-1.0.0', - paths: [ - 'pkg-1.0.0/data_stream/stream1/manifest.yml', - 'pkg-1.0.0/data_stream/stream1/elasticsearch/ingest_pipeline/someotherpipeline.yml', - ], - dataStreamPath: 'stream1', - }) + parseDefaultIngestPipeline('pkg-1.0.0/data_stream/stream1/', [ + 'pkg-1.0.0/data_stream/stream1/manifest.yml', + 'pkg-1.0.0/data_stream/stream1/elasticsearch/ingest_pipeline/someotherpipeline.yml', + ]) ).toEqual(undefined); }); it('Should return default for yml ingest pipeline', () => { expect( - parseDefaultIngestPipeline({ - pkgKey: 'pkg-1.0.0', - paths: [ - 'pkg-1.0.0/data_stream/stream1/manifest.yml', - 'pkg-1.0.0/data_stream/stream1/elasticsearch/ingest_pipeline/default.yml', - ], - dataStreamPath: 'stream1', - }) + parseDefaultIngestPipeline('pkg-1.0.0/data_stream/stream1/', [ + 'pkg-1.0.0/data_stream/stream1/manifest.yml', + 'pkg-1.0.0/data_stream/stream1/elasticsearch/ingest_pipeline/default.yml', + ]) ).toEqual('default'); }); it('Should return default for json ingest pipeline', () => { expect( - parseDefaultIngestPipeline({ - pkgKey: 'pkg-1.0.0', - paths: [ - 'pkg-1.0.0/data_stream/stream1/manifest.yml', - 'pkg-1.0.0/data_stream/stream1/elasticsearch/ingest_pipeline/default.json', - ], - dataStreamPath: 'stream1', - }) + parseDefaultIngestPipeline('pkg-1.0.0/data_stream/stream1/', [ + 'pkg-1.0.0/data_stream/stream1/manifest.yml', + 'pkg-1.0.0/data_stream/stream1/elasticsearch/ingest_pipeline/default.json', + ]) ).toEqual('default'); }); }); diff --git a/x-pack/plugins/fleet/server/services/epm/archive/parse.ts b/x-pack/plugins/fleet/server/services/epm/archive/parse.ts index 06a92e84c0af6..e07e0cd7b477e 100644 --- a/x-pack/plugins/fleet/server/services/epm/archive/parse.ts +++ b/x-pack/plugins/fleet/server/services/epm/archive/parse.ts @@ -12,7 +12,7 @@ import path from 'path'; import { merge } from '@kbn/std'; import yaml from 'js-yaml'; -import { pick, uniq } from 'lodash'; +import { pick } from 'lodash'; import semverMajor from 'semver/functions/major'; import semverPrerelease from 'semver/functions/prerelease'; @@ -217,7 +217,13 @@ function parseAndVerifyArchive(paths: string[], topLevelDirOverride?: string): A ); } - const parsedDataStreams = parseAndVerifyDataStreams(paths, parsed.name, parsed.version); + const parsedDataStreams = parseAndVerifyDataStreams( + paths, + parsed.name, + parsed.version, + topLevelDirOverride + ); + if (parsedDataStreams.length) { parsed.data_streams = parsedDataStreams; } @@ -250,26 +256,27 @@ function parseAndVerifyReadme(paths: string[], pkgName: string, pkgVersion: stri export function parseAndVerifyDataStreams( paths: string[], pkgName: string, - pkgVersion: string + pkgVersion: string, + pkgBasePathOverride?: string ): RegistryDataStream[] { // A data stream is made up of a subdirectory of name-version/data_stream/, containing a manifest.yml - let dataStreamPaths: string[] = []; + const dataStreamPaths = new Set(); const dataStreams: RegistryDataStream[] = []; - const pkgKey = pkgToPkgKey({ name: pkgName, version: pkgVersion }); - - // pick all paths matching name-version/data_stream/DATASTREAM_PATH/... - // from those, pick all unique data stream paths - paths - .filter((filePath) => filePath.startsWith(`${pkgKey}/data_stream/`)) - .forEach((filePath) => { - const parts = filePath.split('/'); - if (parts.length > 2 && parts[2]) dataStreamPaths.push(parts[2]); - }); + const pkgBasePath = pkgBasePathOverride || pkgToPkgKey({ name: pkgName, version: pkgVersion }); + const dataStreamsBasePath = path.join(pkgBasePath, 'data_stream'); + // pick all paths matching name-version/data_stream/DATASTREAM_NAME/... + // from those, pick all unique data stream names + paths.forEach((filePath) => { + if (!filePath.startsWith(dataStreamsBasePath)) return; - dataStreamPaths = uniq(dataStreamPaths); + const streamWithoutPrefix = filePath.slice(dataStreamsBasePath.length); + const [dataStreamPath] = streamWithoutPrefix.split('/').filter((v) => v); // remove undefined incase of leading / + if (dataStreamPath) dataStreamPaths.add(dataStreamPath); + }); dataStreamPaths.forEach((dataStreamPath) => { - const manifestFile = `${pkgKey}/data_stream/${dataStreamPath}/${MANIFEST_NAME}`; + const fullDataStreamPath = path.join(dataStreamsBasePath, dataStreamPath); + const manifestFile = path.join(fullDataStreamPath, MANIFEST_NAME); const manifestBuffer = MANIFESTS[manifestFile]; if (!paths.includes(manifestFile) || !manifestBuffer) { throw new PackageInvalidArchiveError( @@ -302,7 +309,7 @@ export function parseAndVerifyDataStreams( ); } - const ingestPipeline = parseDefaultIngestPipeline({ pkgKey, dataStreamPath, paths }); + const ingestPipeline = parseDefaultIngestPipeline(fullDataStreamPath, paths); const streams = parseAndVerifyStreams(manifestStreams, dataStreamPath); const parsedElasticsearchEntry = parseDataStreamElasticsearchEntry( elasticsearch, @@ -541,13 +548,8 @@ const isDefaultPipelineFile = (pipelinePath: string) => pipelinePath.endsWith(DEFAULT_INGEST_PIPELINE_FILE_NAME_YML) || pipelinePath.endsWith(DEFAULT_INGEST_PIPELINE_FILE_NAME_JSON); -export function parseDefaultIngestPipeline(opts: { - pkgKey: string; - paths: string[]; - dataStreamPath: string; -}) { - const { pkgKey, paths, dataStreamPath } = opts; - const ingestPipelineDirPath = `${pkgKey}/data_stream/${dataStreamPath}/elasticsearch/ingest_pipeline`; +export function parseDefaultIngestPipeline(fullDataStreamPath: string, paths: string[]) { + const ingestPipelineDirPath = path.join(fullDataStreamPath, '/elasticsearch/ingest_pipeline'); const defaultIngestPipelinePaths = paths.filter( (pipelinePath) => pipelinePath.startsWith(ingestPipelineDirPath) && isDefaultPipelineFile(pipelinePath) diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.1.0/data_stream/test_stream/manifest.yml b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.1.0/data_stream/test_stream/manifest.yml index 461d4fa941708..476a62174f644 100644 --- a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.1.0/data_stream/test_stream/manifest.yml +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.1.0/data_stream/test_stream/manifest.yml @@ -2,3 +2,4 @@ title: Test stream type: logs streams: - input: test_input + title: test input diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.2.0-add-non-required-test-var/data_stream/test_stream/manifest.yml b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.2.0-add-non-required-test-var/data_stream/test_stream/manifest.yml index 3500fa8888ceb..5ad939f2c71be 100644 --- a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.2.0-add-non-required-test-var/data_stream/test_stream/manifest.yml +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.2.0-add-non-required-test-var/data_stream/test_stream/manifest.yml @@ -2,6 +2,7 @@ title: Test stream type: logs streams: - input: test_input + title: test input vars: - name: test_var type: text diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.2.5-non-breaking-change/data_stream/test_stream/manifest.yml b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.2.5-non-breaking-change/data_stream/test_stream/manifest.yml index 95b72f0122aec..7ef056ac73595 100644 --- a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.2.5-non-breaking-change/data_stream/test_stream/manifest.yml +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.2.5-non-breaking-change/data_stream/test_stream/manifest.yml @@ -2,6 +2,7 @@ title: Test stream type: logs streams: - input: test_input + title: test input vars: - name: test_var type: text diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.3.0-remove-test-var/data_stream/test_stream/manifest.yml b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.3.0-remove-test-var/data_stream/test_stream/manifest.yml index 47c2fe0f32d33..476a62174f644 100644 --- a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.3.0-remove-test-var/data_stream/test_stream/manifest.yml +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.3.0-remove-test-var/data_stream/test_stream/manifest.yml @@ -2,10 +2,4 @@ title: Test stream type: logs streams: - input: test_input - # vars: - # - name: test_var - # type: text - # title: Test Var - # required: true - # show_user: true - # default: Test Value + title: test input diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.4.0-add-test-var-as-bool/data_stream/test_stream/manifest.yml b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.4.0-add-test-var-as-bool/data_stream/test_stream/manifest.yml index f96486e1a1932..403a084a4e2d4 100644 --- a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.4.0-add-test-var-as-bool/data_stream/test_stream/manifest.yml +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.4.0-add-test-var-as-bool/data_stream/test_stream/manifest.yml @@ -2,6 +2,7 @@ title: Test stream type: logs streams: - input: test_input + title: test input vars: - name: test_var type: bool diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.5.0-restructure-inputs/data_stream/test_stream_new/manifest.yml b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.5.0-restructure-inputs/data_stream/test_stream_new/manifest.yml index 42b5d8641c6cd..ec4b71337738a 100644 --- a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.5.0-restructure-inputs/data_stream/test_stream_new/manifest.yml +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.5.0-restructure-inputs/data_stream/test_stream_new/manifest.yml @@ -2,6 +2,7 @@ title: Test stream type: logs streams: - input: test_input_new + title: test input new vars: - name: test_var_new type: text diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.5.0-restructure-inputs/data_stream/test_stream_new_2/manifest.yml b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.5.0-restructure-inputs/data_stream/test_stream_new_2/manifest.yml index af942e7b6413a..df9bfa4e58ac6 100644 --- a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.5.0-restructure-inputs/data_stream/test_stream_new_2/manifest.yml +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.5.0-restructure-inputs/data_stream/test_stream_new_2/manifest.yml @@ -2,6 +2,7 @@ title: Test stream type: logs streams: - input: test_input_new_2 + title: test input new 2 vars: - name: test_input_new_2_var_1 type: text diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.6.0-restructure-policy-templates/data_stream/test_stream_new/manifest.yml b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.6.0-restructure-policy-templates/data_stream/test_stream_new/manifest.yml index 42b5d8641c6cd..ec4b71337738a 100644 --- a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.6.0-restructure-policy-templates/data_stream/test_stream_new/manifest.yml +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.6.0-restructure-policy-templates/data_stream/test_stream_new/manifest.yml @@ -2,6 +2,7 @@ title: Test stream type: logs streams: - input: test_input_new + title: test input new vars: - name: test_var_new type: text diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.6.0-restructure-policy-templates/data_stream/test_stream_new_2/manifest.yml b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.6.0-restructure-policy-templates/data_stream/test_stream_new_2/manifest.yml index af942e7b6413a..df9bfa4e58ac6 100644 --- a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.6.0-restructure-policy-templates/data_stream/test_stream_new_2/manifest.yml +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.6.0-restructure-policy-templates/data_stream/test_stream_new_2/manifest.yml @@ -2,6 +2,7 @@ title: Test stream type: logs streams: - input: test_input_new_2 + title: test input new 2 vars: - name: test_input_new_2_var_1 type: text diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.7.0-add-stream-with-no-vars/data_stream/test_stream/manifest.yml b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.7.0-add-stream-with-no-vars/data_stream/test_stream/manifest.yml index 461d4fa941708..476a62174f644 100644 --- a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.7.0-add-stream-with-no-vars/data_stream/test_stream/manifest.yml +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.7.0-add-stream-with-no-vars/data_stream/test_stream/manifest.yml @@ -2,3 +2,4 @@ title: Test stream type: logs streams: - input: test_input + title: test input diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.8.0-add-vars-to-stream-with-no-vars/data_stream/test_stream/manifest.yml b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.8.0-add-vars-to-stream-with-no-vars/data_stream/test_stream/manifest.yml index 8b8ea1987ccc3..15b6496c50d76 100644 --- a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.8.0-add-vars-to-stream-with-no-vars/data_stream/test_stream/manifest.yml +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/package_policy_upgrade/0.8.0-add-vars-to-stream-with-no-vars/data_stream/test_stream/manifest.yml @@ -2,6 +2,7 @@ title: Test stream type: logs streams: - input: test_input + title: test input vars: - name: test_var_new type: text diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/with_required_variables/0.1.0/data_stream/log/manifest.yml b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/with_required_variables/0.1.0/data_stream/log/manifest.yml index 0b1ae9c6cb995..a4473a8b3fa2b 100644 --- a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/with_required_variables/0.1.0/data_stream/log/manifest.yml +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/with_required_variables/0.1.0/data_stream/log/manifest.yml @@ -2,6 +2,7 @@ title: Test stream type: logs streams: - input: test_input + title: test input vars: - name: test_var_required type: string From bf9c87c7c98854a689128ffa983e978837934d0f Mon Sep 17 00:00:00 2001 From: gchaps <33642766+gchaps@users.noreply.github.com> Date: Fri, 4 Nov 2022 09:41:24 -0700 Subject: [PATCH 28/31] [DOCS] Adds missing image to landing page (#144626) --- docs/index-custom-title-page.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index-custom-title-page.html b/docs/index-custom-title-page.html index 7935a110ac40a..f605cfce3dee9 100644 --- a/docs/index-custom-title-page.html +++ b/docs/index-custom-title-page.html @@ -102,7 +102,7 @@

- + Protect my environment

Learn how to defend against threats across your environment.

From 116aae0334921462ed01407b62e8adb9666d3cdd Mon Sep 17 00:00:00 2001 From: Nicolas Chaulet Date: Fri, 4 Nov 2022 12:49:44 -0400 Subject: [PATCH 29/31] [Fleet] Create cloud Fleet server host only if no default (#144617) --- .../plugins/fleet/common/openapi/bundled.json | 22 +++++- .../plugins/fleet/common/openapi/bundled.yaml | 14 ++++ .../components/schemas/agent_policy.yaml | 8 +++ .../components/schemas/new_agent_policy.yaml | 8 ++- .../fleet_server_host.test.ts | 72 +++++++++++++++++++ .../preconfiguration/fleet_server_host.ts | 50 +++++++++---- 6 files changed, 156 insertions(+), 18 deletions(-) diff --git a/x-pack/plugins/fleet/common/openapi/bundled.json b/x-pack/plugins/fleet/common/openapi/bundled.json index ab8747170f760..6254d333a66be 100644 --- a/x-pack/plugins/fleet/common/openapi/bundled.json +++ b/x-pack/plugins/fleet/common/openapi/bundled.json @@ -5072,6 +5072,14 @@ "monitoring_output_id": { "type": "string", "nullable": true + }, + "fleet_server_host_id": { + "type": "string", + "nullable": true + }, + "download_source_id": { + "type": "string", + "nullable": true } }, "required": [ @@ -5221,10 +5229,20 @@ "type": "string" }, "data_output_id": { - "type": "string" + "type": "string", + "nullable": true }, "monitoring_output_id": { - "type": "string" + "type": "string", + "nullable": true + }, + "fleet_server_host_id": { + "type": "string", + "nullable": true + }, + "download_source_id": { + "type": "string", + "nullable": true }, "revision": { "type": "number" diff --git a/x-pack/plugins/fleet/common/openapi/bundled.yaml b/x-pack/plugins/fleet/common/openapi/bundled.yaml index eca789024e4f3..0295ea7e44f03 100644 --- a/x-pack/plugins/fleet/common/openapi/bundled.yaml +++ b/x-pack/plugins/fleet/common/openapi/bundled.yaml @@ -3220,6 +3220,12 @@ components: monitoring_output_id: type: string nullable: true + fleet_server_host_id: + type: string + nullable: true + download_source_id: + type: string + nullable: true required: - name - namespace @@ -3322,8 +3328,16 @@ components: type: string data_output_id: type: string + nullable: true monitoring_output_id: type: string + nullable: true + fleet_server_host_id: + type: string + nullable: true + download_source_id: + type: string + nullable: true revision: type: number agents: diff --git a/x-pack/plugins/fleet/common/openapi/components/schemas/agent_policy.yaml b/x-pack/plugins/fleet/common/openapi/components/schemas/agent_policy.yaml index b3895ed2627f7..ab00144064760 100644 --- a/x-pack/plugins/fleet/common/openapi/components/schemas/agent_policy.yaml +++ b/x-pack/plugins/fleet/common/openapi/components/schemas/agent_policy.yaml @@ -21,8 +21,16 @@ allOf: type: string data_output_id: type: string + nullable: true monitoring_output_id: type: string + nullable: true + fleet_server_host_id: + type: string + nullable: true + download_source_id: + type: string + nullable: true revision: type: number agents: diff --git a/x-pack/plugins/fleet/common/openapi/components/schemas/new_agent_policy.yaml b/x-pack/plugins/fleet/common/openapi/components/schemas/new_agent_policy.yaml index 7ad8988f1b0e4..3485d235b7b69 100644 --- a/x-pack/plugins/fleet/common/openapi/components/schemas/new_agent_policy.yaml +++ b/x-pack/plugins/fleet/common/openapi/components/schemas/new_agent_policy.yaml @@ -22,6 +22,12 @@ properties: monitoring_output_id: type: string nullable: true + fleet_server_host_id: + type: string + nullable: true + download_source_id: + type: string + nullable: true required: - name - - namespace \ No newline at end of file + - namespace diff --git a/x-pack/plugins/fleet/server/services/preconfiguration/fleet_server_host.test.ts b/x-pack/plugins/fleet/server/services/preconfiguration/fleet_server_host.test.ts index 685f12f21cb4d..87717860e9be4 100644 --- a/x-pack/plugins/fleet/server/services/preconfiguration/fleet_server_host.test.ts +++ b/x-pack/plugins/fleet/server/services/preconfiguration/fleet_server_host.test.ts @@ -4,17 +4,27 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import { savedObjectsClientMock } from '@kbn/core/server/mocks'; import { appContextService } from '../app_context'; +import { getDefaultFleetServerHost, createFleetServerHost } from '../fleet_server_host'; import { + createCloudFleetServerHostIfNeeded, getCloudFleetServersHosts, getPreconfiguredFleetServerHostFromConfig, } from './fleet_server_host'; +jest.mock('../fleet_server_host'); jest.mock('../app_context'); const mockedAppContextService = appContextService as jest.Mocked; +const mockedGetDefaultFleetServerHost = getDefaultFleetServerHost as jest.MockedFunction< + typeof getDefaultFleetServerHost +>; +const mockedCreateFleetServerHost = createFleetServerHost as jest.MockedFunction< + typeof createFleetServerHost +>; describe('getPreconfiguredFleetServerHostFromConfig', () => { it('should work with preconfigured fleetServerHosts', () => { @@ -129,3 +139,65 @@ describe('getCloudFleetServersHosts', () => { `); }); }); + +describe('createCloudFleetServerHostIfNeeded', () => { + beforeEach(() => { + mockedCreateFleetServerHost.mockReset(); + }); + afterEach(() => { + mockedAppContextService.getCloud.mockReset(); + }); + it('should do nothing if there is no cloud fleet server hosts', async () => { + const soClient = savedObjectsClientMock.create(); + + await createCloudFleetServerHostIfNeeded(soClient); + + expect(mockedCreateFleetServerHost).not.toBeCalled(); + }); + + it('should do nothing if there is already an host configured', async () => { + const soClient = savedObjectsClientMock.create(); + mockedAppContextService.getCloud.mockReturnValue({ + cloudId: + 'dXMtZWFzdC0xLmF3cy5mb3VuZC5pbyRjZWM2ZjI2MWE3NGJmMjRjZTMzYmI4ODExYjg0Mjk0ZiRjNmMyY2E2ZDA0MjI0OWFmMGNjN2Q3YTllOTYyNTc0Mw==', + isCloudEnabled: true, + deploymentId: 'deployment-id-1', + apm: {}, + }); + mockedGetDefaultFleetServerHost.mockResolvedValue({ + id: 'test', + } as any); + + await createCloudFleetServerHostIfNeeded(soClient); + + expect(mockedCreateFleetServerHost).not.toBeCalled(); + }); + + it('should create a new fleet server hosts if there is no host configured', async () => { + const soClient = savedObjectsClientMock.create(); + mockedAppContextService.getCloud.mockReturnValue({ + cloudId: + 'dXMtZWFzdC0xLmF3cy5mb3VuZC5pbyRjZWM2ZjI2MWE3NGJmMjRjZTMzYmI4ODExYjg0Mjk0ZiRjNmMyY2E2ZDA0MjI0OWFmMGNjN2Q3YTllOTYyNTc0Mw==', + isCloudEnabled: true, + deploymentId: 'deployment-id-1', + apm: {}, + }); + mockedGetDefaultFleetServerHost.mockResolvedValue(null); + soClient.create.mockResolvedValue({ + id: 'test-id', + attributes: {}, + } as any); + + await createCloudFleetServerHostIfNeeded(soClient); + + expect(mockedCreateFleetServerHost).toBeCalledTimes(1); + expect(mockedCreateFleetServerHost).toBeCalledWith( + expect.anything(), + expect.objectContaining({ + host_urls: ['https://deployment-id-1.fleet.us-east-1.aws.found.io'], + is_default: true, + }), + { id: 'fleet-default-fleet-server-host', overwrite: true, fromPreconfiguration: true } + ); + }); +}); diff --git a/x-pack/plugins/fleet/server/services/preconfiguration/fleet_server_host.ts b/x-pack/plugins/fleet/server/services/preconfiguration/fleet_server_host.ts index c666bc0a343a5..15e2bf5d80a7b 100644 --- a/x-pack/plugins/fleet/server/services/preconfiguration/fleet_server_host.ts +++ b/x-pack/plugins/fleet/server/services/preconfiguration/fleet_server_host.ts @@ -20,7 +20,9 @@ import { deleteFleetServerHost, listFleetServerHosts, updateFleetServerHost, + getDefaultFleetServerHost, } from '../fleet_server_host'; +import { agentPolicyService } from '../agent_policy'; export function getCloudFleetServersHosts() { const cloudSetup = appContextService.getCloud(); @@ -44,20 +46,7 @@ export function getPreconfiguredFleetServerHostFromConfig(config?: FleetConfigTy const legacyFleetServerHostsConfig = getConfigFleetServerHosts(config); - // is cloud - const cloudServerHosts = getCloudFleetServersHosts(); - const fleetServerHosts: FleetServerHost[] = (fleetServerHostsFromConfig || []).concat([ - ...(cloudServerHosts - ? [ - { - name: 'Default', - is_default: true, - id: DEFAULT_FLEET_SERVER_HOST_ID, - host_urls: cloudServerHosts, - }, - ] - : []), ...(legacyFleetServerHostsConfig ? [ { @@ -82,12 +71,18 @@ export async function ensurePreconfiguredFleetServerHosts( esClient: ElasticsearchClient, preconfiguredFleetServerHosts: FleetServerHost[] ) { - await createOrUpdatePreconfiguredFleetServerHosts(soClient, preconfiguredFleetServerHosts); + await createOrUpdatePreconfiguredFleetServerHosts( + soClient, + esClient, + preconfiguredFleetServerHosts + ); + await createCloudFleetServerHostIfNeeded(soClient); await cleanPreconfiguredFleetServerHosts(soClient, esClient, preconfiguredFleetServerHosts); } export async function createOrUpdatePreconfiguredFleetServerHosts( soClient: SavedObjectsClientContract, + esClient: ElasticsearchClient, preconfiguredFleetServerHosts: FleetServerHost[] ) { const existingFleetServerHosts = await bulkGetFleetServerHosts( @@ -134,12 +129,37 @@ export async function createOrUpdatePreconfiguredFleetServerHosts( }, { fromPreconfiguration: true } ); - // TODO Bump revision of all policies using that output + if (data.is_default) { + await agentPolicyService.bumpAllAgentPolicies(soClient, esClient); + } else { + await agentPolicyService.bumpAllAgentPoliciesForFleetServerHosts(soClient, esClient, id); + } } }) ); } +export async function createCloudFleetServerHostIfNeeded(soClient: SavedObjectsClientContract) { + const cloudServerHosts = getCloudFleetServersHosts(); + if (!cloudServerHosts || cloudServerHosts.length === 0) { + return; + } + + const defaultFleetServerHost = await getDefaultFleetServerHost(soClient); + if (!defaultFleetServerHost) { + await createFleetServerHost( + soClient, + { + name: 'Default', + is_default: true, + host_urls: cloudServerHosts, + is_preconfigured: false, + }, + { id: DEFAULT_FLEET_SERVER_HOST_ID, overwrite: true, fromPreconfiguration: true } + ); + } +} + export async function cleanPreconfiguredFleetServerHosts( soClient: SavedObjectsClientContract, esClient: ElasticsearchClient, From 74f6554b519a6e37e1bd5dac3b86d99c5c501f1f Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Fri, 4 Nov 2022 17:08:26 +0000 Subject: [PATCH 30/31] bugfix: handle dotted values in elasticsearch privileges block (#144628) (cherry picked from commit 207bb468d355bcb7138b9dbec54d9a54281bb929) --- .../server/services/epm/archive/parse.test.ts | 28 ++++++++++++++++ .../server/services/epm/archive/parse.ts | 32 +++++++++---------- 2 files changed, 43 insertions(+), 17 deletions(-) diff --git a/x-pack/plugins/fleet/server/services/epm/archive/parse.test.ts b/x-pack/plugins/fleet/server/services/epm/archive/parse.test.ts index 73e36575cddc2..e4ee10c4e270c 100644 --- a/x-pack/plugins/fleet/server/services/epm/archive/parse.test.ts +++ b/x-pack/plugins/fleet/server/services/epm/archive/parse.test.ts @@ -108,4 +108,32 @@ describe('parseDataStreamElasticsearchEntry', () => { 'index_template.settings': { 'index.lifecycle.name': 'reference' }, }); }); + it('Should handle non-dotted values for privileges', () => { + expect( + parseDataStreamElasticsearchEntry({ + privileges: { + indices: ['read'], + cluster: ['test'], + }, + }) + ).toEqual({ + privileges: { + indices: ['read'], + cluster: ['test'], + }, + }); + }); + it('Should handle dotted values for privileges', () => { + expect( + parseDataStreamElasticsearchEntry({ + 'privileges.indices': ['read'], + 'privileges.cluster': ['test'], + }) + ).toEqual({ + privileges: { + indices: ['read'], + cluster: ['test'], + }, + }); + }); }); diff --git a/x-pack/plugins/fleet/server/services/epm/archive/parse.ts b/x-pack/plugins/fleet/server/services/epm/archive/parse.ts index e07e0cd7b477e..8bcda08fdec6b 100644 --- a/x-pack/plugins/fleet/server/services/epm/archive/parse.ts +++ b/x-pack/plugins/fleet/server/services/epm/archive/parse.ts @@ -62,13 +62,13 @@ const expandDottedField = (dottedFieldName: string, val: unknown): object => { } }; -export const expandDottedObject = (dottedObj: object) => { +export const expandDottedObject = (dottedObj: object = {}) => { if (typeof dottedObj !== 'object' || Array.isArray(dottedObj)) { return dottedObj; } return Object.entries(dottedObj).reduce( (acc, [key, val]) => merge(acc, expandDottedField(key, val)), - {} + {} as Record ); }; @@ -514,31 +514,29 @@ export function parseDataStreamElasticsearchEntry( ingestPipeline?: string ) { const parsedElasticsearchEntry: Record = {}; - + const expandedElasticsearch = expandDottedObject(elasticsearch); if (ingestPipeline) { parsedElasticsearchEntry['ingest_pipeline.name'] = ingestPipeline; } - if (elasticsearch?.privileges) { - parsedElasticsearchEntry.privileges = elasticsearch.privileges; + if (expandedElasticsearch?.privileges) { + parsedElasticsearchEntry.privileges = expandedElasticsearch.privileges; } - if (elasticsearch?.source_mode) { - parsedElasticsearchEntry.source_mode = elasticsearch.source_mode; + if (expandedElasticsearch?.source_mode) { + parsedElasticsearchEntry.source_mode = expandedElasticsearch.source_mode; } - const indexTemplateMappings = - elasticsearch?.index_template?.mappings || elasticsearch?.['index_template.mappings']; - if (indexTemplateMappings) { - parsedElasticsearchEntry['index_template.mappings'] = - expandDottedEntries(indexTemplateMappings); + if (expandedElasticsearch?.index_template?.mappings) { + parsedElasticsearchEntry['index_template.mappings'] = expandDottedEntries( + expandedElasticsearch.index_template.mappings + ); } - const indexTemplateSettings = - elasticsearch?.index_template?.settings || elasticsearch?.['index_template.settings']; - if (indexTemplateSettings) { - parsedElasticsearchEntry['index_template.settings'] = - expandDottedEntries(indexTemplateSettings); + if (expandedElasticsearch?.index_template?.settings) { + parsedElasticsearchEntry['index_template.settings'] = expandDottedEntries( + expandedElasticsearch.index_template.settings + ); } return parsedElasticsearchEntry; From f1f1b5789d8669d3bd40e937f8049683655c32ee Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Fri, 4 Nov 2022 13:19:19 -0400 Subject: [PATCH 31/31] [Synthetics] Sorting and infinite scroll (#139254) * unskip monitor state scoping tests * add describe.only * unskip monitor state scoping test * add retry logic * add sort order * add alphabetical and modified on sorting * adjust styling * adjust overview state * add infinite scroll and sort by status * [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' * adjust test * adjust tests * adjust tests * adjust ux * update infinite scroll behavior * adjust ux * adjust test * adjust i18n * Update x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.tsx * Update x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_monitors_sorted_by_status.tsx * adjust hook * update scroll logic * adjust sort field markup * fix/synthetics-preserve-id-field-on-monitor-attributes * add overview sorting e2e tests * add scroll test * adjust tests * adjust synthetics version * ensure test monitors are cleaned up * remove monitor id from use_monitors_sorted_by_status hook * remove unnecessary comments * update code formatting * [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' * adjust overview sorting logic * adjust tests * Update x-pack/plugins/synthetics/e2e/journeys/synthetics/overview_scrolling.journey.ts * adjust test * fix duplicate overview request Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- package.json | 4 +- .../monitor_management/monitor_types.ts | 2 +- .../synthetics_overview_status.ts | 9 + .../e2e/journeys/synthetics/index.ts | 2 + .../synthetics/monitor_selector.journey.ts | 6 +- .../synthetics/overview_scrolling.journey.ts | 63 +++ .../synthetics/overview_sorting.journey.ts | 130 +++++ .../e2e/page_objects/synthetics_app.tsx | 5 + .../overview/overview/metric_item.tsx | 5 +- .../overview/overview/overview_grid.test.tsx | 57 +- .../overview/overview/overview_grid.tsx | 168 ++++-- .../overview/overview_grid_item_loader.tsx | 21 + .../overview/overview/overview_loader.tsx | 27 + .../overview/overview_pagination_info.tsx | 94 +++- .../overview/overview/sort_fields.tsx | 211 +++++++ .../overview/overview/sort_menu.tsx | 126 +++++ .../monitors_page/overview/overview_page.tsx | 21 +- .../hooks/use_location_names.test.tsx | 53 ++ .../synthetics/hooks/use_location_names.tsx | 29 + .../use_monitors_sorted_by_status.test.tsx | 244 ++++++++ .../hooks/use_monitors_sorted_by_status.tsx | 83 +++ .../public/apps/synthetics/routes.tsx | 2 +- .../apps/synthetics/state/overview/actions.ts | 4 +- .../apps/synthetics/state/overview/api.ts | 2 +- .../apps/synthetics/state/overview/effects.ts | 13 +- .../apps/synthetics/state/overview/index.ts | 12 +- .../apps/synthetics/state/overview/models.ts | 2 + .../apps/synthetics/state/root_effect.ts | 7 +- .../__mocks__/synthetics_store.mock.ts | 4 +- .../routes/monitor_cruds/get_monitor.ts | 67 +-- .../routes/status/current_status.test.ts | 80 +++ .../server/routes/status/current_status.ts | 27 +- .../translations/translations/fr-FR.json | 1 - .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - .../apis/synthetics/get_monitor_overview.ts | 28 +- yarn.lock | 523 +++++++++++++----- 37 files changed, 1791 insertions(+), 343 deletions(-) create mode 100644 x-pack/plugins/synthetics/e2e/journeys/synthetics/overview_scrolling.journey.ts create mode 100644 x-pack/plugins/synthetics/e2e/journeys/synthetics/overview_sorting.journey.ts create mode 100644 x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid_item_loader.tsx create mode 100644 x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_loader.tsx create mode 100644 x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/sort_fields.tsx create mode 100644 x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/sort_menu.tsx create mode 100644 x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_location_names.test.tsx create mode 100644 x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_location_names.tsx create mode 100644 x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_monitors_sorted_by_status.test.tsx create mode 100644 x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_monitors_sorted_by_status.tsx diff --git a/package.json b/package.json index 1be185c0ea385..3be3cc131c27c 100644 --- a/package.json +++ b/package.json @@ -708,7 +708,7 @@ "@cypress/webpack-preprocessor": "^5.12.2", "@elastic/eslint-plugin-eui": "0.0.2", "@elastic/makelogs": "^6.1.1", - "@elastic/synthetics": "^1.0.0-beta.22", + "@elastic/synthetics": "^1.0.0-beta.23", "@emotion/babel-preset-css-prop": "^11.10.0", "@emotion/jest": "^11.10.0", "@istanbuljs/nyc-config-typescript": "^1.0.2", @@ -1089,7 +1089,7 @@ "pirates": "^4.0.1", "piscina": "^3.2.0", "pixelmatch": "^5.3.0", - "playwright": "^1.17.1", + "playwright": "^1.26.0", "pngjs": "^3.4.0", "postcss": "^8.4.14", "postcss-loader": "^4.2.0", diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts index e76ab594e7de7..f05729e29b49c 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts @@ -400,7 +400,7 @@ export type MonitorOverviewItem = t.TypeOf; export const MonitorOverviewResultCodec = t.type({ total: t.number, allMonitorIds: t.array(t.string), - pages: t.record(t.string, t.array(MonitorOverviewItemCodec)), + monitors: t.array(MonitorOverviewItemCodec), }); export type MonitorOverviewResult = t.TypeOf; diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/synthetics_overview_status.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/synthetics_overview_status.ts index afd6579788a99..7d85b1c2278df 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/synthetics_overview_status.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/synthetics_overview_status.ts @@ -7,10 +7,19 @@ import * as t from 'io-ts'; +export const OverviewStatusMetaDataCodec = t.interface({ + heartbeatId: t.string, + configId: t.string, + location: t.string, +}); + export const OverviewStatusType = t.type({ up: t.number, down: t.number, disabledCount: t.number, + upConfigs: t.array(OverviewStatusMetaDataCodec), + downConfigs: t.array(OverviewStatusMetaDataCodec), }); export type OverviewStatus = t.TypeOf; +export type OverviewStatusMetaData = t.TypeOf; diff --git a/x-pack/plugins/synthetics/e2e/journeys/synthetics/index.ts b/x-pack/plugins/synthetics/e2e/journeys/synthetics/index.ts index 1b74aa6a05b42..5affc2796c28a 100644 --- a/x-pack/plugins/synthetics/e2e/journeys/synthetics/index.ts +++ b/x-pack/plugins/synthetics/e2e/journeys/synthetics/index.ts @@ -8,3 +8,5 @@ export * from './getting_started.journey'; export * from './add_monitor.journey'; export * from './monitor_selector.journey'; +export * from './overview_sorting.journey'; +export * from './overview_scrolling.journey'; diff --git a/x-pack/plugins/synthetics/e2e/journeys/synthetics/monitor_selector.journey.ts b/x-pack/plugins/synthetics/e2e/journeys/synthetics/monitor_selector.journey.ts index 866df48d97e78..ab22de07846fc 100644 --- a/x-pack/plugins/synthetics/e2e/journeys/synthetics/monitor_selector.journey.ts +++ b/x-pack/plugins/synthetics/e2e/journeys/synthetics/monitor_selector.journey.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { journey, step, expect, before } from '@elastic/synthetics'; +import { journey, step, expect, before, after } from '@elastic/synthetics'; import { addTestMonitor, cleanTestMonitors, @@ -28,6 +28,10 @@ journey(`MonitorSelector`, async ({ page, params }) => { await addTestMonitor(params.kibanaUrl, testMonitor3); }); + after(async () => { + await cleanTestMonitors(params); + }); + step('Go to monitor-management', async () => { await syntheticsApp.navigateToMonitorManagement(); }); diff --git a/x-pack/plugins/synthetics/e2e/journeys/synthetics/overview_scrolling.journey.ts b/x-pack/plugins/synthetics/e2e/journeys/synthetics/overview_scrolling.journey.ts new file mode 100644 index 0000000000000..448bc2f106896 --- /dev/null +++ b/x-pack/plugins/synthetics/e2e/journeys/synthetics/overview_scrolling.journey.ts @@ -0,0 +1,63 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { before, after, expect, journey, step } from '@elastic/synthetics'; +import { + addTestMonitor, + cleanTestMonitors, + enableMonitorManagedViaApi, +} from './services/add_monitor'; +import { syntheticsAppPageProvider } from '../../page_objects/synthetics_app'; + +journey('Overview Scrolling', async ({ page, params }) => { + const syntheticsApp = syntheticsAppPageProvider({ page, kibanaUrl: params.kibanaUrl }); + + before(async () => { + await enableMonitorManagedViaApi(params.kibanaUrl); + await cleanTestMonitors(params); + + for (let i = 0; i < 100; i++) { + await addTestMonitor(params.kibanaUrl, `test monitor ${i}`); + } + + await syntheticsApp.waitForLoadingToFinish(); + }); + + after(async () => { + await cleanTestMonitors(params); + }); + + step('Go to overview', async () => { + await syntheticsApp.navigateToOverview(); + }); + + step('login to Kibana', async () => { + await syntheticsApp.loginToKibana(); + const invalid = await page.locator(`text=Username or password is incorrect. Please try again.`); + expect(await invalid.isVisible()).toBeFalsy(); + }); + + step('scroll until you see showing all monitors', async () => { + let showingAllMonitorsNode; + + const gridItems = await page.locator(`[data-test-subj="syntheticsOverviewGridItem"]`); + await page.waitForSelector(`text="test monitor 0"`); + let count = await gridItems.count(); + + expect(count).toBe(32); + + while (!showingAllMonitorsNode) { + await page.mouse.wheel(0, 100); + showingAllMonitorsNode = await page.$(`text="Showing all monitors"`); + } + + expect(await showingAllMonitorsNode.isVisible()).toBe(true); + + count = await gridItems.count(); + expect(count).toBe(100); + }); +}); diff --git a/x-pack/plugins/synthetics/e2e/journeys/synthetics/overview_sorting.journey.ts b/x-pack/plugins/synthetics/e2e/journeys/synthetics/overview_sorting.journey.ts new file mode 100644 index 0000000000000..27c6355de3c09 --- /dev/null +++ b/x-pack/plugins/synthetics/e2e/journeys/synthetics/overview_sorting.journey.ts @@ -0,0 +1,130 @@ +/* + * 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 { before, expect, journey, step } from '@elastic/synthetics'; +import { + addTestMonitor, + cleanTestMonitors, + enableMonitorManagedViaApi, +} from './services/add_monitor'; +import { syntheticsAppPageProvider } from '../../page_objects/synthetics_app'; + +journey('Overview Sorting', async ({ page, params }) => { + const syntheticsApp = syntheticsAppPageProvider({ page, kibanaUrl: params.kibanaUrl }); + const testMonitor1 = 'acb'; // second alpha, first created + const testMonitor2 = 'aCd'; // third alpha, second created + const testMonitor3 = 'Abc'; // first alpha, last created + + before(async () => { + await enableMonitorManagedViaApi(params.kibanaUrl); + await cleanTestMonitors(params); + + await addTestMonitor(params.kibanaUrl, testMonitor1); + await addTestMonitor(params.kibanaUrl, testMonitor2); + await addTestMonitor(params.kibanaUrl, testMonitor3); + + await syntheticsApp.waitForLoadingToFinish(); + }); + + step('Go to monitor-management', async () => { + await syntheticsApp.navigateToOverview(); + }); + + step('login to Kibana', async () => { + await syntheticsApp.loginToKibana(); + const invalid = await page.locator(`text=Username or password is incorrect. Please try again.`); + expect(await invalid.isVisible()).toBeFalsy(); + }); + + step('sort alpbhaetical asc', async () => { + await syntheticsApp.navigateToOverview(); + await page.waitForSelector(`[data-test-subj="syntheticsOverviewGridItem"]`); + await page.click('[data-test-subj="syntheticsOverviewSortButton"]'); + await page.click('button:has-text("Alphabetical")'); + await page.waitForSelector('text=Loading'); + await page.waitForSelector(`text=${testMonitor1}`); + await page.waitForSelector(`text=${testMonitor2}`); + await page.waitForSelector(`text=${testMonitor3}`); + const gridItems = await page.locator(`[data-test-subj="syntheticsOverviewGridItem"]`); + const first = await gridItems.nth(0); + const second = await gridItems.nth(1); + const third = await gridItems.nth(2); + const correctFirstMonitor = await first.locator(`button:has-text('${testMonitor3}')`); + const correctSecondMonitor = await second.locator(`button:has-text('${testMonitor1}')`); + const correctThirdMonitor = await third.locator(`button:has-text('${testMonitor2}')`); + expect(await correctFirstMonitor.count()).toBe(1); + expect(await correctSecondMonitor.count()).toBe(1); + expect(await correctThirdMonitor.count()).toBe(1); + }); + + step('sort alpbhaetical desc', async () => { + await page.waitForSelector(`[data-test-subj="syntheticsOverviewGridItem"]`); + await page.click('[data-test-subj="syntheticsOverviewSortButton"]'); + await page.click('button:has-text("Z -> A")'); + await page.waitForSelector('text=Loading'); + await page.waitForSelector(`text=${testMonitor1}`); + await page.waitForSelector(`text=${testMonitor2}`); + await page.waitForSelector(`text=${testMonitor3}`); + const gridItems = await page.locator(`[data-test-subj="syntheticsOverviewGridItem"]`); + const first = await gridItems.nth(0); + const second = await gridItems.nth(1); + const third = await gridItems.nth(2); + const correctFirstMonitor = await first.locator(`button:has-text('${testMonitor2}')`); + const correctSecondMonitor = await second.locator(`button:has-text('${testMonitor1}')`); + const correctThirdMonitor = await third.locator(`button:has-text('${testMonitor3}')`); + expect(await correctFirstMonitor.count()).toBe(1); + expect(await correctSecondMonitor.count()).toBe(1); + expect(await correctThirdMonitor.count()).toBe(1); + }); + + step('sort last updated asc', async () => { + await page.waitForSelector(`[data-test-subj="syntheticsOverviewGridItem"]`); + await page.click('[data-test-subj="syntheticsOverviewSortButton"]'); + await page.click('button:has-text("Last modified")'); + await page.waitForSelector('text=Loading'); + await page.waitForSelector(`text=${testMonitor1}`); + await page.waitForSelector(`text=${testMonitor2}`); + await page.waitForSelector(`text=${testMonitor3}`); + const gridItems = await page.locator(`[data-test-subj="syntheticsOverviewGridItem"]`); + const first = await gridItems.nth(0); + const second = await gridItems.nth(1); + const third = await gridItems.nth(2); + const correctFirstMonitor = await first.locator(`button:has-text('${testMonitor3}')`); + const correctSecondMonitor = await second.locator(`button:has-text('${testMonitor2}')`); + const correctThirdMonitor = await third.locator(`button:has-text('${testMonitor1}')`); + expect(await correctFirstMonitor.count()).toBe(1); + expect(await correctSecondMonitor.count()).toBe(1); + expect(await correctThirdMonitor.count()).toBe(1); + await page.waitForTimeout(30000); + }); + + step('sort last updated desc', async () => { + await page.waitForSelector(`[data-test-subj="syntheticsOverviewGridItem"]`); + await page.click('[data-test-subj="syntheticsOverviewSortButton"]'); + await page.click('button:has-text("Oldest first")'); + await page.waitForSelector('text=Loading'); + await page.waitForSelector(`text=${testMonitor1}`); + await page.waitForSelector(`text=${testMonitor2}`); + await page.waitForSelector(`text=${testMonitor3}`); + const gridItems = await page.locator(`[data-test-subj="syntheticsOverviewGridItem"]`); + const first = await gridItems.nth(0); + const second = await gridItems.nth(1); + const third = await gridItems.nth(2); + const correctFirstMonitor = await first.locator(`button:has-text('${testMonitor1}')`); + const correctSecondMonitor = await second.locator(`button:has-text('${testMonitor2}')`); + const correctThirdMonitor = await third.locator(`button:has-text('${testMonitor3}')`); + expect(await correctFirstMonitor.count()).toBe(1); + expect(await correctSecondMonitor.count()).toBe(1); + expect(await correctThirdMonitor.count()).toBe(1); + await page.waitForTimeout(30000); + }); + + step('delete monitors', async () => { + await syntheticsApp.navigateToMonitorManagement(); + expect(await syntheticsApp.deleteMonitors()).toBeTruthy(); + }); +}); diff --git a/x-pack/plugins/synthetics/e2e/page_objects/synthetics_app.tsx b/x-pack/plugins/synthetics/e2e/page_objects/synthetics_app.tsx index 2813427ae5225..71c4dafe5f07f 100644 --- a/x-pack/plugins/synthetics/e2e/page_objects/synthetics_app.tsx +++ b/x-pack/plugins/synthetics/e2e/page_objects/synthetics_app.tsx @@ -21,6 +21,7 @@ export function syntheticsAppPageProvider({ page, kibanaUrl }: { page: Page; kib const basePath = isRemote ? remoteKibanaUrl : kibanaUrl; const monitorManagement = `${basePath}/app/synthetics/monitors`; const addMonitor = `${basePath}/app/synthetics/add-monitor`; + const overview = `${basePath}/app/synthetics`; return { ...loginPageProvider({ page, @@ -37,6 +38,10 @@ export function syntheticsAppPageProvider({ page, kibanaUrl }: { page: Page; kib await this.waitForMonitorManagementLoadingToFinish(); }, + async navigateToOverview() { + await page.goto(overview, { waitUntil: 'networkidle' }); + }, + async waitForMonitorManagementLoadingToFinish() { while (true) { if ((await page.$(this.byTestId('uptimeLoader'))) === null) break; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/metric_item.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/metric_item.tsx index 755777bad04ea..bf93da5a6adea 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/metric_item.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/metric_item.tsx @@ -7,13 +7,14 @@ import { i18n } from '@kbn/i18n'; import React, { useState } from 'react'; import { Chart, Settings, Metric, MetricTrendShape } from '@elastic/charts'; -import { EuiPanel, EuiLoadingChart } from '@elastic/eui'; +import { EuiPanel } from '@elastic/eui'; import { DARK_THEME } from '@elastic/charts'; import { useTheme } from '@kbn/observability-plugin/public'; import { useLocationName, useStatusByLocation } from '../../../../hooks'; import { formatDuration } from '../../../../utils/formatting'; import { MonitorOverviewItem, Ping } from '../../../../../../../common/runtime_types'; import { ActionsPopover } from './actions_popover'; +import { OverviewGridItemLoader } from './overview_grid_item_loader'; export const getColor = (theme: ReturnType, isEnabled: boolean, ping?: Ping) => { if (!isEnabled) { @@ -101,7 +102,7 @@ export const MetricItem = ({ )} ) : ( - + )}
); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.test.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.test.tsx index 0e566856364bc..9514bba4258ed 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.test.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.test.tsx @@ -48,22 +48,64 @@ describe('Overview Grid', () => { return hits; }; + const perPage = 20; + it('renders correctly', async () => { jest .spyOn(hooks, 'useLast50DurationChart') .mockReturnValue({ data: getMockChart(), averageDuration: 30000, loading: false }); - const { getByText, getAllByTestId } = render(, { + const { getByText, getAllByTestId, queryByText } = render(, { state: { overview: { pageState: { - perPage: 20, + perPage, }, data: { - pages: { - 0: getMockData().slice(0, 20), - 1: getMockData().slice(20, 40), + monitors: getMockData(), + allMonitorIds: [], // not critical for this test + total: getMockData().length, + }, + loaded: true, + loading: false, + }, + serviceLocations: { + locations: [ + { + id: 'us_central', + label: 'Us Central', + }, + { + id: 'us_east', + label: 'US East', }, + ], + locationsLoaded: true, + loading: false, + }, + }, + }); + + expect(getByText('Showing')).toBeInTheDocument(); + expect(getByText('40')).toBeInTheDocument(); + expect(getByText('Monitors')).toBeInTheDocument(); + expect(queryByText('Showing all monitors')).not.toBeInTheDocument(); + expect(getAllByTestId('syntheticsOverviewGridItem').length).toEqual(perPage); + }); + + it('displays showing all monitors label when reaching the end of the list', async () => { + jest + .spyOn(hooks, 'useLast50DurationChart') + .mockReturnValue({ data: getMockChart(), averageDuration: 30000, loading: false }); + + const { getByText } = render(, { + state: { + overview: { + pageState: { + perPage, + }, + data: { + monitors: getMockData().slice(0, 16), allMonitorIds: [], // not critical for this test total: getMockData().length, }, @@ -87,9 +129,6 @@ describe('Overview Grid', () => { }, }); - expect(getByText(/1-20/)).toBeInTheDocument(); - expect(getByText(/of 40/)).toBeInTheDocument(); - expect(getByText('Rows per page: 20')).toBeInTheDocument(); - expect(getAllByTestId('syntheticsOverviewGridItem').length).toEqual(20); + expect(getByText('Showing all monitors')).toBeInTheDocument(); }); }); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.tsx index 359f292079fdb..cf3163052bd73 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.tsx @@ -4,40 +4,77 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import React, { useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import React, { useEffect, useState, useRef } from 'react'; import { i18n } from '@kbn/i18n'; +import useThrottle from 'react-use/lib/useThrottle'; +import { useSelector } from 'react-redux'; +import useIntersection from 'react-use/lib/useIntersection'; import { + EuiFlexGroup, EuiFlexItem, EuiFlexGrid, EuiSpacer, - EuiTablePagination, - EuiFlexGroup, + EuiButtonEmpty, + EuiText, } from '@elastic/eui'; -import { selectOverviewState, setOverviewPerPageAction } from '../../../../state/overview'; +import { selectOverviewState } from '../../../../state/overview'; +import { MonitorOverviewItem } from '../../../../../../../common/runtime_types'; import { OverviewPaginationInfo } from './overview_pagination_info'; import { OverviewGridItem } from './overview_grid_item'; +import { SortFields } from './sort_fields'; +import { useMonitorsSortedByStatus } from '../../../../hooks/use_monitors_sorted_by_status'; +import { OverviewLoader } from './overview_loader'; import { OverviewStatus } from './overview_status'; export const OverviewGrid = () => { const { - data: { pages }, + data: { monitors }, loaded, - pageState: { perPage }, + pageState, } = useSelector(selectOverviewState); - const dispatch = useDispatch(); - const [page, setPage] = useState(0); - const currentMonitors = pages[page] || []; + const { perPage, sortField } = pageState; + const [loadNextPage, setLoadNextPage] = useState(false); + const [page, setPage] = useState(1); + + const { monitorsSortedByStatus } = useMonitorsSortedByStatus( + sortField === 'status' && monitors.length !== 0 + ); + const currentMonitors = getCurrentMonitors({ + monitors, + monitorsSortedByStatus, + perPage, + page, + sortField, + }); + + const intersectionRef = useRef(null); + const intersection = useIntersection(intersectionRef, { + root: null, + rootMargin: '640px', // Height of 4 rows of monitors, minus the gutters + threshold: 0.1, + }); + const hasIntersected = intersection && intersection.intersectionRatio > 0; - const goToPage = (pageNumber: number) => { - setPage(pageNumber); - }; + useThrottle(() => { + if ( + hasIntersected && + currentMonitors.length === page * perPage && + currentMonitors.length !== monitors.length + ) { + setLoadNextPage(true); + } else { + setLoadNextPage(false); + } + }, 1000); - const changeItemsPerPage = (itemsPerPage: number) => { - dispatch(setOverviewPerPageAction(itemsPerPage)); - }; + useEffect(() => { + if (loadNextPage) { + setPage((p) => p + 1); + setLoadNextPage(false); + } + }, [loadNextPage]); - return loaded ? ( + return ( <> @@ -45,29 +82,82 @@ export const OverviewGrid = () => { - + + + + + + setPage(1)} /> + + - - {currentMonitors.map((monitor) => ( - - + {loaded && currentMonitors.length ? ( + + {currentMonitors.map((monitor) => ( + + + + ))} + + ) : ( + + )} + + + + + {currentMonitors.length === monitors.length && ( + + {SHOWING_ALL_MONITORS_LABEL} + + )} + {currentMonitors.length === monitors.length && currentMonitors.length > perPage && ( + + window.scrollTo(0, 0)} + iconType="sortUp" + iconSide="right" + size="xs" + > + {SCROLL_TO_TOP_LABEL} + - ))} - - + )} + - ) : null; + ); }; + +const getCurrentMonitors = ({ + sortField, + perPage, + page, + monitors, + monitorsSortedByStatus, +}: { + sortField: string; + perPage: number; + page: number; + monitors: MonitorOverviewItem[]; + monitorsSortedByStatus: MonitorOverviewItem[]; +}) => { + if (sortField === 'status') { + return monitorsSortedByStatus.slice(0, perPage * page); + } else { + return monitors.slice(0, perPage * page); + } +}; + +const SHOWING_ALL_MONITORS_LABEL = i18n.translate( + 'xpack.synthetics.overview.grid.showingAllMonitors.label', + { + defaultMessage: 'Showing all monitors', + } +); + +const SCROLL_TO_TOP_LABEL = i18n.translate('xpack.synthetics.overview.grid.scrollToTop.label', { + defaultMessage: 'Back to top', +}); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid_item_loader.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid_item_loader.tsx new file mode 100644 index 0000000000000..71a369ad44db5 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid_item_loader.tsx @@ -0,0 +1,21 @@ +/* + * 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 { EuiPanel, EuiLoadingContent } from '@elastic/eui'; + +export const OverviewGridItemLoader = () => { + return ( + + + + ); +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_loader.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_loader.tsx new file mode 100644 index 0000000000000..92cb67187b5bb --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_loader.tsx @@ -0,0 +1,27 @@ +/* + * 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 { EuiFlexGrid, EuiFlexItem } from '@elastic/eui'; +import { OverviewGridItemLoader } from './overview_grid_item_loader'; + +export const OverviewLoader = () => { + const ROWS = 4; + const COLUMNS = 4; + const loaders = Array(ROWS * COLUMNS).fill(null); + return ( + <> + + {loaders.map((_, i) => ( + + + + ))} + + + ); +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_pagination_info.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_pagination_info.tsx index a00f9f9d1692e..d684e4aa41e88 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_pagination_info.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_pagination_info.tsx @@ -5,42 +5,88 @@ * 2.0. */ import React from 'react'; -import { EuiText } from '@elastic/eui'; +import { EuiText, EuiLoadingSpinner, EuiI18nNumber, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { useSelector } from 'react-redux'; import { FormattedMessage } from '@kbn/i18n-react'; import { selectOverviewState } from '../../../../state/overview'; -export const OverviewPaginationInfo = ({ page }: { page: number }) => { +export const OverviewPaginationInfo = ({ + page, + loading, + startRange, + endRange, +}: { + page: number; + loading: boolean; + startRange?: number; + endRange?: number; +}) => { const { - data: { total, pages }, + data: { total, monitors }, loaded, - pageState: { perPage }, } = useSelector(selectOverviewState); - const startRange = (page + 1) * perPage - perPage + 1; - const endRange = startRange + (pages[`${page}`]?.length || 0) - 1; - if (loaded && !Object.keys(pages).length) { + if (loaded && !monitors.length) { return null; } return loaded ? ( - {`${startRange}-${endRange}`}, - total, - monitors: ( - - - - ), - }} - /> + {startRange && endRange ? ( + {`${startRange}-${endRange}`}, + total, + monitors: ( + + + + ), + }} + /> + ) : ( + + + + ), + monitorsLabel: ( + + + + ), + }} + /> + )} - ) : null; + ) : ( + + + + + + + + + + + ); }; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/sort_fields.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/sort_fields.tsx new file mode 100644 index 0000000000000..5bd3dfd44dd33 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/sort_fields.tsx @@ -0,0 +1,211 @@ +/* + * 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 type { PayloadAction } from '@reduxjs/toolkit'; +import { useDispatch, useSelector } from 'react-redux'; +import { i18n } from '@kbn/i18n'; +import { EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui'; +import { ConfigKey } from '../../../../../../../common/runtime_types'; + +import { selectOverviewState, setOverviewPageStateAction } from '../../../../state/overview'; +import { SortMenu } from './sort_menu'; + +export const SortFields = ({ onSortChange }: { onSortChange?: () => void }) => { + const { + pageState: { sortOrder, sortField }, + } = useSelector(selectOverviewState); + const dispatch = useDispatch(); + const { asc, desc, label } = getOrderContent(sortField); + const handleSortChange = (payloadAction: PayloadAction) => { + if (onSortChange) { + onSortChange(); + } + dispatch(payloadAction); + }; + + const orderByOptions = [ + { + label: asc, + value: 'asc', + checked: sortOrder === 'asc', + onClick: () => { + handleSortChange( + setOverviewPageStateAction({ + sortOrder: 'asc', + }) + ); + }, + }, + { + label: desc, + value: 'desc', + checked: sortOrder === 'desc', + onClick: () => { + handleSortChange( + setOverviewPageStateAction({ + sortOrder: 'desc', + }) + ); + }, + }, + ]; + const sortByOptions = [ + { + label: STATUS_LABEL, + value: 'status', + checked: sortField === 'status', + defaultSortOrder: 'asc', + onClick: () => { + handleSortChange( + setOverviewPageStateAction({ + sortField: 'status', + sortOrder: 'asc', + }) + ); + }, + }, + { + label: ALPHABETICAL_LABEL, + value: `${ConfigKey.NAME}.keyword`, + checked: sortField === `${ConfigKey.NAME}.keyword`, + defaultSortOrder: 'asc', + onClick: () => { + handleSortChange( + setOverviewPageStateAction({ + sortField: `${ConfigKey.NAME}.keyword`, + sortOrder: 'asc', + }) + ); + }, + }, + { + label: LAST_MODIFIED_LABEL, + value: 'updated_at', + checked: sortField === 'updated_at', + defaultSortOrder: 'desc', + onClick: () => { + handleSortChange( + setOverviewPageStateAction({ + sortField: 'updated_at', + sortOrder: 'desc', + }) + ); + }, + }, + ]; + + return ( + + + + + + {SORT_TITLE} + + + + + + + + + ); +}; + +const getOrderContent = (sortField: string) => { + switch (sortField) { + case `${ConfigKey.NAME}.keyword`: + return { + asc: SORT_ALPHABETICAL_ASC, + desc: SORT_ALPHABETICAL_DESC, + label: ALPHABETICAL_LABEL, + }; + case 'updated_at': + return { + asc: SORT_UPDATED_ASC, + desc: SORT_UPDATED_DESC, + label: LAST_MODIFIED_LABEL, + }; + case 'status': + return { + asc: SORT_STATUS_ASC, + desc: SORT_STATUS_DESC, + label: STATUS_LABEL, + }; + default: + return { + asc: ASCENDING_LABEL, + desc: DESCENDING_LABEL, + label: '', + }; + } +}; + +const SORT_TITLE = i18n.translate('xpack.synthetics.overview.sortPopover.sort.title', { + defaultMessage: 'Sort', +}); + +const SORT_ALPHABETICAL_ASC = i18n.translate( + 'xpack.synthetics.overview.sortPopover.alphabetical.asc', + { + defaultMessage: 'A -> Z', + description: 'Describes ascending alphabetical sort order', + } +); + +const SORT_ALPHABETICAL_DESC = i18n.translate( + 'xpack.synthetics.overview.sortPopover.alphabetical.desc', + { + defaultMessage: 'Z -> A', + description: 'Describes descending alphabetical sort order', + } +); + +const SORT_UPDATED_ASC = i18n.translate('xpack.synthetics.overview.sortPopover.lastModified.asc', { + defaultMessage: 'Oldest first', +}); + +const SORT_UPDATED_DESC = i18n.translate( + 'xpack.synthetics.overview.sortPopover.lastModified.desc', + { + defaultMessage: 'Newest first', + } +); + +const SORT_STATUS_ASC = i18n.translate('xpack.synthetics.overview.sortPopover.status.asc', { + defaultMessage: 'Down first', +}); + +const SORT_STATUS_DESC = i18n.translate('xpack.synthetics.overview.sortPopover.status.desc', { + defaultMessage: 'Up first', +}); + +const ASCENDING_LABEL = i18n.translate('xpack.synthetics.overview.sortPopover.ascending.label', { + defaultMessage: 'Ascending', +}); + +const DESCENDING_LABEL = i18n.translate('xpack.synthetics.overview.sortPopover.descending.label', { + defaultMessage: 'Descending', +}); + +const STATUS_LABEL = i18n.translate('xpack.synthetics.overview.sortPopover.status.label', { + defaultMessage: 'Status', +}); + +const ALPHABETICAL_LABEL = i18n.translate( + 'xpack.synthetics.overview.sortPopover.alphabetical.label', + { + defaultMessage: 'Alphabetical', + } +); + +const LAST_MODIFIED_LABEL = i18n.translate( + 'xpack.synthetics.overview.sortPopover.lastModified.label', + { + defaultMessage: 'Last modified', + } +); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/sort_menu.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/sort_menu.tsx new file mode 100644 index 0000000000000..c512fcb0bf388 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/sort_menu.tsx @@ -0,0 +1,126 @@ +/* + * 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, { useState } from 'react'; +import { i18n } from '@kbn/i18n'; +import { + EuiButtonEmpty, + EuiContextMenuPanel, + EuiContextMenuItem, + EuiPopover, + useGeneratedHtmlId, + EuiText, + EuiPanel, + EuiHorizontalRule, +} from '@elastic/eui'; + +interface Option { + label: string; + value: string; + checked: boolean; + defaultSortOrder?: string; + onClick: () => void; +} + +interface Props { + sortOptions: Option[]; + orderOptions: Option[]; + sortField: string; +} + +export const SortMenu = ({ sortOptions, orderOptions, sortField }: Props) => { + const [isPopoverOpen, setPopover] = useState(false); + + const singleContextMenuPopoverId = useGeneratedHtmlId({ + prefix: 'singleContextMenuPopover', + }); + + const onButtonClick = () => { + setPopover(!isPopoverOpen); + }; + + const closePopover = () => { + setPopover(false); + }; + + const button = ( + + {sortField} + + ); + + const items = [ + + +

{SORT_BY_TITLE}

+
+
, + ...sortOptions.map((option) => ( + + )), + , + + + +

{ORDER_BY_TITLE}

+
+
, + + ...orderOptions.map((option) => ( + + )), + ]; + + return ( + + + + ); +}; + +const ContextMenuItem = ({ + option, + onClosePopover, +}: { + option: Option; + onClosePopover: () => void; +}) => { + const getIconType = (checked: boolean) => { + return checked ? 'check' : 'empty'; + }; + + return ( + { + onClosePopover(); + option.onClick(); + }} + style={{ + marginRight: 24, + }} + > + {option.label} + + ); +}; + +const SORT_BY_TITLE = i18n.translate('xpack.synthetics.overview.sortPopover.sortBy.title', { + defaultMessage: 'Sort by', +}); + +const ORDER_BY_TITLE = i18n.translate('xpack.synthetics.overview.sortPopover.orderBy.title', { + defaultMessage: 'Order', +}); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview_page.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview_page.tsx index 23997199c5b60..7b15883b79f3e 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview_page.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview_page.tsx @@ -7,13 +7,13 @@ import React, { useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { EuiLoadingElastic, EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; import { useTrackPageview } from '@kbn/observability-plugin/public'; import { Redirect } from 'react-router-dom'; import { useEnablement } from '../../../hooks'; import { useSyntheticsRefreshContext } from '../../../contexts/synthetics_refresh_context'; import { fetchMonitorOverviewAction, + quietFetchOverviewAction, selectOverviewState, selectServiceLocationsState, } from '../../../state'; @@ -34,7 +34,7 @@ export const OverviewPage: React.FC = () => { const { refreshApp, lastRefresh } = useSyntheticsRefreshContext(); - const { loading, pageState } = useSelector(selectOverviewState); + const { pageState } = useSelector(selectOverviewState); const { loading: locationsLoading, locationsLoaded } = useSelector(selectServiceLocationsState); useEffect(() => { @@ -48,10 +48,14 @@ export const OverviewPage: React.FC = () => { if (!locationsLoading && !locationsLoaded) { dispatch(getServiceLocations()); } - }, [dispatch, locationsLoaded, locationsLoading, pageState]); + }, [dispatch, locationsLoaded, locationsLoading]); useEffect(() => { dispatch(fetchMonitorOverviewAction.get(pageState)); + }, [dispatch, pageState]); + + useEffect(() => { + dispatch(quietFetchOverviewAction.get(pageState)); }, [dispatch, pageState, lastRefresh]); const { @@ -69,14 +73,5 @@ export const OverviewPage: React.FC = () => { return ; } - return !loading ? ( - - ) : ( - - - - - - - ); + return ; }; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_location_names.test.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_location_names.test.tsx new file mode 100644 index 0000000000000..26d808ca5ef7c --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_location_names.test.tsx @@ -0,0 +1,53 @@ +/* + * 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 { renderHook } from '@testing-library/react-hooks'; +import { useLocationNames } from './use_location_names'; +import { WrappedHelper } from '../utils/testing'; + +describe('useMonitorListFilters', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('returns map of id to name', () => { + const WrapperWithState = ({ children }: { children: React.ReactElement }) => { + return ( + + {children} + + ); + }; + + const { result } = renderHook(() => useLocationNames(), { wrapper: WrapperWithState }); + expect(result.current).toEqual({ + us_central: 'US Central', + us_east: 'US East', + }); + }); +}); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_location_names.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_location_names.tsx new file mode 100644 index 0000000000000..1911719a093e3 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_location_names.tsx @@ -0,0 +1,29 @@ +/* + * 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 { useMemo, useEffect } from 'react'; +import { useSelector, useDispatch } from 'react-redux'; +import { selectServiceLocationsState, getServiceLocations } from '../state'; + +export function useLocationNames() { + const dispatch = useDispatch(); + const { locationsLoaded, locations } = useSelector(selectServiceLocationsState); + useEffect(() => { + if (!locationsLoaded) { + dispatch(getServiceLocations()); + } + }); + + return useMemo( + () => + locations.reduce>((acc, location) => { + acc[location.id] = location.label; + return acc; + }, {}), + [locations] + ); +} diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_monitors_sorted_by_status.test.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_monitors_sorted_by_status.test.tsx new file mode 100644 index 0000000000000..844eb04649f8e --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_monitors_sorted_by_status.test.tsx @@ -0,0 +1,244 @@ +/* + * 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 { renderHook } from '@testing-library/react-hooks'; +import { useMonitorsSortedByStatus } from './use_monitors_sorted_by_status'; +import { WrappedHelper } from '../utils/testing'; + +describe('useMonitorsSortedByStatus', () => { + const location1 = { + url: 'mockUrl', + id: 'us_central', + label: 'US Central', + isServiceManaged: true, + }; + + const location2 = { + url: 'mockUrl', + id: 'us_east', + label: 'US East', + isServiceManaged: true, + }; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + const WrapperWithState = ({ + children, + sortOrder = 'asc', + }: { + children: React.ReactElement; + sortOrder: 'asc' | 'desc'; + }) => { + return ( + + {children} + + ); + }; + + it('returns monitors down first when sort order is asc', () => { + const { result } = renderHook(() => useMonitorsSortedByStatus(true), { + wrapper: WrapperWithState, + }); + expect(result.current).toEqual({ + monitorsSortedByStatus: [ + { + id: 'test-monitor-2', + name: 'Test monitor 2', + location: location1, + isEnabled: true, + }, + { + id: 'test-monitor-3', + name: 'Test monitor 3', + location: location1, + isEnabled: true, + }, + { + id: 'test-monitor-1', + name: 'Test monitor 1', + location: location2, + isEnabled: true, + }, + { + id: 'test-monitor-2', + name: 'Test monitor 2', + location: location2, + isEnabled: true, + }, + { + id: 'test-monitor-3', + name: 'Test monitor 3', + location: location2, + isEnabled: true, + }, + { + id: 'test-monitor-1', + name: 'Test monitor 1', + location: location1, + isEnabled: false, + }, + ], + downMonitors: { + 'test-monitor-1': ['US Central'], + 'test-monitor-2': ['US Central'], + 'test-monitor-3': ['US Central'], + }, + }); + }); + + it('returns monitors up first when sort order is desc', () => { + const { result } = renderHook(() => useMonitorsSortedByStatus(true), { + wrapper: ({ children }: { children: React.ReactElement }) => ( + {children} + ), + }); + expect(result.current).toEqual({ + monitorsSortedByStatus: [ + { + id: 'test-monitor-1', + name: 'Test monitor 1', + location: location2, + isEnabled: true, + }, + { + id: 'test-monitor-2', + name: 'Test monitor 2', + location: location2, + isEnabled: true, + }, + { + id: 'test-monitor-3', + name: 'Test monitor 3', + location: location2, + isEnabled: true, + }, + { + id: 'test-monitor-2', + name: 'Test monitor 2', + location: location1, + isEnabled: true, + }, + { + id: 'test-monitor-3', + name: 'Test monitor 3', + location: location1, + isEnabled: true, + }, + { + id: 'test-monitor-1', + name: 'Test monitor 1', + location: location1, + isEnabled: false, + }, + ], + downMonitors: { + 'test-monitor-1': ['US Central'], + 'test-monitor-2': ['US Central'], + 'test-monitor-3': ['US Central'], + }, + }); + }); +}); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_monitors_sorted_by_status.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_monitors_sorted_by_status.tsx new file mode 100644 index 0000000000000..0227722d7092a --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_monitors_sorted_by_status.tsx @@ -0,0 +1,83 @@ +/* + * 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 { useEffect, useMemo, useState, useRef } from 'react'; +import { isEqual } from 'lodash'; +import { useSelector } from 'react-redux'; +import { MonitorOverviewItem } from '../../../../common/runtime_types'; +import { selectOverviewState } from '../state/overview'; +import { useLocationNames } from './use_location_names'; + +export function useMonitorsSortedByStatus(shouldUpdate: boolean) { + const { + pageState: { sortOrder }, + data: { monitors }, + status, + } = useSelector(selectOverviewState); + const [monitorsSortedByStatus, setMonitorsSortedByStatus] = useState< + Record + >({ up: [], down: [], disabled: [] }); + const downMonitors = useRef | null>(null); + const currentMonitors = useRef(monitors); + const locationNames = useLocationNames(); + + useEffect(() => { + if (!status) { + return; + } + const { downConfigs } = status; + const downMonitorMap: Record = {}; + downConfigs.forEach(({ location, configId }) => { + if (downMonitorMap[configId]) { + downMonitorMap[configId].push(location); + } else { + downMonitorMap[configId] = [location]; + } + }); + + if ( + !isEqual(downMonitorMap, downMonitors.current) || + !isEqual(monitors, currentMonitors.current) + ) { + const orderedDownMonitors: MonitorOverviewItem[] = []; + const orderedUpMonitors: MonitorOverviewItem[] = []; + const orderedDisabledMonitors: MonitorOverviewItem[] = []; + monitors.forEach((monitor) => { + const monitorLocation = locationNames[monitor.location.id]; + if (!monitor.isEnabled) { + orderedDisabledMonitors.push(monitor); + } else if ( + Object.keys(downMonitorMap).includes(monitor.id) && + downMonitorMap[monitor.id].includes(monitorLocation) + ) { + orderedDownMonitors.push(monitor); + } else { + orderedUpMonitors.push(monitor); + } + }); + downMonitors.current = downMonitorMap; + currentMonitors.current = monitors; + setMonitorsSortedByStatus({ + down: orderedDownMonitors, + up: orderedUpMonitors, + disabled: orderedDisabledMonitors, + }); + } + }, [monitors, locationNames, downMonitors, status]); + + return useMemo(() => { + const upAndDownMonitors = + sortOrder === 'asc' + ? [...monitorsSortedByStatus.down, ...monitorsSortedByStatus.up] + : [...monitorsSortedByStatus.up, ...monitorsSortedByStatus.down]; + + return { + monitorsSortedByStatus: [...upAndDownMonitors, ...monitorsSortedByStatus.disabled], + downMonitors: downMonitors.current, + }; + }, [downMonitors, monitorsSortedByStatus, sortOrder]); +} diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/routes.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/routes.tsx index be85e9bdcc08d..8f9253cf984a6 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/routes.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/routes.tsx @@ -148,7 +148,7 @@ const getRoutes = ( values: { baseTitle }, }), path: OVERVIEW_ROUTE, - component: () => , + component: OverviewPage, dataTestSubj: 'syntheticsOverviewPage', pageHeader: { pageTitle: ( diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/state/overview/actions.ts b/x-pack/plugins/synthetics/public/apps/synthetics/state/overview/actions.ts index c89179a41806e..d94ab2d965216 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/state/overview/actions.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/state/overview/actions.ts @@ -15,7 +15,9 @@ export const fetchMonitorOverviewAction = createAsyncAction< MonitorOverviewResult >('fetchMonitorOverviewAction'); -export const setOverviewPerPageAction = createAction('setOverviewPerPageAction'); +export const setOverviewPageStateAction = createAction>( + 'setOverviewPageStateAction' +); export const quietFetchOverviewAction = createAsyncAction< MonitorOverviewPageState, diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/state/overview/api.ts b/x-pack/plugins/synthetics/public/apps/synthetics/state/overview/api.ts index ecd91b16bb940..db470a18b0423 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/state/overview/api.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/state/overview/api.ts @@ -21,7 +21,7 @@ export const fetchMonitorOverview = async ( ): Promise => { return await apiService.get( SYNTHETICS_API_URLS.SYNTHETICS_OVERVIEW, - { perPage: pageState.perPage }, + { perPage: pageState.perPage, sortOrder: pageState.sortOrder, sortField: pageState.sortField }, MonitorOverviewResultCodec ); }; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/state/overview/effects.ts b/x-pack/plugins/synthetics/public/apps/synthetics/state/overview/effects.ts index 56b056a93110c..0e880dca5a387 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/state/overview/effects.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/state/overview/effects.ts @@ -17,7 +17,7 @@ import { fetchMonitorOverview, fetchOverviewStatus } from './api'; export function* fetchMonitorOverviewEffect() { yield takeLeading( - fetchMonitorOverviewAction.get, + [fetchMonitorOverviewAction.get, quietFetchOverviewAction.get], fetchEffectFactory( fetchMonitorOverview, fetchMonitorOverviewAction.success, @@ -26,17 +26,6 @@ export function* fetchMonitorOverviewEffect() { ); } -export function* quietFetchOverviewEffect() { - yield takeLeading( - quietFetchOverviewAction.get, - fetchEffectFactory( - fetchMonitorOverview, - quietFetchOverviewAction.success, - quietFetchOverviewAction.fail - ) - ); -} - export function* fetchOverviewStatusEffect() { yield takeLatest( [fetchOverviewStatusAction.get, fetchUpsertSuccessAction], diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/state/overview/index.ts b/x-pack/plugins/synthetics/public/apps/synthetics/state/overview/index.ts index 82272638ffb11..8f2031480f115 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/state/overview/index.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/state/overview/index.ts @@ -17,7 +17,7 @@ import { fetchMonitorOverviewAction, fetchOverviewStatusAction, quietFetchOverviewAction, - setOverviewPerPageAction, + setOverviewPageStateAction, } from './actions'; export interface MonitorOverviewState { @@ -34,10 +34,12 @@ const initialState: MonitorOverviewState = { data: { total: 0, allMonitorIds: [], - pages: {}, + monitors: [], }, pageState: { - perPage: 20, + perPage: 16, + sortOrder: 'asc', + sortField: 'status', }, loading: false, loaded: false, @@ -68,10 +70,10 @@ export const monitorOverviewReducer = createReducer(initialState, (builder) => { .addCase(quietFetchOverviewAction.fail, (state, action) => { state.error = action.payload; }) - .addCase(setOverviewPerPageAction, (state, action) => { + .addCase(setOverviewPageStateAction, (state, action) => { state.pageState = { ...state.pageState, - perPage: action.payload, + ...action.payload, }; state.loaded = false; }) diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/state/overview/models.ts b/x-pack/plugins/synthetics/public/apps/synthetics/state/overview/models.ts index d7dcaafeba917..6cc423a3bddda 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/state/overview/models.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/state/overview/models.ts @@ -7,4 +7,6 @@ export interface MonitorOverviewPageState { perPage: number; + sortOrder: 'asc' | 'desc'; + sortField: string; } diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/state/root_effect.ts b/x-pack/plugins/synthetics/public/apps/synthetics/state/root_effect.ts index f8f13b7ed54e8..7a5c55d72fd24 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/state/root_effect.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/state/root_effect.ts @@ -11,11 +11,7 @@ import { fetchSyntheticsMonitorEffect } from './monitor_details'; import { fetchIndexStatusEffect } from './index_status'; import { fetchSyntheticsEnablementEffect } from './synthetics_enablement'; import { fetchMonitorListEffect, upsertMonitorEffect } from './monitor_list'; -import { - fetchMonitorOverviewEffect, - quietFetchOverviewEffect, - fetchOverviewStatusEffect, -} from './overview'; +import { fetchMonitorOverviewEffect, fetchOverviewStatusEffect } from './overview'; import { fetchServiceLocationsEffect } from './service_locations'; import { browserJourneyEffects } from './browser_journey'; @@ -28,7 +24,6 @@ export const rootEffect = function* root(): Generator { fork(fetchMonitorListEffect), fork(fetchSyntheticsMonitorEffect), fork(fetchMonitorOverviewEffect), - fork(quietFetchOverviewEffect), fork(browserJourneyEffects), fork(fetchOverviewStatusEffect), fork(fetchNetworkEventsEffect), diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/utils/testing/__mocks__/synthetics_store.mock.ts b/x-pack/plugins/synthetics/public/apps/synthetics/utils/testing/__mocks__/synthetics_store.mock.ts index c591b90ac5440..7bf845deee9a6 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/utils/testing/__mocks__/synthetics_store.mock.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/utils/testing/__mocks__/synthetics_store.mock.ts @@ -87,11 +87,13 @@ export const mockState: SyntheticsAppState = { overview: { pageState: { perPage: 10, + sortOrder: 'asc', + sortField: 'name.keyword', }, data: { total: 0, allMonitorIds: [], - pages: {}, + monitors: [], }, error: null, loaded: false, diff --git a/x-pack/plugins/synthetics/server/routes/monitor_cruds/get_monitor.ts b/x-pack/plugins/synthetics/server/routes/monitor_cruds/get_monitor.ts index 1d02454ce04ba..0a3ece38ee788 100644 --- a/x-pack/plugins/synthetics/server/routes/monitor_cruds/get_monitor.ts +++ b/x-pack/plugins/synthetics/server/routes/monitor_cruds/get_monitor.ts @@ -6,7 +6,7 @@ */ import { schema } from '@kbn/config-schema'; import { SavedObjectsErrorHelpers } from '@kbn/core/server'; -import { ConfigKey } from '../../../common/runtime_types'; +import { ConfigKey, MonitorOverviewItem, SyntheticsMonitor } from '../../../common/runtime_types'; import { UMServerLibs } from '../../legacy_uptime/lib/lib'; import { SyntheticsRestApiRouteFactory } from '../../legacy_uptime/routes/types'; import { API_URLS, SYNTHETICS_API_URLS } from '../../../common/constants'; @@ -112,55 +112,42 @@ export const getSyntheticsMonitorOverviewRoute: SyntheticsRestApiRouteFactory = query: querySchema, }, handler: async ({ request, savedObjectsClient, syntheticsMonitorClient }): Promise => { - const { perPage = 5 } = request.query; - const { saved_objects: monitors } = await getMonitors( - { - perPage: 1000, - sortField: 'name.keyword', - sortOrder: 'asc', - page: 1, - }, - syntheticsMonitorClient.syntheticsService, - savedObjectsClient - ); + const { sortField, sortOrder } = request.query; + const finder = savedObjectsClient.createPointInTimeFinder({ + type: syntheticsMonitorType, + sortField: sortField === 'status' ? `${ConfigKey.NAME}.keyword` : sortField, + sortOrder, + perPage: 500, + }); const allMonitorIds: string[] = []; - const pages: Record = {}; - let currentPage = 0; - let currentItem = 0; let total = 0; + const allMonitors: MonitorOverviewItem[] = []; - monitors.forEach((monitor) => { + for await (const result of finder.find()) { /* collect all monitor ids for use * in filtering overview requests */ - const id = monitor.id; - allMonitorIds.push(id); + result.saved_objects.forEach((monitor) => { + const id = monitor.id; + allMonitorIds.push(id); - /* for reach location, add a config item */ - const locations = monitor.attributes[ConfigKey.LOCATIONS]; - locations.forEach((location) => { - const config = { - id, - name: monitor.attributes[ConfigKey.NAME], - location, - isEnabled: monitor.attributes[ConfigKey.ENABLED], - }; - if (!pages[currentPage]) { - pages[currentPage] = [config]; - } else { - pages[currentPage].push(config); - } - currentItem++; - total++; - if (currentItem % perPage === 0) { - currentPage++; - currentItem = 0; - } + /* for reach location, add a config item */ + const locations = monitor.attributes[ConfigKey.LOCATIONS]; + locations.forEach((location) => { + const config = { + id, + name: monitor.attributes[ConfigKey.NAME], + location, + isEnabled: monitor.attributes[ConfigKey.ENABLED], + }; + allMonitors.push(config); + total++; + }); }); - }); + } return { - pages, + monitors: allMonitors, total, allMonitorIds, }; diff --git a/x-pack/plugins/synthetics/server/routes/status/current_status.test.ts b/x-pack/plugins/synthetics/server/routes/status/current_status.test.ts index 12fdea5b9fd4d..3a03d96f14db7 100644 --- a/x-pack/plugins/synthetics/server/routes/status/current_status.test.ts +++ b/x-pack/plugins/synthetics/server/routes/status/current_status.test.ts @@ -78,11 +78,18 @@ describe('current status route', () => { '@timestamp': '2022-09-15T16:08:16.724Z', monitor: { status: 'up', + id: 'id1', }, summary: { up: 1, down: 0, }, + config_id: 'id1', + observer: { + geo: { + name: 'test-location', + }, + }, }, }, ], @@ -106,11 +113,18 @@ describe('current status route', () => { '@timestamp': '2022-09-15T16:09:16.724Z', monitor: { status: 'up', + id: 'id2', }, summary: { up: 1, down: 0, }, + config_id: 'id2', + observer: { + geo: { + name: 'test-location', + }, + }, }, }, ], @@ -127,11 +141,18 @@ describe('current status route', () => { '@timestamp': '2022-09-15T16:19:16.724Z', monitor: { status: 'down', + id: 'id2', }, summary: { down: 1, up: 0, }, + config_id: 'id2', + observer: { + geo: { + name: 'test-location', + }, + }, }, }, ], @@ -146,6 +167,25 @@ describe('current status route', () => { expect(await queryMonitorStatus(uptimeEsClient, 3, 140000, ['id1', 'id2'])).toEqual({ down: 1, up: 2, + upConfigs: [ + { + configId: 'id1', + heartbeatId: 'id1', + location: 'test-location', + }, + { + configId: 'id2', + heartbeatId: 'id2', + location: 'test-location', + }, + ], + downConfigs: [ + { + configId: 'id2', + heartbeatId: 'id2', + location: 'test-location', + }, + ], }); }); @@ -167,11 +207,18 @@ describe('current status route', () => { '@timestamp': '2022-09-15T16:08:16.724Z', monitor: { status: 'up', + id: 'id1', }, summary: { up: 1, down: 0, }, + config_id: 'id1', + observer: { + geo: { + name: 'test-location', + }, + }, }, }, ], @@ -195,11 +242,18 @@ describe('current status route', () => { '@timestamp': '2022-09-15T16:09:16.724Z', monitor: { status: 'up', + id: 'id2', }, summary: { up: 1, down: 0, }, + config_id: 'id2', + observer: { + geo: { + name: 'test-location', + }, + }, }, }, ], @@ -216,11 +270,18 @@ describe('current status route', () => { '@timestamp': '2022-09-15T16:19:16.724Z', monitor: { status: 'down', + id: 'id2', }, summary: { up: 0, down: 1, }, + config_id: 'id2', + observer: { + geo: { + name: 'test-location', + }, + }, }, }, ], @@ -242,6 +303,25 @@ describe('current status route', () => { expect(await queryMonitorStatus(uptimeEsClient, 10000, 2500, ['id1', 'id2'])).toEqual({ down: 1, up: 2, + upConfigs: [ + { + configId: 'id1', + heartbeatId: 'id1', + location: 'test-location', + }, + { + configId: 'id2', + heartbeatId: 'id2', + location: 'test-location', + }, + ], + downConfigs: [ + { + configId: 'id2', + heartbeatId: 'id2', + location: 'test-location', + }, + ], }); expect(esClient.search).toHaveBeenCalledTimes(2); // These assertions are to ensure that we are paginating through the IDs we use for filtering diff --git a/x-pack/plugins/synthetics/server/routes/status/current_status.ts b/x-pack/plugins/synthetics/server/routes/status/current_status.ts index 0de4de69776af..5770ab5b9d625 100644 --- a/x-pack/plugins/synthetics/server/routes/status/current_status.ts +++ b/x-pack/plugins/synthetics/server/routes/status/current_status.ts @@ -15,7 +15,7 @@ import { SyntheticsRestApiRouteFactory } from '../../legacy_uptime/routes'; import { getMonitors } from '../common'; import { UptimeEsClient } from '../../legacy_uptime/lib/lib'; import { SyntheticsMonitorClient } from '../../synthetics_service/synthetics_monitor/synthetics_monitor_client'; -import { ConfigKey, OverviewStatus } from '../../../common/runtime_types'; +import { ConfigKey, OverviewStatus, OverviewStatusMetaData } from '../../../common/runtime_types'; /** * Helper function that converts a monitor's schedule to a value to use to generate @@ -36,7 +36,7 @@ export async function queryMonitorStatus( maxLocations: number, maxPeriod: number, ids: Array -): Promise> { +): Promise> { const idSize = Math.trunc(DEFAULT_MAX_ES_BUCKET_SIZE / maxLocations); const pageCount = Math.ceil(ids.length / idSize); const promises: Array> = []; @@ -92,7 +92,7 @@ export async function queryMonitorStatus( }, ], _source: { - includes: ['@timestamp', 'summary'], + includes: ['@timestamp', 'summary', 'monitor', 'observer', 'config_id'], }, }, }, @@ -107,20 +107,35 @@ export async function queryMonitorStatus( } let up = 0; let down = 0; + const upConfigs: OverviewStatusMetaData[] = []; + const downConfigs: OverviewStatusMetaData[] = []; for await (const response of promises) { response.aggregations?.id.buckets.forEach(({ location }: { key: string; location: any }) => { location.buckets.forEach(({ status }: { key: string; status: any }) => { const downCount = status.hits.hits[0]._source.summary.down; const upCount = status.hits.hits[0]._source.summary.up; + const configId = status.hits.hits[0]._source.config_id; + const heartbeatId = status.hits.hits[0]._source.monitor.id; + const locationName = status.hits.hits[0]._source.observer?.geo?.name; if (upCount > 0) { up += 1; + upConfigs.push({ + configId, + heartbeatId, + location: locationName, + }); } else if (downCount > 0) { down += 1; + downConfigs.push({ + configId, + heartbeatId, + location: locationName, + }); } }); }); } - return { up, down }; + return { up, down, upConfigs, downConfigs }; } /** @@ -169,7 +184,7 @@ export async function getStatus( }); } while (monitors.saved_objects.length === monitors.per_page); - const { up, down } = await queryMonitorStatus( + const { up, down, upConfigs, downConfigs } = await queryMonitorStatus( uptimeEsClient, maxLocations, maxPeriod, @@ -180,6 +195,8 @@ export async function getStatus( disabledCount, up, down, + upConfigs, + downConfigs, }; } diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 0a57b7c651d19..28b01bd81281a 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -31216,7 +31216,6 @@ "xpack.synthetics.overview.heading": "Moniteurs", "xpack.synthetics.overview.monitors.label": "Moniteurs", "xpack.synthetics.overview.pageHeader.title": "Aperçu", - "xpack.synthetics.overview.pagination.ariaLabel": "Pagination pour l’aperçu du moniteur", "xpack.synthetics.overviewPage.overviewCrumb": "Aperçu", "xpack.synthetics.overviewPageLink.disabled.ariaLabel": "Bouton de pagination désactivé indiquant qu'aucune autre navigation ne peut être effectuée dans la liste des moniteurs.", "xpack.synthetics.overviewPageLink.next.ariaLabel": "Page de résultats suivante", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 0b4d191d99bcf..4f2f30e3e1fdb 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -31192,7 +31192,6 @@ "xpack.synthetics.overview.heading": "監視", "xpack.synthetics.overview.monitors.label": "監視", "xpack.synthetics.overview.pageHeader.title": "概要", - "xpack.synthetics.overview.pagination.ariaLabel": "監視概要のページネーション", "xpack.synthetics.overviewPage.overviewCrumb": "概要", "xpack.synthetics.overviewPageLink.disabled.ariaLabel": "無効になったページ付けボタンです。モニターリストがこれ以上ナビゲーションできないことを示しています。", "xpack.synthetics.overviewPageLink.next.ariaLabel": "次の結果ページ", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index a44380c72b813..c11034dbc5b93 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -31227,7 +31227,6 @@ "xpack.synthetics.overview.heading": "监测", "xpack.synthetics.overview.monitors.label": "监测", "xpack.synthetics.overview.pageHeader.title": "概览", - "xpack.synthetics.overview.pagination.ariaLabel": "监测概述的分页", "xpack.synthetics.overviewPage.overviewCrumb": "概览", "xpack.synthetics.overviewPageLink.disabled.ariaLabel": "禁用的分页按钮表示在监测列表中无法进行进一步导航。", "xpack.synthetics.overviewPageLink.next.ariaLabel": "下页结果", diff --git a/x-pack/test/api_integration/apis/synthetics/get_monitor_overview.ts b/x-pack/test/api_integration/apis/synthetics/get_monitor_overview.ts index ff690e0093f77..7477e4e48b3c1 100644 --- a/x-pack/test/api_integration/apis/synthetics/get_monitor_overview.ts +++ b/x-pack/test/api_integration/apis/synthetics/get_monitor_overview.ts @@ -82,33 +82,7 @@ export default function ({ getService }: FtrProviderContext) { expect(apiResponse.body.allMonitorIds.sort()).eql( savedMonitors.map((monitor) => monitor.id).sort() ); - expect(apiResponse.body.pages).to.have.keys(['0', '1']); - expect(apiResponse.body.pages[1].length).eql(20); - } finally { - await Promise.all( - savedMonitors.map((monitor) => { - return deleteMonitor(monitor.id); - }) - ); - } - }); - - it('adjusts pagination correctly', async () => { - let savedMonitors: SimpleSavedObject[] = []; - try { - const savedResponse = await Promise.all(monitors.map(saveMonitor)); - savedMonitors = savedResponse; - - const apiResponse = await supertest.get( - SYNTHETICS_API_URLS.SYNTHETICS_OVERVIEW + '?perPage=5' - ); - - expect(apiResponse.body.total).eql(monitors.length * 2); - expect(apiResponse.body.allMonitorIds.sort()).eql( - savedMonitors.map((monitor) => monitor.id).sort() - ); - expect(apiResponse.body.pages).to.have.keys(['0', '1', '2', '3', '4']); - expect(apiResponse.body.pages[1].length).eql(5); + expect(apiResponse.body.monitors.length).eql(40); } finally { await Promise.all( savedMonitors.map((monitor) => { diff --git a/yarn.lock b/yarn.lock index cbed8a4c3432c..9a7142b7d14db 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1297,17 +1297,12 @@ resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== -"@cspotcode/source-map-consumer@0.8.0": - version "0.8.0" - resolved "https://registry.yarnpkg.com/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz#33bf4b7b39c178821606f669bbc447a6a629786b" - integrity sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg== - -"@cspotcode/source-map-support@0.7.0": - version "0.7.0" - resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz#4789840aa859e46d2f3173727ab707c66bf344f5" - integrity sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA== +"@cspotcode/source-map-support@^0.8.0", "@cspotcode/source-map-support@^0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" + integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== dependencies: - "@cspotcode/source-map-consumer" "0.8.0" + "@jridgewell/trace-mapping" "0.3.9" "@csstools/selector-specificity@^2.0.1": version "2.0.1" @@ -1658,24 +1653,31 @@ history "^4.9.0" qs "^6.7.0" -"@elastic/synthetics@^1.0.0-beta.22": - version "1.0.0-beta.22" - resolved "https://registry.yarnpkg.com/@elastic/synthetics/-/synthetics-1.0.0-beta.22.tgz#1ec60e212e925ffaf7fd63619858ad6ce6dfa85d" - integrity sha512-hDFPqBuY30naAZct8UNRMhKNtsVbPV5nYApkwRf/7y3/SgQBXPnMkxUBlxy+2vkPR4QnKusvWROUxMMwgVnXyA== +"@elastic/synthetics@^1.0.0-beta.23": + version "1.0.0-beta.37" + resolved "https://registry.yarnpkg.com/@elastic/synthetics/-/synthetics-1.0.0-beta.37.tgz#ba89918107c7aa166bcf43bbd0cbe4ad6a3b4430" + integrity sha512-MSYu+n4SuZ31AbxWpha5WBS33Y/YTVEvOc8g3WkCIxSqa8iSAPgGEAOZimk/pHOzPZNXJcRKIpL01HnKvqd14g== dependencies: - commander "^9.0.0" + "@cspotcode/source-map-support" "^0.8.1" + "@esbuild-plugins/node-resolve" "^0.1.4" + archiver "^5.3.1" + commander "^9.4.0" deepmerge "^4.2.2" - expect "^27.0.2" + enquirer "^2.3.6" + esbuild "^0.14.54" + expect "^28.1.3" http-proxy "^1.18.1" - kleur "^4.1.4" - micromatch "^4.0.4" - playwright-chromium "=1.14.0" - sharp "^0.30.1" - snakecase-keys "^3.2.1" - sonic-boom "^2.6.0" - source-map-support "^0.5.21" - ts-node "^10.5.0" - typescript "^4.5.5" + kleur "^4.1.5" + micromatch "^4.0.5" + playwright-chromium "=1.26.0" + playwright-core "=1.26.0" + sharp "^0.31.1" + snakecase-keys "^4.0.0" + sonic-boom "^3.2.0" + ts-node "^10.9.1" + typescript "^4.8.3" + undici "^5.10.0" + yaml "^2.1.1" "@elastic/transport@^8.2.0": version "8.2.0" @@ -1919,6 +1921,21 @@ resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz#ea89004119dc42db2e1dba0f97d553f7372f6fcb" integrity sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg== +"@esbuild-plugins/node-resolve@^0.1.4": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@esbuild-plugins/node-resolve/-/node-resolve-0.1.4.tgz#2257ef3b233c9cb3acd2ebde7d5a3d6874046d38" + integrity sha512-haFQ0qhxEpqtWWY0kx1Y5oE3sMyO1PcoSiWEPrAw6tm/ZOOLXjSs6Q+v1v9eyuVF0nNt50YEvrcrvENmyoMv5g== + dependencies: + "@types/resolve" "^1.17.1" + debug "^4.3.1" + escape-string-regexp "^4.0.0" + resolve "^1.19.0" + +"@esbuild/linux-loong64@0.14.54": + version "0.14.54" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz#de2a4be678bd4d0d1ffbb86e6de779cde5999028" + integrity sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw== + "@eslint/eslintrc@^0.4.3": version "0.4.3" resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c" @@ -2403,6 +2420,13 @@ dependencies: jest-get-type "^28.0.2" +"@jest/expect-utils@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-28.1.3.tgz#58561ce5db7cd253a7edddbc051fb39dda50f525" + integrity sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA== + dependencies: + jest-get-type "^28.0.2" + "@jest/fake-timers@^27.5.1": version "27.5.1" resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.5.1.tgz#76979745ce0579c8a94a4678af7a748eda8ada74" @@ -2462,6 +2486,13 @@ dependencies: "@sinclair/typebox" "^0.23.3" +"@jest/schemas@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-28.1.3.tgz#ad8b86a66f11f33619e3d7e1dcddd7f2d40ff905" + integrity sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg== + dependencies: + "@sinclair/typebox" "^0.24.1" + "@jest/source-map@^27.5.1": version "27.5.1" resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.5.1.tgz#6608391e465add4205eae073b55e7f279e04e8cf" @@ -2555,12 +2586,12 @@ "@types/yargs" "^16.0.0" chalk "^4.0.0" -"@jest/types@^28.1.1": - version "28.1.1" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-28.1.1.tgz#d059bbc80e6da6eda9f081f293299348bd78ee0b" - integrity sha512-vRXVqSg1VhDnB8bWcmvLzmg0Bt9CRKVgHPXqYwvWMX3TvAjeO+nRuK6+VdTKCtWOvYlmkF/HqNAL/z+N3B53Kw== +"@jest/types@^28.1.1", "@jest/types@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-28.1.3.tgz#b05de80996ff12512bc5ceb1d208285a7d11748b" + integrity sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ== dependencies: - "@jest/schemas" "^28.0.2" + "@jest/schemas" "^28.1.3" "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^3.0.0" "@types/node" "*" @@ -2599,6 +2630,14 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz#771a1d8d744eeb71b6adb35808e1a6c7b9b8c8ec" integrity sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg== +"@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping@^0.3.0", "@jridgewell/trace-mapping@^0.3.14", "@jridgewell/trace-mapping@^0.3.8", "@jridgewell/trace-mapping@^0.3.9": version "0.3.15" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz#aba35c48a38d3fd84b37e66c9c0423f9744f9774" @@ -4863,6 +4902,11 @@ resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.23.5.tgz#93f7b9f4e3285a7a9ade7557d9a8d36809cbc47d" integrity sha512-AFBVi/iT4g20DHoujvMH1aEDn8fGJh4xsRGCP6d8RpLPMqsNPvW01Jcn0QysXTsg++/xj25NmJsGyH9xug/wKg== +"@sinclair/typebox@^0.24.1": + version "0.24.46" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.46.tgz#57501b58023776dbbae9e25619146286440be34c" + integrity sha512-ng4ut1z2MCBhK/NwDVwIQp3pAUOCs/KNaW3cBxdFB2xTDrOuo1xuNmpr/9HHFhxqIvHrs1NTH3KJg6q+JSy1Kw== + "@sindresorhus/is@^0.14.0": version "0.14.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" @@ -7397,7 +7441,7 @@ resolved "https://registry.yarnpkg.com/@types/resize-observer-browser/-/resize-observer-browser-0.1.5.tgz#36d897708172ac2380cd486da7a3daf1161c1e23" integrity sha512-8k/67Z95Goa6Lznuykxkfhq9YU3l1Qe6LNZmwde1u7802a3x8v44oq0j91DICclxatTr0rNnhXx7+VTIetSrSQ== -"@types/resolve@^1.20.1": +"@types/resolve@^1.17.1", "@types/resolve@^1.20.1": version "1.20.1" resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.1.tgz#3727e48042fda81e374f5d5cf2fa92288bf698f8" integrity sha512-Ku5+GPFa12S3W26Uwtw+xyrtIpaZsGYHH6zxNbZlstmlvMYSZRzOwzwsXbxlVUbHyUucctSyuFtu6bNxwYomIw== @@ -9835,6 +9879,13 @@ builtin-status-codes@^3.0.0: resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= +busboy@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" + integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== + dependencies: + streamsearch "^1.1.0" + byte-size@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-8.1.0.tgz#6353d0bc14ab7a69abcefbf11f8db0145a862cb5" @@ -10655,20 +10706,15 @@ commander@^5.0.0, commander@^5.1.0: resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== -commander@^6.1.0, commander@^6.2.1: +commander@^6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== -commander@^8.2.0: - version "8.3.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" - integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== - -commander@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-9.0.0.tgz#86d58f24ee98126568936bd1d3574e0308a99a40" - integrity sha512-JJfP2saEKbQqvW+FI93OYUB4ByV5cizMpFMiiJI8xDbBvQvSkIk0VvQdn1CZ8mqAO8Loq2h0gYTYtDFUZUeERw== +commander@^9.4.0: + version "9.4.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-9.4.1.tgz#d1dd8f2ce6faf93147295c0df13c7c21141cfbdd" + integrity sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw== common-path-prefix@^3.0.0: version "3.0.0" @@ -12514,6 +12560,14 @@ dot-case@^3.0.3: no-case "^3.0.3" tslib "^1.10.0" +dot-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" + integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + dot-prop@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.2.0.tgz#c34ecc29556dc45f1f4c22697b6f4904e0cc4fcb" @@ -13078,6 +13132,133 @@ es6-weak-map@^2.0.2: es6-iterator "^2.0.1" es6-symbol "^3.1.1" +esbuild-android-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.14.54.tgz#505f41832884313bbaffb27704b8bcaa2d8616be" + integrity sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ== + +esbuild-android-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.54.tgz#8ce69d7caba49646e009968fe5754a21a9871771" + integrity sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg== + +esbuild-darwin-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.54.tgz#24ba67b9a8cb890a3c08d9018f887cc221cdda25" + integrity sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug== + +esbuild-darwin-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.54.tgz#3f7cdb78888ee05e488d250a2bdaab1fa671bf73" + integrity sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw== + +esbuild-freebsd-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.54.tgz#09250f997a56ed4650f3e1979c905ffc40bbe94d" + integrity sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg== + +esbuild-freebsd-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.54.tgz#bafb46ed04fc5f97cbdb016d86947a79579f8e48" + integrity sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q== + +esbuild-linux-32@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.54.tgz#e2a8c4a8efdc355405325033fcebeb941f781fe5" + integrity sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw== + +esbuild-linux-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.54.tgz#de5fdba1c95666cf72369f52b40b03be71226652" + integrity sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg== + +esbuild-linux-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.54.tgz#dae4cd42ae9787468b6a5c158da4c84e83b0ce8b" + integrity sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig== + +esbuild-linux-arm@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.54.tgz#a2c1dff6d0f21dbe8fc6998a122675533ddfcd59" + integrity sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw== + +esbuild-linux-mips64le@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.54.tgz#d9918e9e4cb972f8d6dae8e8655bf9ee131eda34" + integrity sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw== + +esbuild-linux-ppc64le@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.54.tgz#3f9a0f6d41073fb1a640680845c7de52995f137e" + integrity sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ== + +esbuild-linux-riscv64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.54.tgz#618853c028178a61837bc799d2013d4695e451c8" + integrity sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg== + +esbuild-linux-s390x@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.54.tgz#d1885c4c5a76bbb5a0fe182e2c8c60eb9e29f2a6" + integrity sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA== + +esbuild-netbsd-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.54.tgz#69ae917a2ff241b7df1dbf22baf04bd330349e81" + integrity sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w== + +esbuild-openbsd-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.54.tgz#db4c8495287a350a6790de22edea247a57c5d47b" + integrity sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw== + +esbuild-sunos-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.54.tgz#54287ee3da73d3844b721c21bc80c1dc7e1bf7da" + integrity sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw== + +esbuild-windows-32@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.54.tgz#f8aaf9a5667630b40f0fb3aa37bf01bbd340ce31" + integrity sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w== + +esbuild-windows-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.54.tgz#bf54b51bd3e9b0f1886ffdb224a4176031ea0af4" + integrity sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ== + +esbuild-windows-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.54.tgz#937d15675a15e4b0e4fafdbaa3a01a776a2be982" + integrity sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg== + +esbuild@^0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.54.tgz#8b44dcf2b0f1a66fc22459943dccf477535e9aa2" + integrity sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA== + optionalDependencies: + "@esbuild/linux-loong64" "0.14.54" + esbuild-android-64 "0.14.54" + esbuild-android-arm64 "0.14.54" + esbuild-darwin-64 "0.14.54" + esbuild-darwin-arm64 "0.14.54" + esbuild-freebsd-64 "0.14.54" + esbuild-freebsd-arm64 "0.14.54" + esbuild-linux-32 "0.14.54" + esbuild-linux-64 "0.14.54" + esbuild-linux-arm "0.14.54" + esbuild-linux-arm64 "0.14.54" + esbuild-linux-mips64le "0.14.54" + esbuild-linux-ppc64le "0.14.54" + esbuild-linux-riscv64 "0.14.54" + esbuild-linux-s390x "0.14.54" + esbuild-netbsd-64 "0.14.54" + esbuild-openbsd-64 "0.14.54" + esbuild-sunos-64 "0.14.54" + esbuild-windows-32 "0.14.54" + esbuild-windows-64 "0.14.54" + esbuild-windows-arm64 "0.14.54" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -13647,7 +13828,7 @@ expect@^26.6.2: jest-message-util "^26.6.2" jest-regex-util "^26.0.0" -expect@^27.0.2, expect@^27.5.1: +expect@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/expect/-/expect-27.5.1.tgz#83ce59f1e5bdf5f9d2b94b61d2050db48f3fef74" integrity sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw== @@ -13668,6 +13849,17 @@ expect@^28.1.1: jest-message-util "^28.1.1" jest-util "^28.1.1" +expect@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/expect/-/expect-28.1.3.tgz#90a7c1a124f1824133dd4533cce2d2bdcb6603ec" + integrity sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g== + dependencies: + "@jest/expect-utils" "^28.1.3" + jest-get-type "^28.0.2" + jest-matcher-utils "^28.1.3" + jest-message-util "^28.1.3" + jest-util "^28.1.3" + expiry-js@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/expiry-js/-/expiry-js-0.1.7.tgz#76be8c05e572bf936df40c1766448d0b3b2f555f" @@ -16921,6 +17113,16 @@ jest-diff@^28.1.1: jest-get-type "^28.0.2" pretty-format "^28.1.1" +jest-diff@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-28.1.3.tgz#948a192d86f4e7a64c5264ad4da4877133d8792f" + integrity sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw== + dependencies: + chalk "^4.0.0" + diff-sequences "^28.1.1" + jest-get-type "^28.0.2" + pretty-format "^28.1.3" + jest-docblock@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.5.1.tgz#14092f364a42c6108d42c33c8cf30e058e25f6c0" @@ -17091,6 +17293,16 @@ jest-matcher-utils@^28.1.1: jest-get-type "^28.0.2" pretty-format "^28.1.1" +jest-matcher-utils@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz#5a77f1c129dd5ba3b4d7fc20728806c78893146e" + integrity sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw== + dependencies: + chalk "^4.0.0" + jest-diff "^28.1.3" + jest-get-type "^28.0.2" + pretty-format "^28.1.3" + jest-message-util@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-26.6.2.tgz#58173744ad6fc0506b5d21150b9be56ef001ca07" @@ -17121,18 +17333,18 @@ jest-message-util@^27.5.1: slash "^3.0.0" stack-utils "^2.0.3" -jest-message-util@^28.1.1: - version "28.1.1" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-28.1.1.tgz#60aa0b475cfc08c8a9363ed2fb9108514dd9ab89" - integrity sha512-xoDOOT66fLfmTRiqkoLIU7v42mal/SqwDKvfmfiWAdJMSJiU+ozgluO7KbvoAgiwIrrGZsV7viETjc8GNrA/IQ== +jest-message-util@^28.1.1, jest-message-util@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-28.1.3.tgz#232def7f2e333f1eecc90649b5b94b0055e7c43d" + integrity sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g== dependencies: "@babel/code-frame" "^7.12.13" - "@jest/types" "^28.1.1" + "@jest/types" "^28.1.3" "@types/stack-utils" "^2.0.0" chalk "^4.0.0" graceful-fs "^4.2.9" micromatch "^4.0.4" - pretty-format "^28.1.1" + pretty-format "^28.1.3" slash "^3.0.0" stack-utils "^2.0.3" @@ -17389,6 +17601,18 @@ jest-util@^28.1.1: graceful-fs "^4.2.9" picomatch "^2.2.3" +jest-util@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-28.1.3.tgz#f4f932aa0074f0679943220ff9cbba7e497028b0" + integrity sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ== + dependencies: + "@jest/types" "^28.1.3" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + jest-validate@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.5.1.tgz#9197d54dc0bdb52260b8db40b46ae668e04df067" @@ -17462,11 +17686,6 @@ jpeg-js@^0.3.2: resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.3.7.tgz#471a89d06011640592d314158608690172b1028d" integrity sha512-9IXdWudL61npZjvLuVe/ktHiA41iE8qFyLB+4VDTblEsWBzeg8WQTlktdUK4CdncUqtUgUg0bbOmTE2bKBKaBQ== -jpeg-js@^0.4.2: - version "0.4.3" - resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.4.3.tgz#6158e09f1983ad773813704be80680550eff977b" - integrity sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q== - jquery@^3.5.0: version "3.6.0" resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.6.0.tgz#c72a09f15c1bdce142f49dbf1170bdf8adac2470" @@ -17864,10 +18083,10 @@ kleur@^3.0.3: resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== -kleur@^4.1.4: - version "4.1.4" - resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.4.tgz#8c202987d7e577766d039a8cd461934c01cda04d" - integrity sha512-8QADVssbrFjivHWQU7KkMgptGTl6WAcSdlbBPY4uNF+mWr6DGcKrvY2w4FQJoXch7+fKMjj0dRrL75vk3k23OA== +kleur@^4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.5.tgz#95106101795f7050c6c650f350c683febddb1780" + integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ== klona@^2.0.4: version "2.0.4" @@ -18460,6 +18679,13 @@ lower-case@^2.0.1: dependencies: tslib "^1.10.0" +lower-case@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" + integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== + dependencies: + tslib "^2.0.3" + lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" @@ -19099,7 +19325,7 @@ mime@1.6.0, mime@^1.4.1: resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== -mime@^2.4.4, mime@^2.4.6: +mime@^2.4.4: version "2.5.2" resolved "https://registry.yarnpkg.com/mime/-/mime-2.5.2.tgz#6e3dc6cc2b9510643830e5f19d5cb753da5eeabe" integrity sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg== @@ -19660,6 +19886,14 @@ no-case@^3.0.3: lower-case "^2.0.1" tslib "^1.10.0" +no-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" + integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== + dependencies: + lower-case "^2.0.2" + tslib "^2.0.3" + nock@12.0.3: version "12.0.3" resolved "https://registry.yarnpkg.com/nock/-/nock-12.0.3.tgz#83f25076dbc4c9aa82b5cdf54c9604c7a778d1c9" @@ -20979,54 +21213,29 @@ platform@^1.3.0: resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.5.tgz#fb6958c696e07e2918d2eeda0f0bc9448d733444" integrity sha512-TuvHS8AOIZNAlE77WUDiR4rySV/VMptyMfcfeoMgs4P8apaZM3JrnbzBiixKUv+XR6i+BXrQh8WAnjaSPFO65Q== -playwright-chromium@=1.14.0: - version "1.14.0" - resolved "https://registry.yarnpkg.com/playwright-chromium/-/playwright-chromium-1.14.0.tgz#b153eb96412fd6a4fa8d9233a4fdf694fc9f3139" - integrity sha512-qWQN9VTPhvEZdRpn1564EOtiNU+hRHhogKg1heBX9VsfGy6WHytR9XPFJjD4M6fhNAV1WKM2McVPYIbi1EOYww== +playwright-chromium@=1.26.0: + version "1.26.0" + resolved "https://registry.yarnpkg.com/playwright-chromium/-/playwright-chromium-1.26.0.tgz#fa4e75a2034a016b9e2e825fc6577f3efb0d2792" + integrity sha512-4hDiVmMKmtuHW5ne11S1HCQTdL+wytprQMhWYecEjMSIKBR1DJ3JLrcUDgqA0L5Jzi/CBKYQQk6TOVlTjXybXQ== dependencies: - commander "^6.1.0" - debug "^4.1.1" - extract-zip "^2.0.1" - https-proxy-agent "^5.0.0" - jpeg-js "^0.4.2" - mime "^2.4.6" - pngjs "^5.0.0" - progress "^2.0.3" - proper-lockfile "^4.1.1" - proxy-from-env "^1.1.0" - rimraf "^3.0.2" - stack-utils "^2.0.3" - ws "^7.4.6" - yazl "^2.5.1" + playwright-core "1.26.0" -playwright-core@=1.17.1: - version "1.17.1" - resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.17.1.tgz#a16e0f89284a0ed8ae6d77e1c905c84b8a2ba022" - integrity sha512-C3c8RpPiC3qr15fRDN6dx6WnUkPLFmST37gms2aoHPDRvp7EaGDPMMZPpqIm/QWB5J40xDrQCD4YYHz2nBTojQ== - dependencies: - commander "^8.2.0" - debug "^4.1.1" - extract-zip "^2.0.1" - https-proxy-agent "^5.0.0" - jpeg-js "^0.4.2" - mime "^2.4.6" - pngjs "^5.0.0" - progress "^2.0.3" - proper-lockfile "^4.1.1" - proxy-from-env "^1.1.0" - rimraf "^3.0.2" - socks-proxy-agent "^6.1.0" - stack-utils "^2.0.3" - ws "^7.4.6" - yauzl "^2.10.0" - yazl "^2.5.1" +playwright-core@1.26.0, playwright-core@=1.26.0: + version "1.26.0" + resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.26.0.tgz#850228f0638d410a5cdd69800d552f60e4d295cd" + integrity sha512-p8huU8eU4gD3VkJd3DA1nA7R3XA6rFvFL+1RYS96cSljCF2yJE9CWEHTPF4LqX8KN9MoWCrAfVKP5381X3CZqg== + +playwright-core@1.27.1: + version "1.27.1" + resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.27.1.tgz#840ef662e55a3ed759d8b5d3d00a5f885a7184f4" + integrity sha512-9EmeXDncC2Pmp/z+teoVYlvmPWUC6ejSSYZUln7YaP89Z6lpAaiaAnqroUt/BoLo8tn7WYShcfaCh+xofZa44Q== -playwright@^1.17.1: - version "1.17.1" - resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.17.1.tgz#a6d63302ee40f41283c4bf869de261c4743a787c" - integrity sha512-DisCkW9MblDJNS3rG61p8LiLA2WA7IY/4A4W7DX4BphWe/HuWjKmGQptuk4NVIh5UuSwXpW/jaH2+ZgjHs3GMA== +playwright@^1.26.0: + version "1.27.1" + resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.27.1.tgz#4eecac5899566c589d4220ca8acc16abe8a67450" + integrity sha512-xXYZ7m36yTtC+oFgqH0eTgullGztKSRMb4yuwLPl8IYSmgBM88QiB+3IWb1mRIC9/NNwcgbG0RwtFlg+EAFQHQ== dependencies: - playwright-core "=1.17.1" + playwright-core "1.27.1" plugin-error@^1.0.1: version "1.0.1" @@ -21065,11 +21274,6 @@ pngjs@^3.3.3, pngjs@^3.4.0: resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f" integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w== -pngjs@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-5.0.0.tgz#e79dd2b215767fd9c04561c01236df960bce7fbb" - integrity sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw== - pngjs@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-6.0.0.tgz#ca9e5d2aa48db0228a52c419c3308e87720da821" @@ -21521,6 +21725,16 @@ pretty-format@^28.1.1: ansi-styles "^5.0.0" react-is "^18.0.0" +pretty-format@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-28.1.3.tgz#c9fba8cedf99ce50963a11b27d982a9ae90970d5" + integrity sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q== + dependencies: + "@jest/schemas" "^28.1.3" + ansi-regex "^5.0.1" + ansi-styles "^5.0.0" + react-is "^18.0.0" + pretty-format@^3.8.0: version "3.8.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-3.8.0.tgz#bfbed56d5e9a776645f4b1ff7aa1a3ac4fa3c385" @@ -21572,7 +21786,7 @@ process@^0.11.10: resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= -progress@2.0.3, progress@^2.0.0, progress@^2.0.3: +progress@2.0.3, progress@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== @@ -21657,15 +21871,6 @@ propagate@^2.0.0: resolved "https://registry.yarnpkg.com/propagate/-/propagate-2.0.1.tgz#40cdedab18085c792334e64f0ac17256d38f9a45" integrity sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag== -proper-lockfile@^4.1.1: - version "4.1.2" - resolved "https://registry.yarnpkg.com/proper-lockfile/-/proper-lockfile-4.1.2.tgz#c8b9de2af6b2f1601067f98e01ac66baa223141f" - integrity sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA== - dependencies: - graceful-fs "^4.2.4" - retry "^0.12.0" - signal-exit "^3.0.2" - property-information@^5.0.0, property-information@^5.0.1, property-information@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/property-information/-/property-information-5.5.0.tgz#4dc075d493061a82e2b7d096f406e076ed859943" @@ -23990,10 +24195,10 @@ shallowequal@^1.1.0: resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8" integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ== -sharp@^0.30.1: - version "0.30.7" - resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.30.7.tgz#7862bda98804fdd1f0d5659c85e3324b90d94c7c" - integrity sha512-G+MY2YW33jgflKPTXXptVO28HvNOo9G3j0MybYAHeEmby+QuD2U98dT6ueht9cv/XDqZspSpIhoSW+BAKJ7Hig== +sharp@^0.31.1: + version "0.31.1" + resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.31.1.tgz#b2f7076d381a120761aa93700cadefcf90a22458" + integrity sha512-GR8M1wBwOiFKLkm9JPun27OQnNRZdHfSf9VwcdZX6UrRmM1/XnOrLFTF0GAil+y/YK4E6qcM/ugxs80QirsHxg== dependencies: color "^4.2.3" detect-libc "^2.0.1" @@ -24147,13 +24352,21 @@ smart-buffer@^4.1.0: resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== -snakecase-keys@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/snakecase-keys/-/snakecase-keys-3.2.1.tgz#ce5d1a2de8a93c939d7992f76f2743aa59f3d5ad" - integrity sha512-CjU5pyRfwOtaOITYv5C8DzpZ8XA/ieRsDpr93HI2r6e3YInC6moZpSQbmUtg8cTk58tq2x3jcG2gv+p1IZGmMA== +snake-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-3.0.4.tgz#4f2bbd568e9935abdfd593f34c691dadb49c452c" + integrity sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg== + dependencies: + dot-case "^3.0.4" + tslib "^2.0.3" + +snakecase-keys@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/snakecase-keys/-/snakecase-keys-4.0.2.tgz#72e28112b77753a68a4eeb110efec05ab391e190" + integrity sha512-ZFCo3zZtNN43cy2j4fQDHPxS557Uuzn887FBmDdaSB41D8l/MayuvaSrIlCXGFhZ8sXwrHiNaZiIPpKzi88gog== dependencies: map-obj "^4.1.0" - to-snake-case "^1.0.0" + snake-case "^3.0.4" snap-shot-compare@2.8.3: version "2.8.3" @@ -24218,7 +24431,7 @@ sockjs@^0.3.24: uuid "^8.3.2" websocket-driver "^0.7.4" -socks-proxy-agent@^6.0.0, socks-proxy-agent@^6.1.0: +socks-proxy-agent@^6.0.0: version "6.1.1" resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-6.1.1.tgz#e664e8f1aaf4e1fb3df945f09e3d94f911137f87" integrity sha512-t8J0kG3csjA4g6FTbsMOWws+7R7vuRC8aQ/wy3/1OWmsgwA68zs/+cExQ0koSitUDXqhufF/YJr9wtNMZHw5Ew== @@ -24243,10 +24456,10 @@ sonic-boom@^1.0.2: atomic-sleep "^1.0.0" flatstr "^1.0.12" -sonic-boom@^2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-2.6.0.tgz#8786fc78be07c18a90381acd816d1d4afe3537a2" - integrity sha512-6xYZFRmDEtxGqfOKcDQ4cPLrNa0SPEDI+wlzDAHowXE6YV42NeXqg9mP2KkiM8JVu3lHfZ2iQKYlGOz+kTpphg== +sonic-boom@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-3.2.0.tgz#ce9f2de7557e68be2e52c8df6d9b052e7d348143" + integrity sha512-SbbZ+Kqj/XIunvIAgUZRlqd6CGQYq71tRRbXR92Za8J/R3Yh4Av+TWENiSiEgnlwckYLyP0YZQWVfyNC0dzLaA== dependencies: atomic-sleep "^1.0.0" @@ -24296,7 +24509,7 @@ source-map-support@0.5.9: buffer-from "^1.0.0" source-map "^0.6.0" -source-map-support@^0.5.16, source-map-support@^0.5.19, source-map-support@^0.5.20, source-map-support@^0.5.21, source-map-support@^0.5.6, source-map-support@~0.5.12, source-map-support@~0.5.20: +source-map-support@^0.5.16, source-map-support@^0.5.19, source-map-support@^0.5.20, source-map-support@^0.5.6, source-map-support@~0.5.12, source-map-support@~0.5.20: version "0.5.21" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== @@ -24685,6 +24898,11 @@ stream-to-async-iterator@^0.2.0: resolved "https://registry.yarnpkg.com/stream-to-async-iterator/-/stream-to-async-iterator-0.2.0.tgz#bef5c885e9524f98b2fa5effecc357bd58483780" integrity sha1-vvXIhelST5iy+l7/7MNXvVhIN4A= +streamsearch@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" + integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== + strict-uri-encode@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" @@ -25608,13 +25826,6 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" -to-snake-case@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/to-snake-case/-/to-snake-case-1.0.0.tgz#ce746913897946019a87e62edfaeaea4c608ab8c" - integrity sha1-znRpE4l5RgGah+Yu366upMYIq4w= - dependencies: - to-space-case "^1.0.0" - to-source-code@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/to-source-code/-/to-source-code-1.0.2.tgz#dd136bdb1e1dbd80bbeacf088992678e9070bfea" @@ -25788,12 +25999,12 @@ ts-morph@^13.0.2: "@ts-morph/common" "~0.12.2" code-block-writer "^11.0.0" -ts-node@^10.5.0: - version "10.7.0" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.7.0.tgz#35d503d0fab3e2baa672a0e94f4b40653c2463f5" - integrity sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A== +ts-node@^10.9.1: + version "10.9.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" + integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== dependencies: - "@cspotcode/source-map-support" "0.7.0" + "@cspotcode/source-map-support" "^0.8.0" "@tsconfig/node10" "^1.0.7" "@tsconfig/node12" "^1.0.7" "@tsconfig/node14" "^1.0.0" @@ -25804,7 +26015,7 @@ ts-node@^10.5.0: create-require "^1.1.0" diff "^4.0.1" make-error "^1.1.1" - v8-compile-cache-lib "^3.0.0" + v8-compile-cache-lib "^3.0.1" yn "3.1.1" ts-pnp@^1.1.6: @@ -25976,7 +26187,7 @@ typescript-tuple@^2.2.1: dependencies: typescript-compare "^0.0.2" -typescript@4.6.3, typescript@^3.3.3333, typescript@^3.5.3, typescript@^4.5.5: +typescript@4.6.3, typescript@^3.3.3333, typescript@^3.5.3, typescript@^4.8.3: version "4.6.3" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.3.tgz#eefeafa6afdd31d725584c67a0eaba80f6fc6c6c" integrity sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw== @@ -26029,6 +26240,13 @@ undici@^5.1.1: resolved "https://registry.yarnpkg.com/undici/-/undici-5.8.2.tgz#071fc8a6a5d24db0ad510ad442f607d9b09d5eec" integrity sha512-3KLq3pXMS0Y4IELV045fTxqz04Nk9Ms7yfBBHum3yxsTR4XNn+ZCaUbf/mWitgYDAhsplQ0B1G4S5D345lMO3A== +undici@^5.10.0: + version "5.11.0" + resolved "https://registry.yarnpkg.com/undici/-/undici-5.11.0.tgz#1db25f285821828fc09d3804b9e2e934ae86fc13" + integrity sha512-oWjWJHzFet0Ow4YZBkyiJwiK5vWqEYoH7BINzJAJOLedZ++JpAlCbUktW2GQ2DS2FpKmxD/JMtWUUWl1BtghGw== + dependencies: + busboy "^1.6.0" + unfetch@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/unfetch/-/unfetch-4.2.0.tgz#7e21b0ef7d363d8d9af0fb929a5555f6ef97a3be" @@ -26519,10 +26737,10 @@ uuid@^8.3.0, uuid@^8.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== -v8-compile-cache-lib@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz#0582bcb1c74f3a2ee46487ceecf372e46bce53e8" - integrity sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA== +v8-compile-cache-lib@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" + integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== v8-compile-cache@^2.0.3, v8-compile-cache@^2.3.0: version "2.3.0" @@ -27764,6 +27982,11 @@ yaml@^1.10.0, yaml@^1.10.2, yaml@^1.7.2: resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== +yaml@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.1.3.tgz#9b3a4c8aff9821b696275c79a8bee8399d945207" + integrity sha512-AacA8nRULjKMX2DvWvOAdBZMOfQlypSFkjcOcu9FalllIDJ1kvlREzcdIZmidQUqqeMv7jorHjq2HlLv/+c2lg== + yargs-parser@20.2.4, yargs-parser@^20.2.2, yargs-parser@^20.2.3: version "20.2.4" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54"