From 0370f6b5d4b5b97013291147ec6254c3ed0d1a92 Mon Sep 17 00:00:00 2001 From: Tim Sullivan Date: Tue, 2 Feb 2021 13:32:37 -0700 Subject: [PATCH 1/5] [SearchSource] Deserialize query string options for serverside ES Query (#90050) * [SearchSource] Deserialize query string options for serverside ES Query * fix test --- .../es_query/es_query/decorate_query.test.ts | 7 ++++++ .../es_query/es_query/decorate_query.ts | 8 ++++++- .../buckets/create_filter/filters.test.ts | 24 +++++++++++++++++++ .../test_helpers/mock_agg_types_registry.ts | 1 + 4 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/plugins/data/common/es_query/es_query/decorate_query.test.ts b/src/plugins/data/common/es_query/es_query/decorate_query.test.ts index 68d8b875c353..eb08af5269fc 100644 --- a/src/plugins/data/common/es_query/es_query/decorate_query.test.ts +++ b/src/plugins/data/common/es_query/es_query/decorate_query.test.ts @@ -22,6 +22,13 @@ describe('Query decorator', () => { expect(decoratedQuery).toEqual({ query_string: { query: '*', analyze_wildcard: true } }); }); + test('should merge in serialized query string options', () => { + const queryStringOptions = '{ "analyze_wildcard": true }'; + const decoratedQuery = decorateQuery({ query_string: { query: '*' } }, queryStringOptions); + + expect(decoratedQuery).toEqual({ query_string: { query: '*', analyze_wildcard: true } }); + }); + test('should add a default of a time_zone parameter if one is provided', () => { const decoratedQuery = decorateQuery( { query_string: { query: '*' } }, diff --git a/src/plugins/data/common/es_query/es_query/decorate_query.ts b/src/plugins/data/common/es_query/es_query/decorate_query.ts index 501c61485936..b71cebdd21c9 100644 --- a/src/plugins/data/common/es_query/es_query/decorate_query.ts +++ b/src/plugins/data/common/es_query/es_query/decorate_query.ts @@ -20,10 +20,16 @@ import { DslQuery, isEsQueryString } from './es_query_dsl'; export function decorateQuery( query: DslQuery, - queryStringOptions: Record, + queryStringOptions: Record | string, dateFormatTZ?: string ) { if (isEsQueryString(query)) { + // NOTE queryStringOptions comes from UI Settings and, in server context, is a serialized string + // https://github.com/elastic/kibana/issues/89902 + if (typeof queryStringOptions === 'string') { + queryStringOptions = JSON.parse(queryStringOptions); + } + extend(query.query_string, queryStringOptions); if (dateFormatTZ) { defaults(query.query_string, { diff --git a/src/plugins/data/common/search/aggs/buckets/create_filter/filters.test.ts b/src/plugins/data/common/search/aggs/buckets/create_filter/filters.test.ts index ffdd68f7e73a..1eddfc151606 100644 --- a/src/plugins/data/common/search/aggs/buckets/create_filter/filters.test.ts +++ b/src/plugins/data/common/search/aggs/buckets/create_filter/filters.test.ts @@ -51,6 +51,30 @@ describe('AggConfig Filters', () => { const aggConfigs = getAggConfigs(); const filter = createFilterFilters(aggConfigs.aggs[0] as IBucketAggConfig, 'type:nginx'); + expect(filter).toMatchInlineSnapshot(` + Object { + "meta": Object { + "alias": "type:nginx", + "index": "1234", + }, + "query": Object { + "bool": Object { + "filter": Array [], + "must": Array [ + Object { + "query_string": Object { + "query": "type:nginx", + "time_zone": "dateFormat:tz", + }, + }, + ], + "must_not": Array [], + "should": Array [], + }, + }, + } + `); + expect(filter!.query.bool.must[0].query_string.query).toBe('type:nginx'); expect(filter!.meta).toHaveProperty('index', '1234'); expect(filter!.meta).toHaveProperty('alias', 'type:nginx'); diff --git a/src/plugins/data/common/search/aggs/test_helpers/mock_agg_types_registry.ts b/src/plugins/data/common/search/aggs/test_helpers/mock_agg_types_registry.ts index 096654eb4bbb..752d840549d4 100644 --- a/src/plugins/data/common/search/aggs/test_helpers/mock_agg_types_registry.ts +++ b/src/plugins/data/common/search/aggs/test_helpers/mock_agg_types_registry.ts @@ -26,6 +26,7 @@ const mockGetConfig = jest.fn().mockImplementation((key: string) => { ['P1DT', 'YYYY-MM-DD'], ['P1YT', 'YYYY'], ], + 'query:queryString:options': {}, }; return config[key] ?? key; }); From 5f64e672c8f56860a30e3a853c545e1a9fe3785c Mon Sep 17 00:00:00 2001 From: Chris Roberson Date: Tue, 2 Feb 2021 15:33:25 -0500 Subject: [PATCH 2/5] [Monitoring] Avoid spamming toast messages (#89930) * Toast should only show once * Handle any errors here gracefully * Set this early to avoid failing test Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../plugins/monitoring/public/services/clusters.js | 7 ++----- .../lib/alerts/disable_watcher_cluster_alerts.ts | 13 ++++++++++--- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/monitoring/public/services/clusters.js b/x-pack/plugins/monitoring/public/services/clusters.js index e94bf990b090..3475eb8f51ba 100644 --- a/x-pack/plugins/monitoring/public/services/clusters.js +++ b/x-pack/plugins/monitoring/public/services/clusters.js @@ -22,7 +22,6 @@ function formatCluster(cluster) { } let once = false; -let inTransit = false; export function monitoringClustersProvider($injector) { return async (clusterUuid, ccs, codePaths) => { @@ -88,18 +87,16 @@ export function monitoringClustersProvider($injector) { } } - if (!once && !inTransit) { - inTransit = true; + if (!once) { + once = true; const clusters = await getClusters(); if (clusters.length) { try { const [{ data }] = await Promise.all([ensureAlertsEnabled(), ensureMetricbeatEnabled()]); showAlertsToast(data); - once = true; } catch (_err) { // Intentionally swallow the error as this will retry the next page load } - inTransit = false; } return clusters; } diff --git a/x-pack/plugins/monitoring/server/lib/alerts/disable_watcher_cluster_alerts.ts b/x-pack/plugins/monitoring/server/lib/alerts/disable_watcher_cluster_alerts.ts index 5dc0b6d0faaa..e36bd3d488a3 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/disable_watcher_cluster_alerts.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/disable_watcher_cluster_alerts.ts @@ -20,12 +20,19 @@ interface DisableWatchesResponse { >; } -async function callMigrationApi(callCluster: LegacyAPICaller) { - return await callCluster('monitoring.disableWatches'); +async function callMigrationApi(callCluster: LegacyAPICaller, logger: Logger) { + try { + return await callCluster('monitoring.disableWatches'); + } catch (err) { + logger.warn( + `Unable to call migration api to disable cluster alert watches. Message=${err.message}` + ); + return undefined; + } } export async function disableWatcherClusterAlerts(callCluster: LegacyAPICaller, logger: Logger) { - const response: DisableWatchesResponse = await callMigrationApi(callCluster); + const response: DisableWatchesResponse = await callMigrationApi(callCluster, logger); if (!response || response.exporters.length === 0) { return true; } From 10e1f1cb790a27cbae4c91780d15a438b3df03bb Mon Sep 17 00:00:00 2001 From: Tim Sullivan Date: Tue, 2 Feb 2021 13:33:47 -0700 Subject: [PATCH 3/5] Search Sessions: Improve Flaky Functional Test (#89370) * Search Sessions: Unskip Flaky Functional Test * typo * keep skip for now Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../page_objects/search_sessions_management_page.ts | 6 +++++- .../services/search_sessions.ts | 13 +++++++++++-- .../search_sessions/sessions_management.ts | 12 ++++++++++-- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/x-pack/test/functional/page_objects/search_sessions_management_page.ts b/x-pack/test/functional/page_objects/search_sessions_management_page.ts index 99c3be82a214..d57405f1f03a 100644 --- a/x-pack/test/functional/page_objects/search_sessions_management_page.ts +++ b/x-pack/test/functional/page_objects/search_sessions_management_page.ts @@ -7,6 +7,7 @@ import { FtrProviderContext } from '../ftr_provider_context'; export function SearchSessionsPageProvider({ getService, getPageObjects }: FtrProviderContext) { + const log = getService('log'); const find = getService('find'); const testSubjects = getService('testSubjects'); const PageObjects = getPageObjects(['common']); @@ -21,7 +22,7 @@ export function SearchSessionsPageProvider({ getService, getPageObjects }: FtrPr }, async getList() { - const table = await find.byCssSelector('table'); + const table = await testSubjects.find('searchSessionsMgmtTable'); const allRows = await table.findAllByTestSubject('searchSessionsRow'); return Promise.all( @@ -37,15 +38,18 @@ export function SearchSessionsPageProvider({ getService, getPageObjects }: FtrPr expires: $.findTestSubject('sessionManagementExpiresCol').text(), app: $.findTestSubject('sessionManagementAppIcon').attr('data-test-app-id'), view: async () => { + log.debug('management ui: view the session'); await viewCell.click(); }, reload: async () => { + log.debug('management ui: reload the status'); await actionsCell.click(); await find.clickByCssSelector( '[data-test-subj="sessionManagementPopoverAction-reload"]' ); }, cancel: async () => { + log.debug('management ui: cancel the session'); await actionsCell.click(); await find.clickByCssSelector( '[data-test-subj="sessionManagementPopoverAction-cancel"]' diff --git a/x-pack/test/send_search_to_background_integration/services/search_sessions.ts b/x-pack/test/send_search_to_background_integration/services/search_sessions.ts index 7041de646224..f3bac27cd2ac 100644 --- a/x-pack/test/send_search_to_background_integration/services/search_sessions.ts +++ b/x-pack/test/send_search_to_background_integration/services/search_sessions.ts @@ -58,23 +58,27 @@ export function SearchSessionsProvider({ getService }: FtrProviderContext) { } public async viewSearchSessions() { + log.debug('viewSearchSessions'); await this.ensurePopoverOpened(); await testSubjects.click('searchSessionIndicatorviewSearchSessionsLink'); } public async save() { + log.debug('save the search session'); await this.ensurePopoverOpened(); await testSubjects.click('searchSessionIndicatorSaveBtn'); await this.ensurePopoverClosed(); } public async cancel() { + log.debug('cancel the search session'); await this.ensurePopoverOpened(); await testSubjects.click('searchSessionIndicatorCancelBtn'); await this.ensurePopoverClosed(); } public async refresh() { + log.debug('refresh the status'); await this.ensurePopoverOpened(); await testSubjects.click('searchSessionIndicatorRefreshBtn'); await this.ensurePopoverClosed(); @@ -85,8 +89,12 @@ export function SearchSessionsProvider({ getService }: FtrProviderContext) { } private async ensurePopoverOpened() { + log.debug('ensurePopoverOpened'); const isAlreadyOpen = await testSubjects.exists(SEARCH_SESSIONS_POPOVER_CONTENT_TEST_SUBJ); - if (isAlreadyOpen) return; + if (isAlreadyOpen) { + log.debug('Popover is already open'); + return; + } return retry.waitFor(`searchSessions popover opened`, async () => { await testSubjects.click(SEARCH_SESSION_INDICATOR_TEST_SUBJ); return await testSubjects.exists(SEARCH_SESSIONS_POPOVER_CONTENT_TEST_SUBJ); @@ -94,6 +102,7 @@ export function SearchSessionsProvider({ getService }: FtrProviderContext) { } private async ensurePopoverClosed() { + log.debug('ensurePopoverClosed'); const isAlreadyClosed = !(await testSubjects.exists( SEARCH_SESSIONS_POPOVER_CONTENT_TEST_SUBJ )); @@ -110,7 +119,7 @@ export function SearchSessionsProvider({ getService }: FtrProviderContext) { * Alternatively, a test can navigate to `Management > Search Sessions` and use the UI to delete any created tests. */ public async deleteAllSearchSessions() { - log.debug('Deleting created searcg sessions'); + log.debug('Deleting created search sessions'); // ignores 409 errs and keeps retrying await retry.tryForTime(10000, async () => { const { body } = await supertest diff --git a/x-pack/test/send_search_to_background_integration/tests/apps/management/search_sessions/sessions_management.ts b/x-pack/test/send_search_to_background_integration/tests/apps/management/search_sessions/sessions_management.ts index e3797550984a..9efba47a8a60 100644 --- a/x-pack/test/send_search_to_background_integration/tests/apps/management/search_sessions/sessions_management.ts +++ b/x-pack/test/send_search_to_background_integration/tests/apps/management/search_sessions/sessions_management.ts @@ -9,6 +9,7 @@ import { FtrProviderContext } from '../../../../ftr_provider_context'; export default function ({ getService, getPageObjects }: FtrProviderContext) { const testSubjects = getService('testSubjects'); + const retry = getService('retry'); const PageObjects = getPageObjects([ 'common', 'header', @@ -18,13 +19,17 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { ]); const searchSessions = getService('searchSessions'); const esArchiver = getService('esArchiver'); - const retry = getService('retry'); + const log = getService('log'); // FLAKY: https://github.com/elastic/kibana/issues/89069 - describe.skip('Search search sessions Management UI', () => { + describe.skip('Search sessions Management UI', () => { describe('New search sessions', () => { before(async () => { await PageObjects.common.navigateToApp('dashboard'); + log.debug('wait for dashboard landing page'); + retry.tryForTime(10000, async () => { + testSubjects.existOrFail('dashboardLandingPage'); + }); }); after(async () => { @@ -32,6 +37,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('Saves a session and verifies it in the Management app', async () => { + log.debug('loading the "Not Delayed" dashboard'); await PageObjects.dashboard.loadSavedDashboard('Not Delayed'); await PageObjects.dashboard.waitForRenderComplete(); await searchSessions.expectState('completed'); @@ -47,6 +53,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); // find there is only one item in the table which is the newly saved session + log.debug('find the newly saved session'); const searchSessionList = await PageObjects.searchSessionsManagement.getList(); expect(searchSessionList.length).to.be(1); expect(searchSessionList[0].expires).not.to.eql('--'); @@ -63,6 +70,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await searchSessions.expectState('restored'); }); + // NOTE: this test depends on the previous one passing it('Reloads as new session from management', async () => { await PageObjects.searchSessionsManagement.goTo(); From 43faa76f676f9c8d808d2467209bc1de130f0237 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez=20Haro?= Date: Tue, 2 Feb 2021 20:43:20 +0000 Subject: [PATCH 4/5] [APM] `transactions.kubernetes.pod` can be undefined (#90044) --- .../public/components/shared/TransactionActionMenu/sections.ts | 2 +- x-pack/plugins/apm/typings/es_schemas/raw/fields/kubernetes.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/apm/public/components/shared/TransactionActionMenu/sections.ts b/x-pack/plugins/apm/public/components/shared/TransactionActionMenu/sections.ts index c77de875dc84..3cbd2e516a08 100644 --- a/x-pack/plugins/apm/public/components/shared/TransactionActionMenu/sections.ts +++ b/x-pack/plugins/apm/public/components/shared/TransactionActionMenu/sections.ts @@ -54,7 +54,7 @@ export const getSections = ({ urlParams: IUrlParams; }) => { const hostName = transaction.host?.hostname; - const podId = transaction.kubernetes?.pod.uid; + const podId = transaction.kubernetes?.pod?.uid; const containerId = transaction.container?.id; const time = Math.round(transaction.timestamp.us / 1000); diff --git a/x-pack/plugins/apm/typings/es_schemas/raw/fields/kubernetes.ts b/x-pack/plugins/apm/typings/es_schemas/raw/fields/kubernetes.ts index 5bec848056dd..65b3542ff217 100644 --- a/x-pack/plugins/apm/typings/es_schemas/raw/fields/kubernetes.ts +++ b/x-pack/plugins/apm/typings/es_schemas/raw/fields/kubernetes.ts @@ -5,5 +5,5 @@ */ export interface Kubernetes { - pod: { uid: string; [key: string]: unknown }; + pod?: { uid: string; [key: string]: unknown }; } From 76d6606a212a8cfb880afd1076e3a5ce5a47784f Mon Sep 17 00:00:00 2001 From: Jonathan Budzenski Date: Tue, 2 Feb 2021 15:02:13 -0600 Subject: [PATCH 5/5] [build] Build docker contexts by default (#89934) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- src/dev/build/args.test.ts | 10 +++++----- src/dev/build/args.ts | 14 ++++---------- src/dev/build/build_distributables.ts | 2 +- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/src/dev/build/args.test.ts b/src/dev/build/args.test.ts index 745b9d0b910c..798f7db05623 100644 --- a/src/dev/build/args.test.ts +++ b/src/dev/build/args.test.ts @@ -31,7 +31,7 @@ it('build default and oss dist for current platform, without packages, by defaul "createArchives": true, "createDebPackage": false, "createDockerCentOS": false, - "createDockerContexts": false, + "createDockerContexts": true, "createDockerUBI": false, "createRpmPackage": false, "downloadFreshNode": true, @@ -79,7 +79,7 @@ it('limits packages if --rpm passed with --all-platforms', () => { "createArchives": true, "createDebPackage": false, "createDockerCentOS": false, - "createDockerContexts": false, + "createDockerContexts": true, "createDockerUBI": false, "createRpmPackage": true, "downloadFreshNode": true, @@ -103,7 +103,7 @@ it('limits packages if --deb passed with --all-platforms', () => { "createArchives": true, "createDebPackage": true, "createDockerCentOS": false, - "createDockerContexts": false, + "createDockerContexts": true, "createDockerUBI": false, "createRpmPackage": false, "downloadFreshNode": true, @@ -128,7 +128,7 @@ it('limits packages if --docker passed with --all-platforms', () => { "createArchives": true, "createDebPackage": false, "createDockerCentOS": true, - "createDockerContexts": false, + "createDockerContexts": true, "createDockerUBI": true, "createRpmPackage": false, "downloadFreshNode": true, @@ -160,7 +160,7 @@ it('limits packages if --docker passed with --skip-docker-ubi and --all-platform "createArchives": true, "createDebPackage": false, "createDockerCentOS": true, - "createDockerContexts": false, + "createDockerContexts": true, "createDockerUBI": false, "createRpmPackage": false, "downloadFreshNode": true, diff --git a/src/dev/build/args.ts b/src/dev/build/args.ts index 2d26d7db3a5e..e51043ea40fe 100644 --- a/src/dev/build/args.ts +++ b/src/dev/build/args.ts @@ -22,7 +22,7 @@ export function readCliArgs(argv: string[]) { 'rpm', 'deb', 'docker-images', - 'docker-contexts', + 'skip-docker-contexts', 'skip-docker-ubi', 'skip-docker-centos', 'release', @@ -45,7 +45,6 @@ export function readCliArgs(argv: string[]) { rpm: null, deb: null, 'docker-images': null, - 'docker-contexts': null, oss: null, 'version-qualifier': '', }, @@ -72,7 +71,7 @@ export function readCliArgs(argv: string[]) { // In order to build a docker image we always need // to generate all the platforms - if (flags['docker-images'] || flags['docker-contexts']) { + if (flags['docker-images']) { flags['all-platforms'] = true; } @@ -82,12 +81,7 @@ export function readCliArgs(argv: string[]) { } // build all if no flags specified - if ( - flags.rpm === null && - flags.deb === null && - flags['docker-images'] === null && - flags['docker-contexts'] === null - ) { + if (flags.rpm === null && flags.deb === null && flags['docker-images'] === null) { return true; } @@ -106,7 +100,7 @@ export function readCliArgs(argv: string[]) { createDockerCentOS: isOsPackageDesired('docker-images') && !Boolean(flags['skip-docker-centos']), createDockerUBI: isOsPackageDesired('docker-images') && !Boolean(flags['skip-docker-ubi']), - createDockerContexts: isOsPackageDesired('docker-contexts'), + createDockerContexts: !Boolean(flags['skip-docker-contexts']), targetAllPlatforms: Boolean(flags['all-platforms']), }; diff --git a/src/dev/build/build_distributables.ts b/src/dev/build/build_distributables.ts index df4ba45517cc..771401a49a24 100644 --- a/src/dev/build/build_distributables.ts +++ b/src/dev/build/build_distributables.ts @@ -107,7 +107,7 @@ export async function buildDistributables(log: ToolingLog, options: BuildOptions } if (options.createDockerContexts) { - // control w/ --docker-contexts or --skip-os-packages + // control w/ --skip-docker-contexts await run(Tasks.CreateDockerContexts); }