diff --git a/Jenkinsfile b/Jenkinsfile index 261ba00096818..f6844c7f03fe6 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -7,43 +7,45 @@ stage("Kibana Pipeline") { // This stage is just here to help the BlueOcean UI a timeout(time: 120, unit: 'MINUTES') { timestamps { ansiColor('xterm') { - catchError { - parallel([ - 'kibana-intake-agent': kibanaPipeline.legacyJobRunner('kibana-intake'), - 'x-pack-intake-agent': kibanaPipeline.legacyJobRunner('x-pack-intake'), - 'kibana-oss-agent': kibanaPipeline.withWorkers('kibana-oss-tests', { kibanaPipeline.buildOss() }, [ - 'oss-firefoxSmoke': kibanaPipeline.getPostBuildWorker('firefoxSmoke', { runbld('./test/scripts/jenkins_firefox_smoke.sh', 'Execute kibana-firefoxSmoke') }), - 'oss-ciGroup1': kibanaPipeline.getOssCiGroupWorker(1), - 'oss-ciGroup2': kibanaPipeline.getOssCiGroupWorker(2), - 'oss-ciGroup3': kibanaPipeline.getOssCiGroupWorker(3), - 'oss-ciGroup4': kibanaPipeline.getOssCiGroupWorker(4), - 'oss-ciGroup5': kibanaPipeline.getOssCiGroupWorker(5), - 'oss-ciGroup6': kibanaPipeline.getOssCiGroupWorker(6), - 'oss-ciGroup7': kibanaPipeline.getOssCiGroupWorker(7), - 'oss-ciGroup8': kibanaPipeline.getOssCiGroupWorker(8), - 'oss-ciGroup9': kibanaPipeline.getOssCiGroupWorker(9), - 'oss-ciGroup10': kibanaPipeline.getOssCiGroupWorker(10), - 'oss-ciGroup11': kibanaPipeline.getOssCiGroupWorker(11), - 'oss-ciGroup12': kibanaPipeline.getOssCiGroupWorker(12), - 'oss-accessibility': kibanaPipeline.getPostBuildWorker('accessibility', { runbld('./test/scripts/jenkins_accessibility.sh', 'Execute kibana-accessibility') }), - // 'oss-visualRegression': kibanaPipeline.getPostBuildWorker('visualRegression', { runbld('./test/scripts/jenkins_visual_regression.sh', 'Execute kibana-visualRegression') }), - ]), - 'kibana-xpack-agent': kibanaPipeline.withWorkers('kibana-xpack-tests', { kibanaPipeline.buildXpack() }, [ - 'xpack-firefoxSmoke': kibanaPipeline.getPostBuildWorker('xpack-firefoxSmoke', { runbld('./test/scripts/jenkins_xpack_firefox_smoke.sh', 'Execute xpack-firefoxSmoke') }), - 'xpack-ciGroup1': kibanaPipeline.getXpackCiGroupWorker(1), - 'xpack-ciGroup2': kibanaPipeline.getXpackCiGroupWorker(2), - 'xpack-ciGroup3': kibanaPipeline.getXpackCiGroupWorker(3), - 'xpack-ciGroup4': kibanaPipeline.getXpackCiGroupWorker(4), - 'xpack-ciGroup5': kibanaPipeline.getXpackCiGroupWorker(5), - 'xpack-ciGroup6': kibanaPipeline.getXpackCiGroupWorker(6), - 'xpack-ciGroup7': kibanaPipeline.getXpackCiGroupWorker(7), - 'xpack-ciGroup8': kibanaPipeline.getXpackCiGroupWorker(8), - 'xpack-ciGroup9': kibanaPipeline.getXpackCiGroupWorker(9), - 'xpack-ciGroup10': kibanaPipeline.getXpackCiGroupWorker(10), - 'xpack-accessibility': kibanaPipeline.getPostBuildWorker('xpack-accessibility', { runbld('./test/scripts/jenkins_xpack_accessibility.sh', 'Execute xpack-accessibility') }), - // 'xpack-visualRegression': kibanaPipeline.getPostBuildWorker('xpack-visualRegression', { runbld('./test/scripts/jenkins_xpack_visual_regression.sh', 'Execute xpack-visualRegression') }), - ]), - ]) + githubPr.withDefaultPrComments { + catchError { + parallel([ + 'kibana-intake-agent': kibanaPipeline.legacyJobRunner('kibana-intake'), + 'x-pack-intake-agent': kibanaPipeline.legacyJobRunner('x-pack-intake'), + 'kibana-oss-agent': kibanaPipeline.withWorkers('kibana-oss-tests', { kibanaPipeline.buildOss() }, [ + 'oss-firefoxSmoke': kibanaPipeline.getPostBuildWorker('firefoxSmoke', { runbld('./test/scripts/jenkins_firefox_smoke.sh', 'Execute kibana-firefoxSmoke') }), + 'oss-ciGroup1': kibanaPipeline.getOssCiGroupWorker(1), + 'oss-ciGroup2': kibanaPipeline.getOssCiGroupWorker(2), + 'oss-ciGroup3': kibanaPipeline.getOssCiGroupWorker(3), + 'oss-ciGroup4': kibanaPipeline.getOssCiGroupWorker(4), + 'oss-ciGroup5': kibanaPipeline.getOssCiGroupWorker(5), + 'oss-ciGroup6': kibanaPipeline.getOssCiGroupWorker(6), + 'oss-ciGroup7': kibanaPipeline.getOssCiGroupWorker(7), + 'oss-ciGroup8': kibanaPipeline.getOssCiGroupWorker(8), + 'oss-ciGroup9': kibanaPipeline.getOssCiGroupWorker(9), + 'oss-ciGroup10': kibanaPipeline.getOssCiGroupWorker(10), + 'oss-ciGroup11': kibanaPipeline.getOssCiGroupWorker(11), + 'oss-ciGroup12': kibanaPipeline.getOssCiGroupWorker(12), + 'oss-accessibility': kibanaPipeline.getPostBuildWorker('accessibility', { runbld('./test/scripts/jenkins_accessibility.sh', 'Execute kibana-accessibility') }), + // 'oss-visualRegression': kibanaPipeline.getPostBuildWorker('visualRegression', { runbld('./test/scripts/jenkins_visual_regression.sh', 'Execute kibana-visualRegression') }), + ]), + 'kibana-xpack-agent': kibanaPipeline.withWorkers('kibana-xpack-tests', { kibanaPipeline.buildXpack() }, [ + 'xpack-firefoxSmoke': kibanaPipeline.getPostBuildWorker('xpack-firefoxSmoke', { runbld('./test/scripts/jenkins_xpack_firefox_smoke.sh', 'Execute xpack-firefoxSmoke') }), + 'xpack-ciGroup1': kibanaPipeline.getXpackCiGroupWorker(1), + 'xpack-ciGroup2': kibanaPipeline.getXpackCiGroupWorker(2), + 'xpack-ciGroup3': kibanaPipeline.getXpackCiGroupWorker(3), + 'xpack-ciGroup4': kibanaPipeline.getXpackCiGroupWorker(4), + 'xpack-ciGroup5': kibanaPipeline.getXpackCiGroupWorker(5), + 'xpack-ciGroup6': kibanaPipeline.getXpackCiGroupWorker(6), + 'xpack-ciGroup7': kibanaPipeline.getXpackCiGroupWorker(7), + 'xpack-ciGroup8': kibanaPipeline.getXpackCiGroupWorker(8), + 'xpack-ciGroup9': kibanaPipeline.getXpackCiGroupWorker(9), + 'xpack-ciGroup10': kibanaPipeline.getXpackCiGroupWorker(10), + 'xpack-accessibility': kibanaPipeline.getPostBuildWorker('xpack-accessibility', { runbld('./test/scripts/jenkins_xpack_accessibility.sh', 'Execute xpack-accessibility') }), + // 'xpack-visualRegression': kibanaPipeline.getPostBuildWorker('xpack-visualRegression', { runbld('./test/scripts/jenkins_xpack_visual_regression.sh', 'Execute xpack-visualRegression') }), + ]), + ]) + } } kibanaPipeline.sendMail() } diff --git a/packages/kbn-test/src/failed_tests_reporter/__fixtures__/ftr_report.xml b/packages/kbn-test/src/failed_tests_reporter/__fixtures__/ftr_report.xml index c006b0933bfa1..9da63234e03d4 100644 --- a/packages/kbn-test/src/failed_tests_reporter/__fixtures__/ftr_report.xml +++ b/packages/kbn-test/src/failed_tests_reporter/__fixtures__/ftr_report.xml @@ -41,5 +41,13 @@ Wait timed out after 10055ms + + + + diff --git a/packages/kbn-test/src/failed_tests_reporter/get_failures.ts b/packages/kbn-test/src/failed_tests_reporter/get_failures.ts index d38d118a255e7..85eff8eb07f5d 100644 --- a/packages/kbn-test/src/failed_tests_reporter/get_failures.ts +++ b/packages/kbn-test/src/failed_tests_reporter/get_failures.ts @@ -91,7 +91,8 @@ const getFailureText = (failure: NonNullable) => { const isLikelyIrrelevant = ({ name, failure }: TestFailure) => { if ( - failure.includes('NoSuchSessionError: This driver instance does not have a valid session ID') + failure.includes('NoSuchSessionError: This driver instance does not have a valid session ID') || + failure.includes('NoSuchSessionError: Tried to run command without establishing a connection') ) { return true; } diff --git a/src/dev/jest/babel_transform.js b/src/dev/jest/babel_transform.js index 4fce5aecf94ea..46bd72f1ba4bd 100644 --- a/src/dev/jest/babel_transform.js +++ b/src/dev/jest/babel_transform.js @@ -25,6 +25,7 @@ module.exports = babelJest.createTransformer({ '@babel/preset-env': { // disable built-in filtering, which is more performant but strips the import of `regenerator-runtime` required by EUI useBuiltIns: false, + corejs: false } }] ], diff --git a/src/legacy/server/config/__tests__/deprecation_warnings.js b/src/legacy/server/config/__tests__/deprecation_warnings.js index 0915f7de25b45..f49a1b6df45e2 100644 --- a/src/legacy/server/config/__tests__/deprecation_warnings.js +++ b/src/legacy/server/config/__tests__/deprecation_warnings.js @@ -26,7 +26,7 @@ const SETUP_NODE_ENV = require.resolve('../../../../setup_node_env'); const SECOND = 1000; describe('config/deprecation warnings', function () { - this.timeout(15 * SECOND); + this.timeout(65 * SECOND); let stdio = ''; let proc = null; @@ -53,7 +53,7 @@ describe('config/deprecation warnings', function () { // Either time out in 60 seconds, or resolve once the line is in our buffer return Promise.race([ - new Promise((resolve) => setTimeout(resolve, 60000)), + new Promise((resolve) => setTimeout(resolve, 60 * SECOND)), new Promise((resolve, reject) => { proc.stdout.on('data', (chunk) => { stdio += chunk.toString('utf8'); diff --git a/src/legacy/ui/public/courier/fetch/get_search_params.ts b/src/legacy/ui/public/courier/fetch/get_search_params.ts index 21cdbf97945c5..9fb8f2c728c6f 100644 --- a/src/legacy/ui/public/courier/fetch/get_search_params.ts +++ b/src/legacy/ui/public/courier/fetch/get_search_params.ts @@ -40,11 +40,11 @@ export function getSearchParams(config: IUiSettingsClient, esShardTimeout: numbe }; } -export function getIgnoreThrottled(config: IUiSettingsClient) { +function getIgnoreThrottled(config: IUiSettingsClient) { return !config.get('search:includeFrozen'); } -export function getMaxConcurrentShardRequests(config: IUiSettingsClient) { +function getMaxConcurrentShardRequests(config: IUiSettingsClient) { const maxConcurrentShardRequests = config.get('courier:maxConcurrentShardRequests'); return maxConcurrentShardRequests > 0 ? maxConcurrentShardRequests : undefined; } diff --git a/src/legacy/ui/public/courier/index.ts b/src/legacy/ui/public/courier/index.ts index 3c16926d2aba7..c8a06ec2a5518 100644 --- a/src/legacy/ui/public/courier/index.ts +++ b/src/legacy/ui/public/courier/index.ts @@ -17,8 +17,31 @@ * under the License. */ -export * from './fetch'; -export * from './search_source'; -export * from './search_strategy'; -export * from './utils/courier_inspector_utils'; -export * from './types'; +export { SearchSource } from './search_source'; + +// TODO: Exporting this mock outside of jest tests causes errors because +// jest is undefined. Need to refactor the mock to be consistent with +// other NP-style mocks. +// export { searchSourceMock } from './search_source/mocks'; + +export { + addSearchStrategy, // used externally by Rollups + getSearchErrorType, // used externally by Rollups + hasSearchStategyForIndexPattern, // used externally by Discover + isDefaultTypeIndexPattern, // used externally by Discover + SearchError, // used externally by Visualizations & Rollups +} from './search_strategy'; + +export { + getRequestInspectorStats, + getResponseInspectorStats, +} from './utils/courier_inspector_utils'; + +// types +export { SearchSourceContract } from './search_source'; + +export { + EsQuerySortValue, // used externally by Discover + FetchOptions, // used externally by AggTypes + SortDirection, // used externally by Discover +} from './types'; diff --git a/src/legacy/ui/public/courier/utils/courier_inspector_utils.ts b/src/legacy/ui/public/courier/utils/courier_inspector_utils.ts index 2c47fae4cce37..b4d5d5537333e 100644 --- a/src/legacy/ui/public/courier/utils/courier_inspector_utils.ts +++ b/src/legacy/ui/public/courier/utils/courier_inspector_utils.ts @@ -28,7 +28,7 @@ import { i18n } from '@kbn/i18n'; import { SearchResponse } from 'elasticsearch'; import { SearchSourceContract, RequestInspectorStats } from '../types'; -function getRequestInspectorStats(searchSource: SearchSourceContract) { +export function getRequestInspectorStats(searchSource: SearchSourceContract) { const stats: RequestInspectorStats = {}; const index = searchSource.getField('index'); @@ -56,7 +56,8 @@ function getRequestInspectorStats(searchSource: SearchSourceContract) { return stats; } -function getResponseInspectorStats( + +export function getResponseInspectorStats( searchSource: SearchSourceContract, resp: SearchResponse ) { @@ -121,5 +122,3 @@ function getResponseInspectorStats( return stats; } - -export { getRequestInspectorStats, getResponseInspectorStats }; diff --git a/src/plugins/embeddable/public/lib/actions/apply_filter_action.test.ts b/src/plugins/embeddable/public/lib/actions/apply_filter_action.test.ts index a9e0e33cbb967..6b8f2223a14a5 100644 --- a/src/plugins/embeddable/public/lib/actions/apply_filter_action.test.ts +++ b/src/plugins/embeddable/public/lib/actions/apply_filter_action.test.ts @@ -18,7 +18,7 @@ */ import { createFilterAction } from './apply_filter_action'; -import { expectError } from '../../tests/helpers'; +import { expectErrorAsync } from '../../tests/helpers'; test('has APPLY_FILTER_ACTION type and id', () => { const action = createFilterAction(); @@ -95,12 +95,13 @@ describe('execute()', () => { describe('when no filters are given', () => { test('throws an error', async () => { const action = createFilterAction(); - const error = expectError(() => + const error = await expectErrorAsync(() => action.execute({ embeddable: getEmbeddable(), } as any) ); expect(error).toBeInstanceOf(Error); + expect(error.message).toBe('Applying a filter requires a filter and embeddable as context'); }); test('updates filter input on success', async () => { diff --git a/src/plugins/embeddable/public/tests/helpers.ts b/src/plugins/embeddable/public/tests/helpers.ts index df3fea0d6b169..de15ef61c2c60 100644 --- a/src/plugins/embeddable/public/tests/helpers.ts +++ b/src/plugins/embeddable/public/tests/helpers.ts @@ -17,11 +17,27 @@ * under the License. */ -export const expectError = (fn: (...args: any) => any) => { +export const expectErrorAsync = (fn: (...args: unknown[]) => Promise): Promise => { + return fn() + .then(() => { + throw new Error('Expected an error throw.'); + }) + .catch(error => { + if (error.message === 'Expected an error throw.') { + throw error; + } + return error; + }); +}; + +export const expectError = (fn: (...args: any) => any): Error => { try { fn(); throw new Error('Expected an error throw.'); } catch (error) { + if (error.message === 'Expected an error throw.') { + throw error; + } return error; } }; diff --git a/tasks/test.js b/tasks/test.js index 911577d0bca4e..4463aba1e8f96 100644 --- a/tasks/test.js +++ b/tasks/test.js @@ -71,7 +71,7 @@ module.exports = function (grunt) { !grunt.option('quick') && 'run:typeCheck', !grunt.option('quick') && 'run:i18nCheck', 'run:checkFileCasing', - 'licenses', + 'run:licenses', 'test:quick', ]) ); diff --git a/test/functional/apps/visualize/_area_chart.js b/test/functional/apps/visualize/_area_chart.js index c6b33886a2456..47c7a1a6bbee8 100644 --- a/test/functional/apps/visualize/_area_chart.js +++ b/test/functional/apps/visualize/_area_chart.js @@ -57,7 +57,6 @@ export default function ({ getService, getPageObjects }) { it('should save and load with special characters', async function () { const vizNamewithSpecialChars = vizName1 + '/?&=%'; await PageObjects.visualize.saveVisualizationExpectSuccessAndBreadcrumb(vizNamewithSpecialChars); - await PageObjects.visualize.waitForVisualizationSavedToastGone(); }); it('should save and load with non-ascii characters', async function () { @@ -67,7 +66,6 @@ export default function ({ getService, getPageObjects }) { it('should save and load', async function () { await PageObjects.visualize.saveVisualizationExpectSuccessAndBreadcrumb(vizName1); - await PageObjects.visualize.waitForVisualizationSavedToastGone(); await PageObjects.visualize.loadSavedVisualization(vizName1); await PageObjects.visualize.waitForVisualization(); }); diff --git a/test/functional/apps/visualize/_data_table.js b/test/functional/apps/visualize/_data_table.js index 51c0984c89fed..f15d51bd11010 100644 --- a/test/functional/apps/visualize/_data_table.js +++ b/test/functional/apps/visualize/_data_table.js @@ -64,7 +64,7 @@ export default function ({ getService, getPageObjects }) { it('should be able to save and load', async function () { await PageObjects.visualize.saveVisualizationExpectSuccessAndBreadcrumb(vizName1); - await PageObjects.visualize.waitForVisualizationSavedToastGone(); + await PageObjects.visualize.loadSavedVisualization(vizName1); await PageObjects.visualize.waitForVisualization(); }); @@ -126,7 +126,7 @@ export default function ({ getService, getPageObjects }) { // check that it works after a save and reload const SAVE_NAME = 'viz w/ percents'; await PageObjects.visualize.saveVisualizationExpectSuccessAndBreadcrumb(SAVE_NAME); - await PageObjects.visualize.waitForVisualizationSavedToastGone(); + await PageObjects.visualize.loadSavedVisualization(SAVE_NAME); await PageObjects.visualize.waitForVisualization(); diff --git a/test/functional/apps/visualize/_data_table_nontimeindex.js b/test/functional/apps/visualize/_data_table_nontimeindex.js index 6cc0962140329..f55c88cb3a486 100644 --- a/test/functional/apps/visualize/_data_table_nontimeindex.js +++ b/test/functional/apps/visualize/_data_table_nontimeindex.js @@ -64,7 +64,7 @@ export default function ({ getService, getPageObjects }) { it('should be able to save and load', async function () { await PageObjects.visualize.saveVisualizationExpectSuccessAndBreadcrumb(vizName1); - await PageObjects.visualize.waitForVisualizationSavedToastGone(); + await PageObjects.visualize.loadSavedVisualization(vizName1); await PageObjects.visualize.waitForVisualization(); }); diff --git a/test/functional/apps/visualize/_heatmap_chart.js b/test/functional/apps/visualize/_heatmap_chart.js index 547ecdd598811..c1b86d26442c9 100644 --- a/test/functional/apps/visualize/_heatmap_chart.js +++ b/test/functional/apps/visualize/_heatmap_chart.js @@ -47,7 +47,7 @@ export default function ({ getService, getPageObjects }) { it('should save and load', async function () { await PageObjects.visualize.saveVisualizationExpectSuccessAndBreadcrumb(vizName1); - await PageObjects.visualize.waitForVisualizationSavedToastGone(); + await PageObjects.visualize.loadSavedVisualization(vizName1); await PageObjects.visualize.waitForVisualization(); }); diff --git a/test/functional/apps/visualize/_line_chart.js b/test/functional/apps/visualize/_line_chart.js index cbadb7408f985..f407dd0e16f76 100644 --- a/test/functional/apps/visualize/_line_chart.js +++ b/test/functional/apps/visualize/_line_chart.js @@ -140,7 +140,7 @@ export default function ({ getService, getPageObjects }) { it('should be able to save and load', async function () { await PageObjects.visualize.saveVisualizationExpectSuccessAndBreadcrumb(vizName1); - await PageObjects.visualize.waitForVisualizationSavedToastGone(); + await PageObjects.visualize.loadSavedVisualization(vizName1); await PageObjects.visualize.waitForVisualization(); }); diff --git a/test/functional/apps/visualize/_pie_chart.js b/test/functional/apps/visualize/_pie_chart.js index fc040c038afd0..72fda07d473d6 100644 --- a/test/functional/apps/visualize/_pie_chart.js +++ b/test/functional/apps/visualize/_pie_chart.js @@ -51,7 +51,7 @@ export default function ({ getService, getPageObjects }) { it('should save and load', async function () { await PageObjects.visualize.saveVisualizationExpectSuccessAndBreadcrumb(vizName1); - await PageObjects.visualize.waitForVisualizationSavedToastGone(); + await PageObjects.visualize.loadSavedVisualization(vizName1); await PageObjects.visualize.waitForVisualization(); }); @@ -156,7 +156,7 @@ export default function ({ getService, getPageObjects }) { it('should correctly save disabled agg', async () => { await PageObjects.visualize.saveVisualizationExpectSuccessAndBreadcrumb(vizName1); - await PageObjects.visualize.waitForVisualizationSavedToastGone(); + await PageObjects.visualize.loadSavedVisualization(vizName1); await PageObjects.visualize.waitForRenderingCount(); diff --git a/test/functional/apps/visualize/_tag_cloud.js b/test/functional/apps/visualize/_tag_cloud.js index 5b435ef29a268..f104b906909a5 100644 --- a/test/functional/apps/visualize/_tag_cloud.js +++ b/test/functional/apps/visualize/_tag_cloud.js @@ -96,7 +96,7 @@ export default function ({ getService, getPageObjects }) { it('should save and load', async function () { await PageObjects.visualize.saveVisualizationExpectSuccessAndBreadcrumb(vizName1); - await PageObjects.visualize.waitForVisualizationSavedToastGone(); + await PageObjects.visualize.loadSavedVisualization(vizName1); await PageObjects.visualize.waitForVisualization(); }); diff --git a/test/functional/apps/visualize/_vertical_bar_chart.js b/test/functional/apps/visualize/_vertical_bar_chart.js index fb08cfa898237..704081d6966dd 100644 --- a/test/functional/apps/visualize/_vertical_bar_chart.js +++ b/test/functional/apps/visualize/_vertical_bar_chart.js @@ -52,7 +52,7 @@ export default function ({ getService, getPageObjects }) { it('should save and load', async function () { await PageObjects.visualize.saveVisualizationExpectSuccessAndBreadcrumb(vizName1); - await PageObjects.visualize.waitForVisualizationSavedToastGone(); + await PageObjects.visualize.loadSavedVisualization(vizName1); await PageObjects.visualize.waitForVisualization(); }); diff --git a/test/functional/apps/visualize/_vertical_bar_chart_nontimeindex.js b/test/functional/apps/visualize/_vertical_bar_chart_nontimeindex.js index 426a429f4b401..e30aac6251e84 100644 --- a/test/functional/apps/visualize/_vertical_bar_chart_nontimeindex.js +++ b/test/functional/apps/visualize/_vertical_bar_chart_nontimeindex.js @@ -51,7 +51,7 @@ export default function ({ getService, getPageObjects }) { it('should save and load', async function () { await PageObjects.visualize.saveVisualizationExpectSuccessAndBreadcrumb(vizName1); - await PageObjects.visualize.waitForVisualizationSavedToastGone(); + await PageObjects.visualize.loadSavedVisualization(vizName1); await PageObjects.visualize.waitForVisualization(); }); diff --git a/test/functional/page_objects/common_page.ts b/test/functional/page_objects/common_page.ts index 19a7bd25db9c6..0e9a64e736999 100644 --- a/test/functional/page_objects/common_page.ts +++ b/test/functional/page_objects/common_page.ts @@ -409,6 +409,14 @@ export function CommonPageProvider({ getService, getPageObjects }: FtrProviderCo }); return response.status !== 200; } + async waitForSaveModalToClose() { + log.debug('Waiting for save modal to close'); + await retry.try(async () => { + if (await testSubjects.exists('savedObjectSaveModal')) { + throw new Error('save modal still open'); + } + }); + } } return new CommonPage(); diff --git a/test/functional/page_objects/dashboard_page.js b/test/functional/page_objects/dashboard_page.js index 49e6bd02d681f..73424a3df55da 100644 --- a/test/functional/page_objects/dashboard_page.js +++ b/test/functional/page_objects/dashboard_page.js @@ -322,20 +322,11 @@ export function DashboardPageProvider({ getService, getPageObjects }) { await testSubjects.existOrFail('saveDashboardSuccess'); const message = await PageObjects.common.closeToast(); await PageObjects.header.waitUntilLoadingHasFinished(); - await this.waitForSaveModalToClose(); + await PageObjects.common.waitForSaveModalToClose(); return message; } - async waitForSaveModalToClose() { - log.debug('Waiting for dashboard save modal to close'); - await retry.try(async () => { - if (await testSubjects.exists('savedObjectSaveModal')) { - throw new Error('dashboard save still open'); - } - }); - } - async deleteDashboard(dashboardName, dashboardId) { await this.gotoDashboardLandingPage(); await this.searchForDashboardWithName(dashboardName); diff --git a/test/functional/page_objects/visualize_page.js b/test/functional/page_objects/visualize_page.js index a6792670fdb3f..1104f60171c9a 100644 --- a/test/functional/page_objects/visualize_page.js +++ b/test/functional/page_objects/visualize_page.js @@ -756,19 +756,23 @@ export function VisualizePageProvider({ getService, getPageObjects, updateBaseli await testSubjects.click('saveAsNewCheckbox'); } log.debug('Click Save Visualization button'); + await testSubjects.click('confirmSaveSavedObjectButton'); - // if we wait for this, the success toast message could be gone :-() - // wait for save to complete before completion - // await PageObjects.header.waitUntilLoadingHasFinished(); + // Confirm that the Visualization has actually been saved + await testSubjects.existOrFail('saveVisualizationSuccess'); + const message = await PageObjects.common.closeToast(); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.common.waitForSaveModalToClose(); + + return message; } async saveVisualizationExpectSuccess(vizName, { saveAsNew = false } = {}) { - await this.saveVisualization(vizName, { saveAsNew }); - const successToast = await testSubjects.exists('saveVisualizationSuccess', { - timeout: 2 * defaultFindTimeout - }); - expect(successToast).to.be(true); + const saveMessage = await this.saveVisualization(vizName, { saveAsNew }); + if (!saveMessage) { + throw new Error(`Expected saveVisualization to respond with the saveMessage from the toast, got ${saveMessage}`); + } } async saveVisualizationExpectSuccessAndBreadcrumb(vizName, { saveAsNew = false } = {}) { diff --git a/vars/githubPr.groovy b/vars/githubPr.groovy new file mode 100644 index 0000000000000..09a166192bf7a --- /dev/null +++ b/vars/githubPr.groovy @@ -0,0 +1,173 @@ +/** + Wraps the main/important part of a job, executes it, and then publishes a comment to GitHub with the status. + + It will check for the existence of GHPRB env variables before doing any actual PR work, + so it can be used to wrap code that is executed in both PR and non-PR contexts. + + Inside the comment, it will hide a JSON blob containing build data (status, etc). + + Then, the next time it posts a comment, it will: + 1. Read the previous comment and parse the json + 2. Create a new comment, add a summary of up to 5 previous builds to it, and append this build's data to the hidden JSON + 3. Delete the old comment + + So, there is only ever one build status comment on a PR at any given time, the most recent one. +*/ +def withDefaultPrComments(closure) { + catchError { + catchError { + closure() + } + + if (!params.ENABLE_GITHUB_PR_COMMENTS || !isPr()) { + return + } + + def status = buildUtils.getBuildStatus() + if (status == "ABORTED") { + return; + } + + def lastComment = getLatestBuildComment() + def info = getLatestBuildInfo(lastComment) ?: [:] + info.builds = (info.builds ?: []).takeRight(5) // Rotate out old builds + + def message = getNextCommentMessage(info) + postComment(message) + + if (lastComment) { + deleteComment(lastComment.id) + } + } +} + +// Checks whether or not this currently executing build was triggered via a PR in the elastic/kibana repo +def isPr() { + return !!(env.ghprbPullId && env.ghprbPullLink && env.ghprbPullLink =~ /\/elastic\/kibana\//) +} + +def getLatestBuildComment() { + return getComments() + .reverse() + .find { it.user.login == 'elasticmachine' && it.body =~ // + if (!matches || !matches[0]) { + return null + } + + return toJSON(matches[0][1].trim()) +} + +def getLatestBuildInfo() { + return getLatestBuildInfo(getLatestBuildComment()) +} + +def getLatestBuildInfo(comment) { + return comment ? getBuildInfoFromComment(comment) : null +} + +def createBuildInfo() { + return [ + status: buildUtils.getBuildStatus(), + url: env.BUILD_URL, + number: env.BUILD_NUMBER, + commit: getCommitHash() + ] +} + +def getHistoryText(builds) { + if (!builds || builds.size() < 1) { + return "" + } + + def list = builds + .reverse() + .collect { build -> + if (build.status == "SUCCESS") { + return "* :green_heart: [Build #${build.number}](${build.url}) succeeded ${build.commit}" + } else { + return "* :broken_heart: [Build #${build.number}](${build.url}) failed ${build.commit}" + } + } + .join("\n") + + return "### History\n${list}" +} + +def getNextCommentMessage(previousCommentInfo = [:]) { + info = previousCommentInfo ?: [:] + info.builds = previousCommentInfo.builds ?: [] + + def messages = [] + + if (buildUtils.getBuildStatus() == 'SUCCESS') { + messages << """ + ## :green_heart: Build Succeeded + * [continuous-integration/kibana-ci/pull-request](${env.BUILD_URL}) + * Commit: ${getCommitHash()} + """ + } else { + messages << """ + ## :broken_heart: Build Failed + * [continuous-integration/kibana-ci/pull-request](${env.BUILD_URL}) + * Commit: ${getCommitHash()} + """ + } + + if (info.builds && info.builds.size() > 0) { + messages << getHistoryText(info.builds) + } + + messages << "To update your PR or re-run it, just comment with:\n`@elasticmachine merge upstream`" + + info.builds << createBuildInfo() + + messages << """ + + """ + + return messages + .findAll { !!it } // No blank strings + .collect { it.stripIndent().trim() } + .join("\n\n") +} + +def withGithubCredentials(closure) { + withCredentials([ + string(credentialsId: '2a9602aa-ab9f-4e52-baf3-b71ca88469c7', variable: 'GITHUB_TOKEN'), + ]) { + closure() + } +} + +def postComment(message) { + if (!isPr()) { + error "Trying to post a GitHub PR comment on a non-PR or non-elastic PR build" + } + + withGithubCredentials { + return githubApi.post("repos/elastic/kibana/issues/${env.ghprbPullId}/comments", [ body: message ]) + } +} + +def getComments() { + withGithubCredentials { + return githubIssues.getComments(env.ghprbPullId) + } +} + +def deleteComment(commentId) { + withGithubCredentials { + def path = "repos/elastic/kibana/issues/comments/${commentId}" + return githubApi([ path: path ], [ method: "DELETE" ]) + } +} + +def getCommitHash() { + return env.ghprbActualCommit +} diff --git a/x-pack/legacy/plugins/actions/README.md b/x-pack/legacy/plugins/actions/README.md index 2eec667ce95c4..a982565fc6d07 100644 --- a/x-pack/legacy/plugins/actions/README.md +++ b/x-pack/legacy/plugins/actions/README.md @@ -96,7 +96,7 @@ Payload: |Property|Description|Type| |---|---|---| -|description|A description to reference and search in the future. This value will be used to populate dropdowns.|string| +|name|A name to reference and search in the future. This value will be used to populate dropdowns.|string| |actionTypeId|The id value of the action type you want to call when the action executes.|string| |config|The configuration the action type expects. See related action type to see what attributes are expected. This will also validate against the action type if config validation is defined.|object| |secrets|The secrets the action type expects. See related action type to see what attributes are expected. This will also validate against the action type if secrets validation is defined.|object| @@ -139,7 +139,7 @@ Payload: |Property|Description|Type| |---|---|---| -|description|A description to reference and search in the future. This value will be used to populate dropdowns.|string| +|name|A name to reference and search in the future. This value will be used to populate dropdowns.|string| |config|The configuration the action type expects. See related action type to see what attributes are expected. This will also validate against the action type if config validation is defined.|object| |secrets|The secrets the action type expects. See related action type to see what attributes are expected. This will also validate against the action type if secrets validation is defined.|object| @@ -301,7 +301,7 @@ $ kbn-action create .slack "post to slack" '{"webhookUrl": "https://hooks.slack. "id": "d6f1e228-1806-4a72-83ac-e06f3d5c2fbe", "attributes": { "actionTypeId": ".slack", - "description": "post to slack", + "name": "post to slack", "config": {} }, "references": [], diff --git a/x-pack/legacy/plugins/actions/mappings.json b/x-pack/legacy/plugins/actions/mappings.json index 480462eb4a63f..a9c4d80b00af1 100644 --- a/x-pack/legacy/plugins/actions/mappings.json +++ b/x-pack/legacy/plugins/actions/mappings.json @@ -1,7 +1,7 @@ { "action": { "properties": { - "description": { + "name": { "type": "text" }, "actionTypeId": { diff --git a/x-pack/legacy/plugins/actions/server/actions_client.test.ts b/x-pack/legacy/plugins/actions/server/actions_client.test.ts index 933b7b0b239b6..1c10d1b1a83af 100644 --- a/x-pack/legacy/plugins/actions/server/actions_client.test.ts +++ b/x-pack/legacy/plugins/actions/server/actions_client.test.ts @@ -50,7 +50,7 @@ describe('create()', () => { id: '1', type: 'type', attributes: { - description: 'my description', + name: 'my name', actionTypeId: 'my-action-type', config: {}, }, @@ -64,7 +64,7 @@ describe('create()', () => { savedObjectsClient.create.mockResolvedValueOnce(savedObjectCreateResult); const result = await actionsClient.create({ action: { - description: 'my description', + name: 'my name', actionTypeId: 'my-action-type', config: {}, secrets: {}, @@ -72,7 +72,7 @@ describe('create()', () => { }); expect(result).toEqual({ id: '1', - description: 'my description', + name: 'my name', actionTypeId: 'my-action-type', config: {}, }); @@ -83,7 +83,7 @@ describe('create()', () => { Object { "actionTypeId": "my-action-type", "config": Object {}, - "description": "my description", + "name": "my name", "secrets": Object {}, }, ] @@ -104,7 +104,7 @@ describe('create()', () => { await expect( actionsClient.create({ action: { - description: 'my description', + name: 'my name', actionTypeId: 'my-action-type', config: {}, secrets: {}, @@ -119,7 +119,7 @@ describe('create()', () => { await expect( actionsClient.create({ action: { - description: 'my description', + name: 'my name', actionTypeId: 'unregistered-action-type', config: {}, secrets: {}, @@ -140,7 +140,7 @@ describe('create()', () => { id: '1', type: 'type', attributes: { - description: 'my description', + name: 'my name', actionTypeId: 'my-action-type', config: { a: true, @@ -153,7 +153,7 @@ describe('create()', () => { }); const result = await actionsClient.create({ action: { - description: 'my description', + name: 'my name', actionTypeId: 'my-action-type', config: { a: true, @@ -165,7 +165,7 @@ describe('create()', () => { }); expect(result).toEqual({ id: '1', - description: 'my description', + name: 'my name', actionTypeId: 'my-action-type', config: { a: true, @@ -184,7 +184,7 @@ describe('create()', () => { "b": true, "c": true, }, - "description": "my description", + "name": "my name", "secrets": Object {}, }, ] @@ -301,7 +301,7 @@ describe('update()', () => { type: 'action', attributes: { actionTypeId: 'my-action-type', - description: 'my description', + name: 'my name', config: {}, secrets: {}, }, @@ -310,7 +310,7 @@ describe('update()', () => { const result = await actionsClient.update({ id: 'my-action', action: { - description: 'my description', + name: 'my name', config: {}, secrets: {}, }, @@ -318,7 +318,7 @@ describe('update()', () => { expect(result).toEqual({ id: 'my-action', actionTypeId: 'my-action-type', - description: 'my description', + name: 'my name', config: {}, }); expect(savedObjectsClient.update).toHaveBeenCalledTimes(1); @@ -329,7 +329,7 @@ describe('update()', () => { Object { "actionTypeId": "my-action-type", "config": Object {}, - "description": "my description", + "name": "my name", "secrets": Object {}, }, ] @@ -366,7 +366,7 @@ describe('update()', () => { actionsClient.update({ id: 'my-action', action: { - description: 'my description', + name: 'my name', config: {}, secrets: {}, }, @@ -395,7 +395,7 @@ describe('update()', () => { type: 'action', attributes: { actionTypeId: 'my-action-type', - description: 'my description', + name: 'my name', config: { a: true, b: true, @@ -408,7 +408,7 @@ describe('update()', () => { const result = await actionsClient.update({ id: 'my-action', action: { - description: 'my description', + name: 'my name', config: { a: true, b: true, @@ -420,7 +420,7 @@ describe('update()', () => { expect(result).toEqual({ id: 'my-action', actionTypeId: 'my-action-type', - description: 'my description', + name: 'my name', config: { a: true, b: true, @@ -439,7 +439,7 @@ describe('update()', () => { "b": true, "c": true, }, - "description": "my description", + "name": "my name", "secrets": Object {}, }, ] diff --git a/x-pack/legacy/plugins/actions/server/actions_client.ts b/x-pack/legacy/plugins/actions/server/actions_client.ts index 1e4135bd0d66f..10713d72a3858 100644 --- a/x-pack/legacy/plugins/actions/server/actions_client.ts +++ b/x-pack/legacy/plugins/actions/server/actions_client.ts @@ -16,7 +16,7 @@ import { validateConfig, validateSecrets } from './lib'; import { ActionResult, FindActionResult, RawAction } from './types'; interface ActionUpdate extends SavedObjectAttributes { - description: string; + name: string; config: SavedObjectAttributes; secrets: SavedObjectAttributes; } @@ -87,14 +87,14 @@ export class ActionsClient { * Create an action */ public async create({ action }: CreateOptions): Promise { - const { actionTypeId, description, config, secrets } = action; + const { actionTypeId, name, config, secrets } = action; const actionType = this.actionTypeRegistry.get(actionTypeId); const validatedActionTypeConfig = validateConfig(actionType, config); const validatedActionTypeSecrets = validateSecrets(actionType, secrets); const result = await this.savedObjectsClient.create('action', { actionTypeId, - description, + name, config: validatedActionTypeConfig as SavedObjectAttributes, secrets: validatedActionTypeSecrets as SavedObjectAttributes, }); @@ -102,7 +102,7 @@ export class ActionsClient { return { id: result.id, actionTypeId: result.attributes.actionTypeId, - description: result.attributes.description, + name: result.attributes.name, config: result.attributes.config, }; } @@ -113,14 +113,14 @@ export class ActionsClient { public async update({ id, action }: UpdateOptions): Promise { const existingObject = await this.savedObjectsClient.get('action', id); const { actionTypeId } = existingObject.attributes; - const { description, config, secrets } = action; + const { name, config, secrets } = action; const actionType = this.actionTypeRegistry.get(actionTypeId); const validatedActionTypeConfig = validateConfig(actionType, config); const validatedActionTypeSecrets = validateSecrets(actionType, secrets); const result = await this.savedObjectsClient.update('action', id, { actionTypeId, - description, + name, config: validatedActionTypeConfig as SavedObjectAttributes, secrets: validatedActionTypeSecrets as SavedObjectAttributes, }); @@ -128,7 +128,7 @@ export class ActionsClient { return { id, actionTypeId: result.attributes.actionTypeId as string, - description: result.attributes.description as string, + name: result.attributes.name as string, config: result.attributes.config as Record, }; } @@ -142,7 +142,7 @@ export class ActionsClient { return { id, actionTypeId: result.attributes.actionTypeId as string, - description: result.attributes.description as string, + name: result.attributes.name as string, config: result.attributes.config as Record, }; } diff --git a/x-pack/legacy/plugins/actions/server/lib/action_executor.ts b/x-pack/legacy/plugins/actions/server/lib/action_executor.ts index b7d4ea96ea0f8..1afb8a8870215 100644 --- a/x-pack/legacy/plugins/actions/server/lib/action_executor.ts +++ b/x-pack/legacy/plugins/actions/server/lib/action_executor.ts @@ -67,7 +67,7 @@ export class ActionExecutor { // Ensure user can read the action before processing const { - attributes: { actionTypeId, config, description }, + attributes: { actionTypeId, config, name }, } = await services.savedObjectsClient.get('action', actionId); // Only get encrypted attributes here, the remaining attributes can be fetched in // the savedObjectsClient call @@ -95,7 +95,7 @@ export class ActionExecutor { } let result: ActionTypeExecutorResult | null = null; - const actionLabel = `${actionId} - ${actionTypeId} - ${description}`; + const actionLabel = `${actionId} - ${actionTypeId} - ${name}`; try { result = await actionType.executor({ diff --git a/x-pack/legacy/plugins/actions/server/plugin.ts b/x-pack/legacy/plugins/actions/server/plugin.ts index 26b65b1a1689a..27eead7d736c1 100644 --- a/x-pack/legacy/plugins/actions/server/plugin.ts +++ b/x-pack/legacy/plugins/actions/server/plugin.ts @@ -100,7 +100,7 @@ export class Plugin { plugins.encryptedSavedObjects.registerType({ type: 'action', attributesToEncrypt: new Set(['secrets']), - attributesToExcludeFromAAD: new Set(['description']), + attributesToExcludeFromAAD: new Set(['name']), }); plugins.encryptedSavedObjects.registerType({ type: 'action_task_params', diff --git a/x-pack/legacy/plugins/actions/server/routes/create.test.ts b/x-pack/legacy/plugins/actions/server/routes/create.test.ts index 3b3f331fda526..3b6446280e8d5 100644 --- a/x-pack/legacy/plugins/actions/server/routes/create.test.ts +++ b/x-pack/legacy/plugins/actions/server/routes/create.test.ts @@ -19,7 +19,7 @@ it('creates an action with proper parameters', async () => { method: 'POST', url: '/api/action', payload: { - description: 'My description', + name: 'My name', actionTypeId: 'abc', config: { foo: true }, secrets: {}, @@ -27,7 +27,7 @@ it('creates an action with proper parameters', async () => { }; const createResult = { id: '1', - description: 'My description', + name: 'My name', actionTypeId: 'abc', config: { foo: true }, }; @@ -38,7 +38,7 @@ it('creates an action with proper parameters', async () => { const response = JSON.parse(payload); expect(response).toEqual({ id: '1', - description: 'My description', + name: 'My name', actionTypeId: 'abc', config: { foo: true }, }); @@ -51,7 +51,7 @@ it('creates an action with proper parameters', async () => { "config": Object { "foo": true, }, - "description": "My description", + "name": "My name", "secrets": Object {}, }, }, diff --git a/x-pack/legacy/plugins/actions/server/routes/create.ts b/x-pack/legacy/plugins/actions/server/routes/create.ts index abe077b1f9136..d3cc130f24324 100644 --- a/x-pack/legacy/plugins/actions/server/routes/create.ts +++ b/x-pack/legacy/plugins/actions/server/routes/create.ts @@ -16,7 +16,7 @@ interface CreateRequest extends WithoutQueryAndParams { id?: string; }; payload: { - description: string; + name: string; actionTypeId: string; config: Record; secrets: Record; @@ -34,7 +34,7 @@ export const createActionRoute = { }, payload: Joi.object() .keys({ - description: Joi.string().required(), + name: Joi.string().required(), actionTypeId: Joi.string().required(), config: Joi.object().default({}), secrets: Joi.object().default({}), diff --git a/x-pack/legacy/plugins/actions/server/routes/find.test.ts b/x-pack/legacy/plugins/actions/server/routes/find.test.ts index 147a80bdbba5b..b4e0cb3a13a97 100644 --- a/x-pack/legacy/plugins/actions/server/routes/find.test.ts +++ b/x-pack/legacy/plugins/actions/server/routes/find.test.ts @@ -23,9 +23,9 @@ it('sends proper arguments to action find function', async () => { 'page=1&' + 'search=text*&' + 'default_search_operator=AND&' + - 'search_fields=description&' + - 'sort_field=description&' + - 'fields=description', + 'search_fields=name&' + + 'sort_field=name&' + + 'fields=name', }; const expectedResult = { total: 0, @@ -46,7 +46,7 @@ it('sends proper arguments to action find function', async () => { "options": Object { "defaultSearchOperator": "AND", "fields": Array [ - "description", + "name", ], "filter": undefined, "hasReference": undefined, @@ -54,9 +54,9 @@ it('sends proper arguments to action find function', async () => { "perPage": 1, "search": "text*", "searchFields": Array [ - "description", + "name", ], - "sortField": "description", + "sortField": "name", }, }, ] diff --git a/x-pack/legacy/plugins/actions/server/routes/get.test.ts b/x-pack/legacy/plugins/actions/server/routes/get.test.ts index 5d61b3fd448e7..cdc38df5f6350 100644 --- a/x-pack/legacy/plugins/actions/server/routes/get.test.ts +++ b/x-pack/legacy/plugins/actions/server/routes/get.test.ts @@ -24,7 +24,7 @@ it('calls get with proper parameters', async () => { id: '1', actionTypeId: 'my-action-type-id', config: {}, - description: 'my action type description', + name: 'my action type name', }; actionsClient.get.mockResolvedValueOnce(expectedResult); diff --git a/x-pack/legacy/plugins/actions/server/routes/update.test.ts b/x-pack/legacy/plugins/actions/server/routes/update.test.ts index e2e7bdb3b90d8..d6294e72474f9 100644 --- a/x-pack/legacy/plugins/actions/server/routes/update.test.ts +++ b/x-pack/legacy/plugins/actions/server/routes/update.test.ts @@ -20,14 +20,14 @@ it('calls the update function with proper parameters', async () => { method: 'PUT', url: '/api/action/1', payload: { - description: 'My description', + name: 'My name', config: { foo: true }, }, }; const updateResult: ActionResult = { id: '1', actionTypeId: 'my-action-type-id', - description: 'My description', + name: 'My name', config: { foo: true }, }; @@ -38,7 +38,7 @@ it('calls the update function with proper parameters', async () => { expect(response).toEqual({ id: '1', actionTypeId: 'my-action-type-id', - description: 'My description', + name: 'My name', config: { foo: true }, }); expect(actionsClient.update).toHaveBeenCalledTimes(1); @@ -49,7 +49,7 @@ it('calls the update function with proper parameters', async () => { "config": Object { "foo": true, }, - "description": "My description", + "name": "My name", "secrets": Object {}, }, "id": "1", diff --git a/x-pack/legacy/plugins/actions/server/routes/update.ts b/x-pack/legacy/plugins/actions/server/routes/update.ts index 3d7095bf1c8d5..a86ef8fa99c8a 100644 --- a/x-pack/legacy/plugins/actions/server/routes/update.ts +++ b/x-pack/legacy/plugins/actions/server/routes/update.ts @@ -9,7 +9,7 @@ import Hapi from 'hapi'; interface UpdateRequest extends Hapi.Request { payload: { - description: string; + name: string; config: Record; secrets: Record; }; @@ -31,7 +31,7 @@ export const updateActionRoute = { .required(), payload: Joi.object() .keys({ - description: Joi.string().required(), + name: Joi.string().required(), config: Joi.object().default({}), secrets: Joi.object().default({}), }) @@ -40,8 +40,8 @@ export const updateActionRoute = { }, async handler(request: UpdateRequest) { const { id } = request.params; - const { description, config, secrets } = request.payload; + const { name, config, secrets } = request.payload; const actionsClient = request.getActionsClient!(); - return await actionsClient.update({ id, action: { description, config, secrets } }); + return await actionsClient.update({ id, action: { name, config, secrets } }); }, }; diff --git a/x-pack/legacy/plugins/actions/server/types.ts b/x-pack/legacy/plugins/actions/server/types.ts index 1ee5022338a46..5a74241bc4829 100644 --- a/x-pack/legacy/plugins/actions/server/types.ts +++ b/x-pack/legacy/plugins/actions/server/types.ts @@ -41,7 +41,7 @@ export interface ActionTypeExecutorOptions { export interface ActionResult { id: string; actionTypeId: string; - description: string; + name: string; config: Record; } @@ -81,7 +81,7 @@ export interface ActionType { export interface RawAction extends SavedObjectAttributes { actionTypeId: string; - description: string; + name: string; config: SavedObjectAttributes; secrets: SavedObjectAttributes; } diff --git a/x-pack/legacy/plugins/apm/public/services/rest/callApi.ts b/x-pack/legacy/plugins/apm/public/services/rest/callApi.ts index 887200bdfc22a..853ba5023f6fd 100644 --- a/x-pack/legacy/plugins/apm/public/services/rest/callApi.ts +++ b/x-pack/legacy/plugins/apm/public/services/rest/callApi.ts @@ -21,18 +21,11 @@ function fetchOptionsWithDebug(fetchOptions: FetchOptions) { sessionStorage.getItem('apm_debug') === 'true' && startsWith(fetchOptions.pathname, '/api/apm'); - const isGet = !fetchOptions.method || fetchOptions.method === 'GET'; - - // Need an empty body to pass route validation - const body = isGet - ? {} - : { - body: JSON.stringify(fetchOptions.body || {}) - }; + const { body, ...rest } = fetchOptions; return { - ...fetchOptions, - ...body, + ...rest, + ...(body !== undefined ? { body: JSON.stringify(body) } : {}), query: { ...fetchOptions.query, ...(debugEnabled ? { _debug: true } : {}) diff --git a/x-pack/legacy/plugins/apm/public/services/rest/ml.ts b/x-pack/legacy/plugins/apm/public/services/rest/ml.ts index 28b14fa722bbd..e495a8968a7f3 100644 --- a/x-pack/legacy/plugins/apm/public/services/rest/ml.ts +++ b/x-pack/legacy/plugins/apm/public/services/rest/ml.ts @@ -61,7 +61,7 @@ export async function startMLJob({ return callApi(http, { method: 'POST', pathname: `/api/ml/modules/setup/apm_transaction`, - body: JSON.stringify({ + body: { prefix: getMlPrefix(serviceName, transactionType), groups, indexPatternName: transactionIndices, @@ -71,7 +71,7 @@ export async function startMLJob({ filter } } - }) + } }); } diff --git a/x-pack/legacy/plugins/apm/scripts/kibana-security/setup-custom-kibana-user-role.ts b/x-pack/legacy/plugins/apm/scripts/kibana-security/setup-custom-kibana-user-role.ts index ae9174d678ba5..57b169c8ab1d8 100644 --- a/x-pack/legacy/plugins/apm/scripts/kibana-security/setup-custom-kibana-user-role.ts +++ b/x-pack/legacy/plugins/apm/scripts/kibana-security/setup-custom-kibana-user-role.ts @@ -69,7 +69,8 @@ async function init() { return; } - if (!isSecurityEnabled()) { + const isEnabled = await isSecurityEnabled(); + if (!isEnabled) { console.log('Security must be enabled!'); return; } diff --git a/x-pack/legacy/plugins/apm/server/routes/create_api/index.test.ts b/x-pack/legacy/plugins/apm/server/routes/create_api/index.test.ts index 3a74c4377920a..309e503c4a497 100644 --- a/x-pack/legacy/plugins/apm/server/routes/create_api/index.test.ts +++ b/x-pack/legacy/plugins/apm/server/routes/create_api/index.test.ts @@ -131,7 +131,7 @@ describe('createApi', () => { // stub default values params: {}, query: {}, - body: {}, + body: null, ...requestMock }, responseMock @@ -144,7 +144,7 @@ describe('createApi', () => { it('adds a _debug query parameter by default', async () => { const { simulate, handlerMock, responseMock } = initApi({}); - await simulate({ query: { _debug: true } }); + await simulate({ query: { _debug: 'true' } }); expect(handlerMock).toHaveBeenCalledTimes(1); @@ -288,7 +288,7 @@ describe('createApi', () => { await simulate({ query: { bar: '', - _debug: true + _debug: 'true' } }); diff --git a/x-pack/legacy/plugins/apm/server/routes/create_api/index.ts b/x-pack/legacy/plugins/apm/server/routes/create_api/index.ts index 2bbd8b6ddfb62..3e97d851acd29 100644 --- a/x-pack/legacy/plugins/apm/server/routes/create_api/index.ts +++ b/x-pack/legacy/plugins/apm/server/routes/create_api/index.ts @@ -18,8 +18,9 @@ import { Route, Params } from '../typings'; +import { jsonRt } from '../../../common/runtime_types/json_rt'; -const debugRt = t.partial({ _debug: t.boolean }); +const debugRt = t.partial({ _debug: jsonRt.pipe(t.boolean) }); export function createApi() { const factoryFns: Array> = []; @@ -53,28 +54,37 @@ export function createApi() { | 'get' | 'delete'; - const bodyRt = params.body; - const fallbackBodyRt = bodyRt || t.strict({}); + // For all runtime types with props, we create an exact + // version that will strip all keys that are unvalidated. + + const bodyRt = + params.body && 'props' in params.body + ? t.exact(params.body) + : params.body; const rts = { - // add _debug query parameter to all routes + // Add _debug query parameter to all routes query: params.query ? t.exact(t.intersection([params.query, debugRt])) : t.exact(debugRt), path: params.path ? t.exact(params.path) : t.strict({}), - body: bodyRt && 'props' in bodyRt ? t.exact(bodyRt) : fallbackBodyRt + body: bodyRt || t.null }; + const anyObject = schema.object({}, { allowUnknowns: true }); + (router[routerMethod] as RouteRegistrar)( { path, options, validate: { - ...(routerMethod === 'get' - ? {} - : { body: schema.object({}, { allowUnknowns: true }) }), - params: schema.object({}, { allowUnknowns: true }), - query: schema.object({}, { allowUnknowns: true }) + // `body` can be null, but `validate` expects non-nullable types + // if any validation is defined. Not having validation currently + // means we don't get the payload. See + // https://github.com/elastic/kibana/issues/50179 + body: schema.nullable(anyObject) as typeof anyObject, + params: anyObject, + query: anyObject } }, async (context, request, response) => { @@ -83,7 +93,7 @@ export function createApi() { path: request.params, body: request.body, query: { - _debug: false, + _debug: 'false', ...request.query } }; @@ -100,6 +110,9 @@ export function createApi() { throw Boom.badRequest(PathReporter.report(result)[0]); } + // `io-ts` has stripped unvalidated keys, so we can compare + // the output with the input to see if all object keys are + // known and validated. const strippedKeys = difference( Object.keys(value || {}), Object.keys(result.right || {}) @@ -124,7 +137,9 @@ export function createApi() { context: { ...context, __LEGACY, - // only return values for parameters that have runtime types + // Only return values for parameters that have runtime types, + // but always include query as _debug is always set even if + // it's not defined in the route. params: pick(parsedParams, ...Object.keys(params), 'query'), config, logger diff --git a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/decrypt_job_headers.test.ts b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/decrypt_job_headers.test.ts index 8c78143677214..9ba7cfbcac1d8 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/decrypt_job_headers.test.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/decrypt_job_headers.test.ts @@ -4,10 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -// @ts-ignore import { cryptoFactory } from '../../../server/lib/crypto'; import { createMockServer } from '../../../test_helpers/create_mock_server'; -import { decryptJobHeaders } from './index'; +import { Logger } from '../../../types'; +import { decryptJobHeaders } from './decrypt_job_headers'; let mockServer: any; beforeEach(() => { @@ -24,17 +24,16 @@ describe('headers', () => { await expect( decryptJobHeaders({ job: { - title: 'cool-job-bro', - type: 'csv', - jobParams: { - savedObjectId: 'abc-123', - isImmediate: false, - savedObjectType: 'search', - }, + headers: 'Q53+9A+zf+Xe+ceR/uB/aR/Sw/8e+M+qR+WiG+8z+EY+mo+HiU/zQL+Xn', }, + logger: ({ + error: jest.fn(), + } as unknown) as Logger, server: mockServer, }) - ).rejects.toBeDefined(); + ).rejects.toMatchInlineSnapshot( + `[Error: Failed to decrypt report job data. Please ensure that xpack.reporting.encryptionKey is set and re-generate this report. Error: Invalid IV length]` + ); }); test(`passes back decrypted headers that were passed in`, async () => { @@ -48,13 +47,9 @@ describe('headers', () => { job: { title: 'cool-job-bro', type: 'csv', - jobParams: { - savedObjectId: 'abc-123', - isImmediate: false, - savedObjectType: 'search', - }, headers: encryptedHeaders, }, + logger: {} as Logger, server: mockServer, }); expect(decryptedHeaders).toEqual(headers); diff --git a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/decrypt_job_headers.ts b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/decrypt_job_headers.ts index 887f4dbb11be7..486181117bbfb 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/decrypt_job_headers.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/decrypt_job_headers.ts @@ -3,18 +3,48 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -// @ts-ignore + +import { i18n } from '@kbn/i18n'; import { cryptoFactory } from '../../../server/lib/crypto'; -import { CryptoFactory, JobDocPayload, ServerFacade } from '../../../types'; +import { CryptoFactory, ServerFacade, Logger } from '../../../types'; + +interface HasEncryptedHeaders { + headers?: string; +} -export const decryptJobHeaders = async ({ +// TODO merge functionality with CSV execute job +export const decryptJobHeaders = async < + JobParamsType, + JobDocPayloadType extends HasEncryptedHeaders +>({ job, server, + logger, }: { - job: JobDocPayload; + job: JobDocPayloadType; server: ServerFacade; -}) => { + logger: Logger; +}): Promise<{ + job: JobDocPayloadType; + server: ServerFacade; + decryptedHeaders: Record; +}> => { const crypto: CryptoFactory = cryptoFactory(server); - const decryptedHeaders: string = await crypto.decrypt(job.headers); - return { job, decryptedHeaders, server }; + try { + const decryptedHeaders: Record = await crypto.decrypt(job.headers); + return { job, decryptedHeaders, server }; + } catch (err) { + logger.error(err); + + throw new Error( + i18n.translate( + 'xpack.reporting.exportTypes.common.failedToDecryptReportJobDataErrorMessage', + { + defaultMessage: + 'Failed to decrypt report job data. Please ensure that {encryptionKey} is set and re-generate this report. {err}', + values: { encryptionKey: 'xpack.reporting.encryptionKey', err: err.toString() }, + } + ) + ); + } }; diff --git a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_conditional_headers.test.ts b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_conditional_headers.test.ts index 5a3c8d9f55f75..66990c1f37df4 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_conditional_headers.test.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_conditional_headers.test.ts @@ -28,7 +28,7 @@ describe('conditions', () => { }; const { conditionalHeaders } = await getConditionalHeaders({ - job: {} as JobDocPayload, + job: {} as JobDocPayload, filteredHeaders: permittedHeaders, server: mockServer, }); @@ -45,7 +45,7 @@ describe('conditions', () => { }; const { conditionalHeaders } = await getConditionalHeaders({ - job: {} as JobDocPayload, + job: {} as JobDocPayload, filteredHeaders: permittedHeaders, server: mockServer, }); @@ -66,7 +66,7 @@ describe('conditions', () => { }; const { conditionalHeaders } = await getConditionalHeaders({ - job: {} as JobDocPayload, + job: {} as JobDocPayload, filteredHeaders: permittedHeaders, server: mockServer, }); @@ -83,7 +83,7 @@ describe('conditions', () => { }; const { conditionalHeaders } = await getConditionalHeaders({ - job: {} as JobDocPayload, + job: {} as JobDocPayload, filteredHeaders: permittedHeaders, server: mockServer, }); @@ -98,7 +98,7 @@ describe('conditions', () => { }; const { conditionalHeaders } = await getConditionalHeaders({ - job: {} as JobDocPayload, + job: {} as JobDocPayload, filteredHeaders: permittedHeaders, server: mockServer, }); @@ -121,7 +121,7 @@ describe('conditions', () => { }; const { conditionalHeaders } = await getConditionalHeaders({ - job: {} as JobDocPayload, + job: {} as JobDocPayload, filteredHeaders: permittedHeaders, server: mockServer, }); @@ -138,7 +138,7 @@ describe('conditions', () => { }; const { conditionalHeaders } = await getConditionalHeaders({ - job: {} as JobDocPayload, + job: {} as JobDocPayload, filteredHeaders: permittedHeaders, server: mockServer, }); @@ -154,7 +154,7 @@ test('uses basePath from job when creating saved object service', async () => { }; const { conditionalHeaders } = await getConditionalHeaders({ - job: {} as JobDocPayload, + job: {} as JobDocPayload, filteredHeaders: permittedHeaders, server: mockServer, }); @@ -181,7 +181,7 @@ test(`uses basePath from server if job doesn't have a basePath when creating sav }; const { conditionalHeaders } = await getConditionalHeaders({ - job: {} as JobDocPayload, + job: {} as JobDocPayload, filteredHeaders: permittedHeaders, server: mockServer, }); @@ -204,7 +204,7 @@ describe('config formatting', () => { test(`lowercases server.host`, async () => { mockServer = createMockServer({ settings: { 'server.host': 'COOL-HOSTNAME' } }); const { conditionalHeaders } = await getConditionalHeaders({ - job: {} as JobDocPayload, + job: {} as JobDocPayload, filteredHeaders: {}, server: mockServer, }); diff --git a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_conditional_headers.ts b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_conditional_headers.ts index 9522d6c087a89..14c092ccfb4a6 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_conditional_headers.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_conditional_headers.ts @@ -3,14 +3,14 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { ConditionalHeaders, JobDocPayload, ServerFacade } from '../../../types'; +import { ConditionalHeaders, ServerFacade } from '../../../types'; -export const getConditionalHeaders = ({ +export const getConditionalHeaders = ({ job, filteredHeaders, server, }: { - job: JobDocPayload; + job: JobDocPayloadType; filteredHeaders: Record; server: ServerFacade; }) => { diff --git a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_full_urls.test.ts b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_full_urls.test.ts index 024c79f2861f1..60735b4abd446 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_full_urls.test.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_full_urls.test.ts @@ -5,10 +5,17 @@ */ import { createMockServer } from '../../../test_helpers/create_mock_server'; +import { ServerFacade } from '../../../types'; import { JobDocPayloadPNG } from '../../png/types'; import { JobDocPayloadPDF } from '../../printable_pdf/types'; import { getFullUrls } from './get_full_urls'; +interface FullUrlsOpts { + job: JobDocPayloadPNG & JobDocPayloadPDF; + server: ServerFacade; + conditionalHeaders: any; +} + let mockServer: any; beforeEach(() => { mockServer = createMockServer(''); @@ -17,9 +24,9 @@ beforeEach(() => { test(`fails if no URL is passed`, async () => { await expect( getFullUrls({ - job: {} as JobDocPayloadPNG, + job: {}, server: mockServer, - }) + } as FullUrlsOpts) ).rejects.toMatchInlineSnapshot( `[Error: No valid URL fields found in Job Params! Expected \`job.relativeUrl\` or \`job.objects[{ relativeUrl }]\`]` ); @@ -33,9 +40,9 @@ test(`fails if URLs are file-protocols for PNGs`, async () => { job: { relativeUrl, forceNow, - } as JobDocPayloadPNG, + }, server: mockServer, - }) + } as FullUrlsOpts) ).rejects.toMatchInlineSnapshot( `[Error: Found invalid URL(s), all URLs must be relative: ${relativeUrl}]` ); @@ -50,9 +57,9 @@ test(`fails if URLs are absolute for PNGs`, async () => { job: { relativeUrl, forceNow, - } as JobDocPayloadPNG, + }, server: mockServer, - }) + } as FullUrlsOpts) ).rejects.toMatchInlineSnapshot( `[Error: Found invalid URL(s), all URLs must be relative: ${relativeUrl}]` ); @@ -70,9 +77,9 @@ test(`fails if URLs are file-protocols for PDF`, async () => { }, ], forceNow, - } as JobDocPayloadPDF, + }, server: mockServer, - }) + } as FullUrlsOpts) ).rejects.toMatchInlineSnapshot( `[Error: Found invalid URL(s), all URLs must be relative: ${relativeUrl}]` ); @@ -91,9 +98,9 @@ test(`fails if URLs are absolute for PDF`, async () => { }, ], forceNow, - } as JobDocPayloadPDF, + }, server: mockServer, - }) + } as FullUrlsOpts) ).rejects.toMatchInlineSnapshot( `[Error: Found invalid URL(s), all URLs must be relative: ${relativeUrl}]` ); @@ -118,9 +125,9 @@ test(`fails if any URLs are absolute or file's for PDF`, async () => { job: { objects, forceNow, - } as JobDocPayloadPDF, + }, server: mockServer, - }) + } as FullUrlsOpts) ).rejects.toMatchInlineSnapshot( `[Error: Found invalid URL(s), all URLs must be relative: ${objects[1].relativeUrl} ${objects[2].relativeUrl}]` ); @@ -131,9 +138,9 @@ test(`fails if URL does not route to a visualization`, async () => { getFullUrls({ job: { relativeUrl: '/app/phoney', - } as JobDocPayloadPNG, + }, server: mockServer, - }) + } as FullUrlsOpts) ).rejects.toMatchInlineSnapshot( `[Error: No valid hash in the URL! A hash is expected for the application to route to the intended visualization.]` ); @@ -145,9 +152,9 @@ test(`adds forceNow to hash's query, if it exists`, async () => { job: { relativeUrl: '/app/kibana#/something', forceNow, - } as JobDocPayloadPNG, + }, server: mockServer, - }); + } as FullUrlsOpts); expect(urls[0]).toEqual( 'http://localhost:5601/sbp/app/kibana#/something?forceNow=2000-01-01T00%3A00%3A00.000Z' @@ -161,9 +168,9 @@ test(`appends forceNow to hash's query, if it exists`, async () => { job: { relativeUrl: '/app/kibana#/something?_g=something', forceNow, - } as JobDocPayloadPNG, + }, server: mockServer, - }); + } as FullUrlsOpts); expect(urls[0]).toEqual( 'http://localhost:5601/sbp/app/kibana#/something?_g=something&forceNow=2000-01-01T00%3A00%3A00.000Z' @@ -174,9 +181,9 @@ test(`doesn't append forceNow query to url, if it doesn't exists`, async () => { const { urls } = await getFullUrls({ job: { relativeUrl: '/app/kibana#/something', - } as JobDocPayloadPNG, + }, server: mockServer, - }); + } as FullUrlsOpts); expect(urls[0]).toEqual('http://localhost:5601/sbp/app/kibana#/something'); }); @@ -192,9 +199,9 @@ test(`adds forceNow to each of multiple urls`, async () => { { relativeUrl: '/app/kibana#/something_ddd' }, ], forceNow, - } as JobDocPayloadPDF, + }, server: mockServer, - }); + } as FullUrlsOpts); expect(urls).toEqual([ 'http://localhost:5601/sbp/app/kibana#/something_aaa?forceNow=2000-01-01T00%3A00%3A00.000Z', diff --git a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_full_urls.ts b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_full_urls.ts index 2b66c77067ed2..59c748aba9662 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_full_urls.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_full_urls.ts @@ -12,21 +12,26 @@ import { } from 'url'; import { getAbsoluteUrlFactory } from '../../../common/get_absolute_url'; import { validateUrls } from '../../../common/validate_urls'; -import { ServerFacade } from '../../../types'; +import { ServerFacade, ConditionalHeaders } from '../../../types'; import { JobDocPayloadPNG } from '../../png/types'; import { JobDocPayloadPDF } from '../../printable_pdf/types'; -interface KeyedRelativeUrl { - relativeUrl: string; +function isPngJob(job: JobDocPayloadPNG | JobDocPayloadPDF): job is JobDocPayloadPNG { + return (job as JobDocPayloadPNG).relativeUrl !== undefined; +} +function isPdfJob(job: JobDocPayloadPNG | JobDocPayloadPDF): job is JobDocPayloadPDF { + return (job as JobDocPayloadPDF).objects !== undefined; } -export async function getFullUrls({ +export async function getFullUrls({ job, server, ...mergeValues // pass-throughs }: { - job: JobDocPayloadPNG | JobDocPayloadPDF; + job: JobDocPayloadPDF | JobDocPayloadPNG; server: ServerFacade; + conditionalHeaders: ConditionalHeaders; + logo?: string; }) { const config = server.config(); @@ -40,12 +45,10 @@ export async function getFullUrls({ // PDF and PNG job params put in the url differently let relativeUrls: string[] = []; - if (job.relativeUrl) { - // single page (png) + if (isPngJob(job)) { relativeUrls = [job.relativeUrl]; - } else if (job.objects) { - // multi page (pdf) - relativeUrls = job.objects.map((obj: KeyedRelativeUrl) => obj.relativeUrl); + } else if (isPdfJob(job)) { + relativeUrls = job.objects.map(obj => obj.relativeUrl); } else { throw new Error( `No valid URL fields found in Job Params! Expected \`job.relativeUrl\` or \`job.objects[{ relativeUrl }]\`` @@ -93,5 +96,5 @@ export async function getFullUrls({ }); }); - return { job, urls, server, ...mergeValues }; + return { job, server, urls, ...mergeValues }; } diff --git a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/omit_blacklisted_headers.ts b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/omit_blacklisted_headers.ts index a0aa4d973298d..1bd52a0f1b2d2 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/omit_blacklisted_headers.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/omit_blacklisted_headers.ts @@ -5,14 +5,14 @@ */ import { omit } from 'lodash'; import { KBN_SCREENSHOT_HEADER_BLACKLIST } from '../../../common/constants'; -import { JobDocPayload, ServerFacade } from '../../../types'; +import { ServerFacade } from '../../../types'; -export const omitBlacklistedHeaders = ({ +export const omitBlacklistedHeaders = ({ job, decryptedHeaders, server, }: { - job: JobDocPayload; + job: JobDocPayloadType; decryptedHeaders: Record; server: ServerFacade; }) => { diff --git a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/index.ts b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/index.ts index 30bbac61b0248..2b4411584d752 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/index.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/index.ts @@ -10,7 +10,7 @@ import { ServerFacade, CaptureConfig } from '../../../../types'; import { HeadlessChromiumDriver as HeadlessBrowser } from '../../../../server/browsers/chromium/driver'; import { ElementsPositionAndAttribute, - Screenshot, + ScreenshotResults, ScreenshotObservableOpts, TimeRange, } from './types'; @@ -26,11 +26,6 @@ import { getElementPositionAndAttributes } from './get_element_position_data'; import { getScreenshots } from './get_screenshots'; import { skipTelemetry } from './skip_telemetry'; -interface ScreenshotResults { - timeRange: TimeRange; - screenshots: Screenshot[]; -} - export function screenshotsObservableFactory(server: ServerFacade) { const config = server.config(); const captureConfig: CaptureConfig = config.get('xpack.reporting.capture'); @@ -48,7 +43,7 @@ export function screenshotsObservableFactory(server: ServerFacade) { browserTimezone, }); - // @ts-ignore this needs to be refactored to use less random type declaration and instead rely on structures that work with inference + // @ts-ignore this needs to be refactored to use less random type declaration and instead rely on structures that work with inference TODO return create$.pipe( mergeMap(({ driver$, exit$ }) => { const screenshot$ = driver$.pipe( diff --git a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/types.ts b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/types.ts index 249cc14026aa4..4f461ef4ec5f9 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/types.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/types.ts @@ -30,7 +30,12 @@ export interface ElementsPositionAndAttribute { } export interface Screenshot { - base64EncodedData: string; + base64EncodedData: Buffer; title: string; description: string; } + +export interface ScreenshotResults { + timeRange: TimeRange; + screenshots: Screenshot[]; +} diff --git a/x-pack/legacy/plugins/reporting/export_types/csv/metadata.js b/x-pack/legacy/plugins/reporting/export_types/csv/metadata.ts similarity index 95% rename from x-pack/legacy/plugins/reporting/export_types/csv/metadata.js rename to x-pack/legacy/plugins/reporting/export_types/csv/metadata.ts index 932799e404423..5e72fbb8ce147 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv/metadata.js +++ b/x-pack/legacy/plugins/reporting/export_types/csv/metadata.ts @@ -6,5 +6,5 @@ export const metadata = { id: 'csv', - name: 'CSV' + name: 'CSV', }; diff --git a/x-pack/legacy/plugins/reporting/export_types/csv/server/create_job.ts b/x-pack/legacy/plugins/reporting/export_types/csv/server/create_job.ts index 7cfed0d09a4fb..063ac7f77704c 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv/server/create_job.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv/server/create_job.ts @@ -5,15 +5,23 @@ */ import { cryptoFactory } from '../../../server/lib/crypto'; -import { ConditionalHeaders, ServerFacade, RequestFacade } from '../../../types'; +import { + CreateJobFactory, + ConditionalHeaders, + ServerFacade, + RequestFacade, + ESQueueCreateJobFn, +} from '../../../types'; import { JobParamsDiscoverCsv } from '../types'; -export const createJobFactory = function createJobFn(server: ServerFacade) { +export const createJobFactory: CreateJobFactory> = function createJobFactoryFn(server: ServerFacade) { const crypto = cryptoFactory(server); return async function createJob( jobParams: JobParamsDiscoverCsv, - headers: ConditionalHeaders, + headers: ConditionalHeaders['headers'], request: RequestFacade ) { const serializedEncryptedHeaders = await crypto.encrypt(headers); diff --git a/x-pack/legacy/plugins/reporting/export_types/csv/server/execute_job.js b/x-pack/legacy/plugins/reporting/export_types/csv/server/execute_job.ts similarity index 85% rename from x-pack/legacy/plugins/reporting/export_types/csv/server/execute_job.js rename to x-pack/legacy/plugins/reporting/export_types/csv/server/execute_job.ts index 19656a94c6a46..fef45f5a5eae8 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv/server/execute_job.js +++ b/x-pack/legacy/plugins/reporting/export_types/csv/server/execute_job.ts @@ -4,20 +4,30 @@ * you may not use this file except in compliance with the Elastic License. */ +import { i18n } from '@kbn/i18n'; +import { ExecuteJobFactory, ESQueueWorkerExecuteFn, ServerFacade } from '../../../types'; import { CSV_JOB_TYPE, PLUGIN_ID } from '../../../common/constants'; import { cryptoFactory, LevelLogger } from '../../../server/lib'; +import { JobDocPayloadDiscoverCsv } from '../types'; +// @ts-ignore untyped module TODO import { createGenerateCsv } from './lib/generate_csv'; +// @ts-ignore untyped module TODO import { fieldFormatMapFactory } from './lib/field_format_map'; -import { i18n } from '@kbn/i18n'; -export function executeJobFactory(server) { +export const executeJobFactory: ExecuteJobFactory> = function executeJobFactoryFn(server: ServerFacade) { const { callWithRequest } = server.plugins.elasticsearch.getCluster('data'); const crypto = cryptoFactory(server); const config = server.config(); const logger = LevelLogger.createForServer(server, [PLUGIN_ID, CSV_JOB_TYPE, 'execute-job']); const serverBasePath = config.get('server.basePath'); - return async function executeJob(jobId, job, cancellationToken) { + return async function executeJob( + jobId: string, + job: JobDocPayloadDiscoverCsv, + cancellationToken: any + ) { const jobLogger = logger.clone([jobId]); const { @@ -65,7 +75,7 @@ export function executeJobFactory(server) { }, }; - const callEndpoint = (endpoint, clientParams = {}, options = {}) => { + const callEndpoint = (endpoint: string, clientParams = {}, options = {}) => { return callWithRequest(fakeRequest, endpoint, clientParams, options); }; const savedObjects = server.savedObjects; @@ -76,6 +86,7 @@ export function executeJobFactory(server) { const [formatsMap, uiSettings] = await Promise.all([ (async () => { + // @ts-ignore fieldFormatServiceFactory' does not exist on type 'ServerFacade TODO const fieldFormats = await server.fieldFormatServiceFactory(uiConfig); return fieldFormatMapFactory(indexPatternSavedObject, fieldFormats); })(), @@ -125,4 +136,4 @@ export function executeJobFactory(server) { csv_contains_formulas: csvContainsFormulas, }; }; -} +}; diff --git a/x-pack/legacy/plugins/reporting/export_types/csv/server/index.js b/x-pack/legacy/plugins/reporting/export_types/csv/server/index.ts similarity index 85% rename from x-pack/legacy/plugins/reporting/export_types/csv/server/index.js rename to x-pack/legacy/plugins/reporting/export_types/csv/server/index.ts index f41f6ca9a1580..d752cdcd9779d 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv/server/index.js +++ b/x-pack/legacy/plugins/reporting/export_types/csv/server/index.ts @@ -4,12 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ +import { ExportTypesRegistry } from '../../../types'; import { createJobFactory } from './create_job'; import { executeJobFactory } from './execute_job'; import { metadata } from '../metadata'; import { CSV_JOB_TYPE as jobType } from '../../../common/constants'; -export function register(registry) { +export function register(registry: ExportTypesRegistry) { registry.register({ ...metadata, jobType, diff --git a/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/check_cells_for_formulas.test.ts b/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/check_cells_for_formulas.test.ts index 0107e77bb76ae..31f5a91e5a57b 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/check_cells_for_formulas.test.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv/server/lib/check_cells_for_formulas.test.ts @@ -84,8 +84,8 @@ describe(`Check CSV Injected values`, () => { checkIfRowsHaveFormulas( { _doc: 'foo-bar', - // @ts-ignore need to assert non-string values still return false - value: nonRow, + // need to assert non-string values still return false + value: (nonRow as unknown) as string, title: 'nice', }, ['_doc', 'value', 'title'] diff --git a/x-pack/legacy/plugins/reporting/export_types/csv/types.d.ts b/x-pack/legacy/plugins/reporting/export_types/csv/types.d.ts index 09f32833915b6..5070c69553cfa 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv/types.d.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv/types.d.ts @@ -15,19 +15,14 @@ export interface JobParamPostPayloadDiscoverCsv extends JobParamPostPayload { export interface JobParamsDiscoverCsv { indexPatternId?: string; - post?: JobParamPostPayloadDiscoverCsv; // delete this + post?: JobParamPostPayloadDiscoverCsv; } -export interface JobDocPayloadDiscoverCsv extends JobDocPayload { +export interface JobDocPayloadDiscoverCsv extends JobDocPayload { + basePath: string; searchRequest: any; fields: any; indexPatternSavedObject: any; metaFields: any; conflictedTypesFields: any; } - -export type ESQueueCreateJobFnDiscoverCsv = ( - jobParams: JobParamsDiscoverCsv, - headers: ConditionalHeaders, - request: RequestFacade -) => Promise; diff --git a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/create_job/create_job.ts b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/create_job/create_job.ts index a3e531d16a2e6..8443be2b25f4f 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/create_job/create_job.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/create_job/create_job.ts @@ -8,7 +8,12 @@ import { notFound, notImplemented } from 'boom'; import { get } from 'lodash'; import { PLUGIN_ID, CSV_FROM_SAVEDOBJECT_JOB_TYPE } from '../../../../common/constants'; import { cryptoFactory, LevelLogger } from '../../../../server/lib'; -import { ImmediateCreateJobFn, ServerFacade, RequestFacade } from '../../../../types'; +import { + CreateJobFactory, + ImmediateCreateJobFn, + ServerFacade, + RequestFacade, +} from '../../../../types'; import { SavedObject, SavedObjectServiceError, @@ -27,7 +32,9 @@ interface VisData { panel: SearchPanel; } -export function createJobFactory(server: ServerFacade): ImmediateCreateJobFn { +export const createJobFactory: CreateJobFactory> = function createJobFactoryFn(server: ServerFacade) { const crypto = cryptoFactory(server); const logger = LevelLogger.createForServer(server, [ PLUGIN_ID, @@ -88,9 +95,8 @@ export function createJobFactory(server: ServerFacade): ImmediateCreateJobFn { return { headers: serializedEncryptedHeaders, jobParams: { ...jobParams, panel, visType }, - type: null, // resolved in executeJob - objects: null, // resolved in executeJob + type: null, title, }; }; -} +}; diff --git a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/execute_job.ts b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/execute_job.ts index d2284b73c7673..e161d7afc84e2 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/execute_job.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/execute_job.ts @@ -7,6 +7,7 @@ import { i18n } from '@kbn/i18n'; import { cryptoFactory, LevelLogger } from '../../../server/lib'; import { + ExecuteJobFactory, ImmediateExecuteFn, JobDocOutputExecuted, ServerFacade, @@ -26,7 +27,9 @@ import { } from '../types'; import { createGenerateCsv } from './lib'; -export function executeJobFactory(server: ServerFacade): ImmediateExecuteFn { +export const executeJobFactory: ExecuteJobFactory> = function executeJobFactoryFn(server: ServerFacade) { const crypto = cryptoFactory(server); const logger = LevelLogger.createForServer(server, [ PLUGIN_ID, @@ -118,4 +121,4 @@ export function executeJobFactory(server: ServerFacade): ImmediateExecuteFn { size, }; }; -} +}; diff --git a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/lib/generate_csv_search.ts b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/lib/generate_csv_search.ts index 0ab103f0ab4c7..081800d1d7b2d 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/lib/generate_csv_search.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/lib/generate_csv_search.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -// @ts-ignore no module definition +// @ts-ignore no module definition TODO import { createGenerateCsv } from '../../../csv/server/lib/generate_csv'; import { CancellationToken } from '../../../../common/cancellation_token'; import { ServerFacade, RequestFacade, Logger } from '../../../../types'; diff --git a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/types.d.ts b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/types.d.ts index a90b7e713e3ef..b6dd174410c11 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/types.d.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/types.d.ts @@ -25,8 +25,7 @@ export interface JobParamsPanelCsv { visType?: string; } -export interface JobDocPayloadPanelCsv extends JobDocPayload { - type: string | null; +export interface JobDocPayloadPanelCsv extends JobDocPayload { jobParams: JobParamsPanelCsv; } diff --git a/x-pack/legacy/plugins/reporting/export_types/png/metadata.js b/x-pack/legacy/plugins/reporting/export_types/png/metadata.ts similarity index 95% rename from x-pack/legacy/plugins/reporting/export_types/png/metadata.js rename to x-pack/legacy/plugins/reporting/export_types/png/metadata.ts index 8be016568d9f1..69831e86bd7ef 100644 --- a/x-pack/legacy/plugins/reporting/export_types/png/metadata.js +++ b/x-pack/legacy/plugins/reporting/export_types/png/metadata.ts @@ -6,5 +6,5 @@ export const metadata = { id: 'png', - name: 'PNG' + name: 'PNG', }; diff --git a/x-pack/legacy/plugins/reporting/export_types/png/server/create_job/index.ts b/x-pack/legacy/plugins/reporting/export_types/png/server/create_job/index.ts index a5b6c37b20c18..3f03246106d3e 100644 --- a/x-pack/legacy/plugins/reporting/export_types/png/server/create_job/index.ts +++ b/x-pack/legacy/plugins/reporting/export_types/png/server/create_job/index.ts @@ -4,17 +4,25 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ServerFacade, RequestFacade, ConditionalHeaders } from '../../../../types'; +import { + CreateJobFactory, + ServerFacade, + RequestFacade, + ESQueueCreateJobFn, + ConditionalHeaders, +} from '../../../../types'; import { validateUrls } from '../../../../common/validate_urls'; import { cryptoFactory } from '../../../../server/lib/crypto'; import { JobParamsPNG } from '../../types'; -export const createJobFactory = function createJobFn(server: ServerFacade) { +export const createJobFactory: CreateJobFactory> = function createJobFactoryFn(server: ServerFacade) { const crypto = cryptoFactory(server); return async function createJob( { objectType, title, relativeUrl, browserTimezone, layout }: JobParamsPNG, - headers: ConditionalHeaders, + headers: ConditionalHeaders['headers'], request: RequestFacade ) { const serializedEncryptedHeaders = await crypto.encrypt(headers); diff --git a/x-pack/legacy/plugins/reporting/export_types/png/server/execute_job/index.test.js b/x-pack/legacy/plugins/reporting/export_types/png/server/execute_job/index.test.js index 552d00833c4ed..867d537017f41 100644 --- a/x-pack/legacy/plugins/reporting/export_types/png/server/execute_job/index.test.js +++ b/x-pack/legacy/plugins/reporting/export_types/png/server/execute_job/index.test.js @@ -45,6 +45,7 @@ beforeEach(() => { getScopedSavedObjectsClient: jest.fn(), }, uiSettingsServiceFactory: jest.fn().mockReturnValue({ get: jest.fn() }), + log: jest.fn(), }; mockServer.config().get.mockImplementation((key) => { diff --git a/x-pack/legacy/plugins/reporting/export_types/png/server/execute_job/index.js b/x-pack/legacy/plugins/reporting/export_types/png/server/execute_job/index.ts similarity index 63% rename from x-pack/legacy/plugins/reporting/export_types/png/server/execute_job/index.js rename to x-pack/legacy/plugins/reporting/export_types/png/server/execute_job/index.ts index 7c6ca8520c51e..6678a83079d31 100644 --- a/x-pack/legacy/plugins/reporting/export_types/png/server/execute_job/index.js +++ b/x-pack/legacy/plugins/reporting/export_types/png/server/execute_job/index.ts @@ -5,39 +5,33 @@ */ import * as Rx from 'rxjs'; -import { i18n } from '@kbn/i18n'; import { mergeMap, catchError, map, takeUntil } from 'rxjs/operators'; import { PLUGIN_ID, PNG_JOB_TYPE } from '../../../../common/constants'; +import { ServerFacade, ExecuteJobFactory, ESQueueWorkerExecuteFn } from '../../../../types'; import { LevelLogger } from '../../../../server/lib'; -import { generatePngObservableFactory } from '../lib/generate_png'; import { decryptJobHeaders, omitBlacklistedHeaders, getConditionalHeaders, getFullUrls, } from '../../../common/execute_job/'; +import { JobDocPayloadPNG } from '../../types'; +import { generatePngObservableFactory } from '../lib/generate_png'; -export function executeJobFactory(server) { +export const executeJobFactory: ExecuteJobFactory> = function executeJobFactoryFn(server: ServerFacade) { const generatePngObservable = generatePngObservableFactory(server); const logger = LevelLogger.createForServer(server, [PLUGIN_ID, PNG_JOB_TYPE, 'execute']); - return function executeJob(jobId, jobToExecute, cancellationToken) { + return function executeJob( + jobId: string, + jobToExecute: JobDocPayloadPNG, + cancellationToken: any + ) { const jobLogger = logger.clone([jobId]); - const process$ = Rx.of({ job: jobToExecute, server }).pipe( + const process$ = Rx.of({ job: jobToExecute, server, logger }).pipe( mergeMap(decryptJobHeaders), - catchError(err => { - jobLogger.error(err); - return Rx.throwError( - i18n.translate( - 'xpack.reporting.exportTypes.png.compShim.failedToDecryptReportJobDataErrorMessage', - { - defaultMessage: - 'Failed to decrypt report job data. Please ensure that {encryptionKey} is set and re-generate this report. {err}', - values: { encryptionKey: 'xpack.reporting.encryptionKey', err: err.toString() }, - } - ) - ); - }), map(omitBlacklistedHeaders), map(getConditionalHeaders), mergeMap(getFullUrls), @@ -51,11 +45,13 @@ export function executeJobFactory(server) { job.layout ); }), - map(buffer => ({ - content_type: 'image/png', - content: buffer.toString('base64'), - size: buffer.byteLength, - })), + map((buffer: Buffer) => { + return { + content_type: 'image/png', + content: buffer.toString('base64'), + size: buffer.byteLength, + }; + }), catchError(err => { jobLogger.error(err); return Rx.throwError(err); @@ -63,7 +59,6 @@ export function executeJobFactory(server) { ); const stop$ = Rx.fromEventPattern(cancellationToken.on); - return process$.pipe(takeUntil(stop$)).toPromise(); }; -} +}; diff --git a/x-pack/legacy/plugins/reporting/export_types/png/server/index.js b/x-pack/legacy/plugins/reporting/export_types/png/server/index.ts similarity index 85% rename from x-pack/legacy/plugins/reporting/export_types/png/server/index.js rename to x-pack/legacy/plugins/reporting/export_types/png/server/index.ts index 65802491b89b1..a569719f02324 100644 --- a/x-pack/legacy/plugins/reporting/export_types/png/server/index.js +++ b/x-pack/legacy/plugins/reporting/export_types/png/server/index.ts @@ -4,12 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ +import { ExportTypesRegistry } from '../../../types'; import { createJobFactory } from './create_job'; import { executeJobFactory } from './execute_job'; import { metadata } from '../metadata'; import { PNG_JOB_TYPE as jobType } from '../../../common/constants'; -export function register(registry) { +export function register(registry: ExportTypesRegistry) { registry.register({ ...metadata, jobType, diff --git a/x-pack/legacy/plugins/reporting/export_types/png/server/lib/generate_png.ts b/x-pack/legacy/plugins/reporting/export_types/png/server/lib/generate_png.ts index 81b37ecf74f73..90aeea25db858 100644 --- a/x-pack/legacy/plugins/reporting/export_types/png/server/lib/generate_png.ts +++ b/x-pack/legacy/plugins/reporting/export_types/png/server/lib/generate_png.ts @@ -5,40 +5,15 @@ */ import * as Rx from 'rxjs'; -import { toArray, mergeMap } from 'rxjs/operators'; +import { map } from 'rxjs/operators'; import { LevelLogger } from '../../../../server/lib'; import { ServerFacade, ConditionalHeaders } from '../../../../types'; import { screenshotsObservableFactory } from '../../../common/lib/screenshots'; import { PreserveLayout } from '../../../common/layouts/preserve_layout'; import { LayoutParams } from '../../../common/layouts/layout'; -interface ScreenshotData { - base64EncodedData: string; -} - -interface UrlScreenshot { - screenshots: ScreenshotData[]; -} - export function generatePngObservableFactory(server: ServerFacade) { const screenshotsObservable = screenshotsObservableFactory(server); - const captureConcurrency = 1; - - // prettier-ignore - const createPngWithScreenshots = async ({ urlScreenshots }: { urlScreenshots: UrlScreenshot[] }): Promise => { - if (urlScreenshots.length !== 1) { - throw new Error( - `Expected there to be 1 URL screenshot, but there are ${urlScreenshots.length}` - ); - } - if (urlScreenshots[0].screenshots.length !== 1) { - throw new Error( - `Expected there to be 1 screenshot, but there are ${urlScreenshots[0].screenshots.length}` - ); - } - - return urlScreenshots[0].screenshots[0].base64EncodedData; - }; return function generatePngObservable( logger: LevelLogger, @@ -46,24 +21,30 @@ export function generatePngObservableFactory(server: ServerFacade) { browserTimezone: string, conditionalHeaders: ConditionalHeaders, layoutParams: LayoutParams - ): Rx.Observable { + ): Rx.Observable { if (!layoutParams || !layoutParams.dimensions) { throw new Error(`LayoutParams.Dimensions is undefined.`); } const layout = new PreserveLayout(layoutParams.dimensions); - const screenshots$ = Rx.of(url).pipe( - mergeMap( - iUrl => - screenshotsObservable({ logger, url: iUrl, conditionalHeaders, layout, browserTimezone }), - (jUrl: string, screenshot: UrlScreenshot) => screenshot, - captureConcurrency - ) + const screenshots$ = screenshotsObservable({ + logger, + url, + conditionalHeaders, + layout, + browserTimezone, + }).pipe( + map(urlScreenshots => { + if (urlScreenshots.screenshots.length !== 1) { + throw new Error( + `Expected there to be 1 screenshot, but there are ${urlScreenshots.screenshots.length}` + ); + } + + return urlScreenshots.screenshots[0].base64EncodedData; + }) ); - return screenshots$.pipe( - toArray(), - mergeMap(urlScreenshots => createPngWithScreenshots({ urlScreenshots })) - ); + return screenshots$; }; } diff --git a/x-pack/legacy/plugins/reporting/export_types/png/types.d.ts b/x-pack/legacy/plugins/reporting/export_types/png/types.d.ts index 895c1fa91d28f..4f5f295f33f4a 100644 --- a/x-pack/legacy/plugins/reporting/export_types/png/types.d.ts +++ b/x-pack/legacy/plugins/reporting/export_types/png/types.d.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { LayoutInstance } from '../common/layouts/layout'; +import { LayoutInstance, LayoutParams } from '../common/layouts/layout'; import { ConditionalHeaders, JobDocPayload, RequestFacade } from '../../types'; // Job params: structure of incoming user request data @@ -17,17 +17,10 @@ export interface JobParamsPNG { } // Job payload: structure of stored job data provided by create_job -export interface JobDocPayloadPNG extends JobDocPayload { +export interface JobDocPayloadPNG extends JobDocPayload { basePath?: string; browserTimezone: string; forceNow?: string; - layout: LayoutInstance; + layout: LayoutParams; relativeUrl: string; - objects: undefined; } - -export type ESQueueCreateJobFnPNG = ( - jobParams: JobParamsPNG, - headers: ConditionalHeaders, - request: RequestFacade -) => Promise; diff --git a/x-pack/legacy/plugins/reporting/export_types/printable_pdf/metadata.js b/x-pack/legacy/plugins/reporting/export_types/printable_pdf/metadata.ts similarity index 95% rename from x-pack/legacy/plugins/reporting/export_types/printable_pdf/metadata.js rename to x-pack/legacy/plugins/reporting/export_types/printable_pdf/metadata.ts index 53352910daeba..53e9699ac7e4e 100644 --- a/x-pack/legacy/plugins/reporting/export_types/printable_pdf/metadata.js +++ b/x-pack/legacy/plugins/reporting/export_types/printable_pdf/metadata.ts @@ -6,5 +6,5 @@ export const metadata = { id: 'printablePdf', - name: 'PDF' + name: 'PDF', }; diff --git a/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/create_job/index.js b/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/create_job/index.ts similarity index 70% rename from x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/create_job/index.js rename to x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/create_job/index.ts index d6c6eb7eb2007..d17713057abc1 100644 --- a/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/create_job/index.js +++ b/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/create_job/index.ts @@ -5,20 +5,39 @@ */ import { PLUGIN_ID, PDF_JOB_TYPE } from '../../../../common/constants'; +import { + CreateJobFactory, + ESQueueCreateJobFn, + ServerFacade, + RequestFacade, + ConditionalHeaders, +} from '../../../../types'; import { validateUrls } from '../../../../common/validate_urls'; import { LevelLogger } from '../../../../server/lib'; import { cryptoFactory } from '../../../../server/lib/crypto'; +import { JobParamsPDF } from '../../types'; +// @ts-ignore untyped module import { compatibilityShimFactory } from './compatibility_shim'; -export function createJobFactory(server) { +interface CreateJobFnOpts { + objectType: any; + title: string; + relativeUrls: string[]; + browserTimezone: string; + layout: any; +} + +export const createJobFactory: CreateJobFactory> = function createJobFactoryFn(server: ServerFacade) { const logger = LevelLogger.createForServer(server, [PLUGIN_ID, PDF_JOB_TYPE, 'create']); const compatibilityShim = compatibilityShimFactory(server, logger); const crypto = cryptoFactory(server); return compatibilityShim(async function createJobFn( - { objectType, title, relativeUrls, browserTimezone, layout }, - headers, - request + { objectType, title, relativeUrls, browserTimezone, layout }: CreateJobFnOpts, + headers: ConditionalHeaders['headers'], + request: RequestFacade ) { const serializedEncryptedHeaders = await crypto.encrypt(headers); @@ -35,4 +54,4 @@ export function createJobFactory(server) { forceNow: new Date().toISOString(), }; }); -} +}; diff --git a/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/execute_job/index.js b/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/execute_job/index.ts similarity index 57% rename from x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/execute_job/index.js rename to x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/execute_job/index.ts index d55ee95ff215b..543d5b587906d 100644 --- a/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/execute_job/index.js +++ b/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/execute_job/index.ts @@ -6,7 +6,8 @@ import * as Rx from 'rxjs'; import { mergeMap, catchError, map, takeUntil } from 'rxjs/operators'; -import { i18n } from '@kbn/i18n'; +import { ExecuteJobFactory, ESQueueWorkerExecuteFn, ServerFacade } from '../../../../types'; +import { JobDocPayloadPDF } from '../../types'; import { PLUGIN_ID, PDF_JOB_TYPE } from '../../../../common/constants'; import { LevelLogger } from '../../../../server/lib'; import { generatePdfObservableFactory } from '../lib/generate_pdf'; @@ -18,44 +19,40 @@ import { getCustomLogo, } from '../../../common/execute_job/'; -export function executeJobFactory(server) { +export const executeJobFactory: ExecuteJobFactory> = function executeJobFactoryFn(server: ServerFacade) { const generatePdfObservable = generatePdfObservableFactory(server); const logger = LevelLogger.createForServer(server, [PLUGIN_ID, PDF_JOB_TYPE, 'execute']); - return function executeJob(jobId, jobToExecute, cancellationToken) { + return function executeJob( + jobId: string, + jobToExecute: JobDocPayloadPDF, + cancellationToken: any + ) { const jobLogger = logger.clone([jobId]); - const process$ = Rx.of({ job: jobToExecute, server }).pipe( + const process$ = Rx.of({ job: jobToExecute, server, logger }).pipe( mergeMap(decryptJobHeaders), - catchError(err => { - jobLogger.error(err); - return Rx.throwError( - i18n.translate( - 'xpack.reporting.exportTypes.printablePdf.compShim.failedToDecryptReportJobDataErrorMessage', - { - defaultMessage: - 'Failed to decrypt report job data. Please ensure that {encryptionKey} is set and re-generate this report. {err}', - values: { encryptionKey: 'xpack.reporting.encryptionKey', err: err.toString() }, - } - ) - ); - }), map(omitBlacklistedHeaders), map(getConditionalHeaders), mergeMap(getCustomLogo), mergeMap(getFullUrls), - mergeMap(({ job, conditionalHeaders, logo, urls }) => { - return generatePdfObservable( - jobLogger, - job.title, - urls, - job.browserTimezone, - conditionalHeaders, - job.layout, - logo - ); - }), - map(buffer => ({ + mergeMap( + ({ job, conditionalHeaders, logo, urls }): Rx.Observable => { + const { browserTimezone, layout } = jobToExecute; + return generatePdfObservable( + jobLogger, + job.title, + urls, + browserTimezone, + conditionalHeaders, + layout, + logo + ); + } + ), + map((buffer: Buffer) => ({ content_type: 'application/pdf', content: buffer.toString('base64'), size: buffer.byteLength, @@ -70,4 +67,4 @@ export function executeJobFactory(server) { return process$.pipe(takeUntil(stop$)).toPromise(); }; -} +}; diff --git a/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/index.js b/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/index.ts similarity index 85% rename from x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/index.js rename to x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/index.ts index 51caa8502acaa..df798a7af23ec 100644 --- a/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/index.js +++ b/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/index.ts @@ -4,12 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ +import { ExportTypesRegistry } from '../../../types'; import { createJobFactory } from './create_job'; import { executeJobFactory } from './execute_job'; import { metadata } from '../metadata'; import { PDF_JOB_TYPE as jobType } from '../../../common/constants'; -export function register(registry) { +export function register(registry: ExportTypesRegistry) { registry.register({ ...metadata, jobType, diff --git a/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/lib/generate_pdf.ts b/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/lib/generate_pdf.ts index 52e867cc471ce..1e0245ebd513f 100644 --- a/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/lib/generate_pdf.ts +++ b/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/lib/generate_pdf.ts @@ -13,21 +13,10 @@ import { ServerFacade, ConditionalHeaders } from '../../../../types'; import { pdf } from './pdf'; import { screenshotsObservableFactory } from '../../../common/lib/screenshots'; import { createLayout } from '../../../common/layouts'; -import { TimeRange } from '../../../common/lib/screenshots/types'; +import { ScreenshotResults } from '../../../common/lib/screenshots/types'; import { LayoutInstance, LayoutParams } from '../../../common/layouts/layout'; -interface ScreenshotData { - base64EncodedData: string; - title: string; - description: string; -} - -interface UrlScreenshot { - screenshots: ScreenshotData[]; - timeRange: TimeRange; -} - -const getTimeRange = (urlScreenshots: UrlScreenshot[]) => { +const getTimeRange = (urlScreenshots: ScreenshotResults[]) => { const grouped = groupBy(urlScreenshots.map(u => u.timeRange)); const values = Object.values(grouped); if (values.length === 1) { @@ -48,20 +37,16 @@ export function generatePdfObservableFactory(server: ServerFacade) { browserTimezone: string, conditionalHeaders: ConditionalHeaders, layoutParams: LayoutParams, - logo: string + logo?: string ) { const layout = createLayout(server, layoutParams) as LayoutInstance; - const screenshots$ = Rx.from(urls).pipe( mergeMap( url => screenshotsObservable({ logger, url, conditionalHeaders, layout, browserTimezone }), captureConcurrency - ) - ); - - return screenshots$.pipe( + ), toArray(), - mergeMap(async (urlScreenshots: UrlScreenshot[]) => { + mergeMap(async (urlScreenshots: ScreenshotResults[]) => { const pdfOutput = pdf.create(layout, logo); if (title) { @@ -84,5 +69,7 @@ export function generatePdfObservableFactory(server: ServerFacade) { return buffer; }) ); + + return screenshots$; }; } diff --git a/x-pack/legacy/plugins/reporting/export_types/printable_pdf/types.d.ts b/x-pack/legacy/plugins/reporting/export_types/printable_pdf/types.d.ts index d1e5e58f0f0a5..b51a2d4d5711c 100644 --- a/x-pack/legacy/plugins/reporting/export_types/printable_pdf/types.d.ts +++ b/x-pack/legacy/plugins/reporting/export_types/printable_pdf/types.d.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { LayoutInstance } from '../common/layouts/layout'; -import { ConditionalHeaders, JobDocPayload, ServerFacade, RequestFacade } from '../../types'; +import { LayoutInstance, LayoutParams } from '../common/layouts/layout'; +import { JobDocPayload, ServerFacade, RequestFacade } from '../../types'; // Job params: structure of incoming user request data, after being parsed from RISON export interface JobParamsPDF { @@ -17,21 +17,12 @@ export interface JobParamsPDF { } // Job payload: structure of stored job data provided by create_job -export interface JobDocPayloadPDF extends JobDocPayload { +export interface JobDocPayloadPDF extends JobDocPayload { basePath?: string; browserTimezone: string; forceNow?: string; - layout: any; + layout: LayoutParams; objects: Array<{ relativeUrl: string; }>; - relativeUrl: undefined; } - -export type ESQueueCreateJobFnPDF = ( - jobParams: JobParamsPDF, - headers: ConditionalHeaders, - request: RequestFacade -) => Promise; - -export type CreateJobFactoryPDF = (server: ServerFacade) => ESQueueCreateJobFnPDF; diff --git a/x-pack/legacy/plugins/reporting/server/lib/create_worker.ts b/x-pack/legacy/plugins/reporting/server/lib/create_worker.ts index 0a86f9d1d4ff5..01f59099a1d99 100644 --- a/x-pack/legacy/plugins/reporting/server/lib/create_worker.ts +++ b/x-pack/legacy/plugins/reporting/server/lib/create_worker.ts @@ -11,9 +11,8 @@ import { QueueConfig, ExportTypeDefinition, ESQueueWorkerExecuteFn, - ImmediateExecuteFn, - JobDoc, JobDocPayload, + ImmediateExecuteFn, JobSource, RequestFacade, ServerFacade, @@ -22,7 +21,8 @@ import { import { events as esqueueEvents } from './esqueue'; import { LevelLogger } from './level_logger'; -export function createWorkerFactory(server: ServerFacade) { +export function createWorkerFactory(server: ServerFacade) { + type JobDocPayloadType = JobDocPayload; const config = server.config(); const logger = LevelLogger.createForServer(server, [PLUGIN_ID, 'queue-worker']); const queueConfig: QueueConfig = config.get('xpack.reporting.queue'); @@ -31,34 +31,47 @@ export function createWorkerFactory(server: ServerFacade) { const { exportTypesRegistry } = server.plugins.reporting!; // Once more document types are added, this will need to be passed in - return function createWorker(queue: ESQueueInstance) { + return function createWorker(queue: ESQueueInstance) { // export type / execute job map - const jobExecutors: Map = new Map(); + const jobExecutors: Map< + string, + ImmediateExecuteFn | ESQueueWorkerExecuteFn + > = new Map(); - for (const exportType of exportTypesRegistry.getAll() as ExportTypeDefinition[]) { + for (const exportType of exportTypesRegistry.getAll() as Array< + ExportTypeDefinition + >) { const executeJobFactory = exportType.executeJobFactory(server); jobExecutors.set(exportType.jobType, executeJobFactory); } - const workerFn = ( - job: JobSource, - arg1: JobDocPayload | JobDoc, - arg2: CancellationToken | RequestFacade | undefined - ) => { + const workerFn = (jobSource: JobSource, ...workerRestArgs: any[]) => { + const { + _id: jobId, + _source: { jobtype: jobType }, + } = jobSource; + + const jobTypeExecutor = jobExecutors.get(jobType); // pass the work to the jobExecutor - if (!jobExecutors.get(job._source.jobtype)) { - throw new Error(`Unable to find a job executor for the claimed job: [${job._id}]`); + if (!jobTypeExecutor) { + throw new Error(`Unable to find a job executor for the claimed job: [${jobId}]`); } - // job executor function signature is different depending on whether it - // is ESQueueWorkerExecuteFn or ImmediateExecuteFn - if (job._id) { - const jobExecutor = jobExecutors.get(job._source.jobtype) as ESQueueWorkerExecuteFn; - return jobExecutor(job._id, arg1 as JobDoc, arg2 as CancellationToken); + + if (jobId) { + const jobExecutorWorker = jobTypeExecutor as ESQueueWorkerExecuteFn; + return jobExecutorWorker( + jobId, + ...(workerRestArgs as [JobDocPayloadType, CancellationToken]) + ); } else { - const jobExecutor = jobExecutors.get(job._source.jobtype) as ImmediateExecuteFn; - return jobExecutor(null, arg1 as JobDocPayload, arg2 as RequestFacade); + const jobExecutorImmediate = jobExecutors.get(jobType) as ImmediateExecuteFn; + return jobExecutorImmediate( + null, + ...(workerRestArgs as [JobDocPayload, RequestFacade]) + ); } }; + const workerOptions = { kibanaName, kibanaId, diff --git a/x-pack/legacy/plugins/reporting/server/lib/enqueue_job.ts b/x-pack/legacy/plugins/reporting/server/lib/enqueue_job.ts index 9b1d7992283a5..a8cefa3fdc49b 100644 --- a/x-pack/legacy/plugins/reporting/server/lib/enqueue_job.ts +++ b/x-pack/legacy/plugins/reporting/server/lib/enqueue_job.ts @@ -8,6 +8,8 @@ import { get } from 'lodash'; // @ts-ignore import { events as esqueueEvents } from './esqueue'; import { + ESQueueCreateJobFn, + ImmediateCreateJobFn, Job, ServerFacade, RequestFacade, @@ -32,17 +34,19 @@ export function enqueueJobFactory(server: ServerFacade) { const queueConfig: QueueConfig = config.get('xpack.reporting.queue'); const { exportTypesRegistry, queue: jobQueue } = server.plugins.reporting!; - return async function enqueueJob( + return async function enqueueJob( parentLogger: Logger, exportTypeId: string, - jobParams: object, + jobParams: JobParamsType, user: string, headers: ConditionalHeaders['headers'], request: RequestFacade ): Promise { + type CreateJobFn = ESQueueCreateJobFn | ImmediateCreateJobFn; + const logger = parentLogger.clone(['queue-job']); const exportType = exportTypesRegistry.getById(exportTypeId); - const createJob = exportType.createJobFactory(server); + const createJob = exportType.createJobFactory(server) as CreateJobFn; const payload = await createJob(jobParams, headers, request); const options = { diff --git a/x-pack/legacy/plugins/reporting/server/lib/export_types_registry.ts b/x-pack/legacy/plugins/reporting/server/lib/export_types_registry.ts index 35c97f1db10dc..af1457ab52fe2 100644 --- a/x-pack/legacy/plugins/reporting/server/lib/export_types_registry.ts +++ b/x-pack/legacy/plugins/reporting/server/lib/export_types_registry.ts @@ -10,7 +10,7 @@ import { ServerFacade } from '../../types'; import { PLUGIN_ID } from '../../common/constants'; import { oncePerServer } from './once_per_server'; import { LevelLogger } from './level_logger'; -// @ts-ignore untype module +// @ts-ignore untype module TODO import { ExportTypesRegistry } from '../../common/export_types_registry'; function scan(pattern: string) { diff --git a/x-pack/legacy/plugins/reporting/server/lib/index.ts b/x-pack/legacy/plugins/reporting/server/lib/index.ts index c4b61638794f3..b11f7bd95d9ef 100644 --- a/x-pack/legacy/plugins/reporting/server/lib/index.ts +++ b/x-pack/legacy/plugins/reporting/server/lib/index.ts @@ -4,11 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -// @ts-ignore untyped module export { exportTypesRegistryFactory } from './export_types_registry'; // @ts-ignore untyped module export { checkLicenseFactory } from './check_license'; - export { LevelLogger } from './level_logger'; export { createQueueFactory } from './create_queue'; export { cryptoFactory } from './crypto'; diff --git a/x-pack/legacy/plugins/reporting/server/routes/generate_from_savedobject.ts b/x-pack/legacy/plugins/reporting/server/routes/generate_from_savedobject.ts index ec0a56f8de442..72c8055614065 100644 --- a/x-pack/legacy/plugins/reporting/server/routes/generate_from_savedobject.ts +++ b/x-pack/legacy/plugins/reporting/server/routes/generate_from_savedobject.ts @@ -38,7 +38,7 @@ export function registerGenerateCsvFromSavedObject( * 3. Ensure that details for a queued job were returned */ - let result: QueuedJobPayload; + let result: QueuedJobPayload; try { const jobParams = getJobParamsFromRequest(request, { isImmediate: false }); result = await handleRoute(CSV_FROM_SAVEDOBJECT_JOB_TYPE, jobParams, request, h); diff --git a/x-pack/legacy/plugins/reporting/server/routes/generate_from_savedobject_immediate.ts b/x-pack/legacy/plugins/reporting/server/routes/generate_from_savedobject_immediate.ts index 2303fddf555e0..8b0dd1a6e7c4f 100644 --- a/x-pack/legacy/plugins/reporting/server/routes/generate_from_savedobject_immediate.ts +++ b/x-pack/legacy/plugins/reporting/server/routes/generate_from_savedobject_immediate.ts @@ -12,7 +12,6 @@ import { ResponseFacade, ReportingResponseToolkit, Logger, - JobIDForImmediate, JobDocOutputExecuted, } from '../../types'; import { JobDocPayloadPanelCsv } from '../../export_types/csv_from_savedobject/types'; @@ -57,11 +56,7 @@ export function registerGenerateCsvFromSavedObjectImmediate( content_type: jobOutputContentType, content: jobOutputContent, size: jobOutputSize, - }: JobDocOutputExecuted = await executeJobFn( - null as JobIDForImmediate, - jobDocPayload, - request - ); + }: JobDocOutputExecuted = await executeJobFn(null, jobDocPayload, request); logger.info(`Job output size: ${jobOutputSize} bytes`); diff --git a/x-pack/legacy/plugins/reporting/server/routes/index.ts b/x-pack/legacy/plugins/reporting/server/routes/index.ts index fd86b281ccf8a..c48a37a36812e 100644 --- a/x-pack/legacy/plugins/reporting/server/routes/index.ts +++ b/x-pack/legacy/plugins/reporting/server/routes/index.ts @@ -17,7 +17,7 @@ import { registerLegacy } from './legacy'; export function registerRoutes(server: ServerFacade, logger: Logger) { const config = server.config(); const DOWNLOAD_BASE_URL = config.get('server.basePath') + `${API_BASE_URL}/jobs/download`; - // @ts-ignore + // @ts-ignore TODO const { errors: esErrors } = server.plugins.elasticsearch.getCluster('admin'); const enqueueJob = enqueueJobFactory(server); @@ -30,7 +30,6 @@ export function registerRoutes(server: ServerFacade, logger: Logger) { request: RequestFacade, h: ReportingResponseToolkit ) { - // @ts-ignore const user = request.pre.user; const headers = request.headers; diff --git a/x-pack/legacy/plugins/reporting/server/routes/jobs.ts b/x-pack/legacy/plugins/reporting/server/routes/jobs.ts index 58a212aa0d7fb..71d9f0d3ae13b 100644 --- a/x-pack/legacy/plugins/reporting/server/routes/jobs.ts +++ b/x-pack/legacy/plugins/reporting/server/routes/jobs.ts @@ -6,7 +6,13 @@ import boom from 'boom'; import { API_BASE_URL } from '../../common/constants'; -import { JobDoc, ServerFacade, RequestFacade, ReportingResponseToolkit } from '../../types'; +import { + ServerFacade, + RequestFacade, + ReportingResponseToolkit, + JobDocOutput, + JobSource, +} from '../../types'; // @ts-ignore import { jobsQueryFactory } from '../lib/jobs_query'; // @ts-ignore @@ -65,8 +71,7 @@ export function registerJobs(server: ServerFacade) { const { docId } = request.params; return jobsQuery.get(request.pre.user, docId, { includeContent: true }).then( - (doc: any): JobDoc => { - const job = doc._source; + ({ _source: job }: JobSource): JobDocOutput => { if (!job) { throw boom.notFound(); } @@ -90,9 +95,9 @@ export function registerJobs(server: ServerFacade) { handler: (request: RequestFacade) => { const { docId } = request.params; - return jobsQuery.get(request.pre.user, docId).then( - (doc: any): JobDoc => { - const job: JobDoc = doc._source; + return jobsQuery + .get(request.pre.user, docId) + .then(({ _source: job }: JobSource): JobSource['_source'] => { if (!job) { throw boom.notFound(); } @@ -103,14 +108,13 @@ export function registerJobs(server: ServerFacade) { } return { - ...doc._source, + ...job, payload: { ...payload, headers: undefined, }, }; - } - ); + }); }, }); diff --git a/x-pack/legacy/plugins/reporting/server/routes/lib/get_document_payload.ts b/x-pack/legacy/plugins/reporting/server/routes/lib/get_document_payload.ts index 9952cbb980778..a69c19c006b61 100644 --- a/x-pack/legacy/plugins/reporting/server/routes/lib/get_document_payload.ts +++ b/x-pack/legacy/plugins/reporting/server/routes/lib/get_document_payload.ts @@ -21,10 +21,12 @@ interface ICustomHeaders { const DEFAULT_TITLE = 'report'; -const getTitle = (exportType: ExportTypeDefinition, title?: string): string => +type ExportTypeType = ExportTypeDefinition; + +const getTitle = (exportType: ExportTypeType, title?: string): string => `${title || DEFAULT_TITLE}.${exportType.jobContentExtension}`; -const getReportingHeaders = (output: JobDocOutputExecuted, exportType: ExportTypeDefinition) => { +const getReportingHeaders = (output: JobDocOutputExecuted, exportType: ExportTypeType) => { const metaDataHeaders: ICustomHeaders = {}; if (exportType.jobType === CSV_JOB_TYPE) { @@ -41,7 +43,7 @@ const getReportingHeaders = (output: JobDocOutputExecuted, exportType: ExportTyp export function getDocumentPayloadFactory(server: ServerFacade) { const exportTypesRegistry = server.plugins.reporting!.exportTypesRegistry; - function encodeContent(content: string | null, exportType: ExportTypeDefinition) { + function encodeContent(content: string | null, exportType: ExportTypeType) { switch (exportType.jobContentEncoding) { case 'base64': return content ? Buffer.from(content, 'base64') : content; // Buffer.from rejects null @@ -51,9 +53,7 @@ export function getDocumentPayloadFactory(server: ServerFacade) { } function getCompleted(output: JobDocOutputExecuted, jobType: string, title: string) { - const exportType = exportTypesRegistry.get( - (item: ExportTypeDefinition) => item.jobType === jobType - ); + const exportType = exportTypesRegistry.get((item: ExportTypeType) => item.jobType === jobType); const filename = getTitle(exportType, title); const headers = getReportingHeaders(output, exportType); @@ -88,9 +88,11 @@ export function getDocumentPayloadFactory(server: ServerFacade) { }; } - return function getDocumentPayload(doc: { _source: JobDocExecuted }) { + return function getDocumentPayload(doc: { + _source: JobDocExecuted<{ output: JobDocOutputExecuted }>; + }) { const { status, jobtype: jobType, payload: { title } = { title: '' } } = doc._source; - const { output } = doc._source as { output: JobDocOutputExecuted }; + const { output } = doc._source; if (status === 'completed') { return getCompleted(output, jobType, title); diff --git a/x-pack/legacy/plugins/reporting/server/routes/types.d.ts b/x-pack/legacy/plugins/reporting/server/routes/types.d.ts index aabe4445f9bae..b50d443ec00b9 100644 --- a/x-pack/legacy/plugins/reporting/server/routes/types.d.ts +++ b/x-pack/legacy/plugins/reporting/server/routes/types.d.ts @@ -15,11 +15,11 @@ export type HandlerFunction = ( export type HandlerErrorFunction = (exportType: string, err: Error) => any; -export interface QueuedJobPayload { +export interface QueuedJobPayload { error?: boolean; source: { job: { - payload: JobDocPayload; + payload: JobDocPayload; }; }; } diff --git a/x-pack/legacy/plugins/reporting/types.d.ts b/x-pack/legacy/plugins/reporting/types.d.ts index e8fb015426f51..afba9f3e17838 100644 --- a/x-pack/legacy/plugins/reporting/types.d.ts +++ b/x-pack/legacy/plugins/reporting/types.d.ts @@ -25,13 +25,15 @@ export type Job = EventEmitter & { export interface ReportingPlugin { queue: { - addJob: (type: string, payload: object, options: object) => Job; + addJob: (type: string, payload: PayloadType, options: object) => Job; }; // TODO: convert exportTypesRegistry to TS exportTypesRegistry: { - getById: (id: string) => ExportTypeDefinition; - getAll: () => ExportTypeDefinition[]; - get: (callback: (item: ExportTypeDefinition) => boolean) => ExportTypeDefinition; + getById: (id: string) => ExportTypeDefinition; + getAll: () => Array>; + get: ( + callback: (item: ExportTypeDefinition) => boolean + ) => ExportTypeDefinition; }; browserDriverFactory: HeadlessChromiumDriverFactory; } @@ -182,7 +184,7 @@ export interface ConditionalHeadersConditions { } export interface CryptoFactory { - decrypt: (headers?: Record) => string; + decrypt: (headers?: string) => any; } export interface TimeRangeParams { @@ -196,17 +198,11 @@ export interface JobParamPostPayload { timerange: TimeRangeParams; } -export interface JobDocPayload { - headers?: Record; - jobParams: any; +export interface JobDocPayload { + headers?: string; // serialized encrypted headers + jobParams: JobParamsType; title: string; type: string | null; - objects?: null | object[]; -} - -export interface JobSource { - _id: string; - _source: JobDoc; } export interface JobDocOutput { @@ -214,18 +210,21 @@ export interface JobDocOutput { contentType: string; } -export interface JobDoc { +export interface JobDocExecuted { jobtype: string; - output: JobDocOutput; - payload: JobDocPayload; + output: JobDocOutputExecuted; + payload: JobDocPayload; status: string; // completed, failed, etc } -export interface JobDocExecuted { - jobtype: string; - output: JobDocOutputExecuted; - payload: JobDocPayload; - status: string; // completed, failed, etc +export interface JobSource { + _id: string; + _source: { + jobtype: string; + output: JobDocOutput; + payload: JobDocPayload; + status: string; // completed, failed, etc + }; } /* @@ -251,41 +250,35 @@ export interface ESQueueWorker { on: (event: string, handler: any) => void; } -type JobParamsUrl = object; - -interface JobParamsSavedObject { - savedObjectType: string; - savedObjectId: string; - isImmediate: boolean; -} - -export type ESQueueCreateJobFn = ( - jobParams: JobParamsSavedObject | JobParamsUrl, +export type ESQueueCreateJobFn = ( + jobParams: JobParamsType, headers: Record, request: RequestFacade -) => Promise; +) => Promise; -export type ImmediateCreateJobFn = ( - jobParams: any, +export type ImmediateCreateJobFn = ( + jobParams: JobParamsType, headers: Record, req: RequestFacade ) => Promise<{ type: string | null; title: string; - jobParams: any; + jobParams: JobParamsType; }>; -export type ESQueueWorkerExecuteFn = ( +export type ESQueueWorkerExecuteFn = ( jobId: string, - job: JobDoc, + job: JobDocPayloadType, cancellationToken?: CancellationToken ) => void; -export type JobIDForImmediate = null; - -export type ImmediateExecuteFn = ( - jobId: JobIDForImmediate, - job: JobDocPayload, +/* + * ImmediateExecuteFn receives the job doc payload because the payload was + * generated in the CreateFn + */ +export type ImmediateExecuteFn = ( + jobId: null, + job: JobDocPayload, request: RequestFacade ) => Promise; @@ -296,30 +289,48 @@ export interface ESQueueWorkerOptions { intervalErrorMultiplier: number; } -export interface ESQueueInstance { +// GenericWorkerFn is a generic for ImmediateExecuteFn | ESQueueWorkerExecuteFn, +type GenericWorkerFn = ( + jobSource: JobSource, + ...workerRestArgs: any[] +) => void | Promise; + +export interface ESQueueInstance { registerWorker: ( - jobtype: string, - workerFn: any, + pluginId: string, + workerFn: GenericWorkerFn, workerOptions: ESQueueWorkerOptions ) => ESQueueWorker; } -export type CreateJobFactory = (server: ServerFacade) => ESQueueCreateJobFn | ImmediateCreateJobFn; -export type ExecuteJobFactory = (server: ServerFacade) => ESQueueWorkerExecuteFn | ImmediateExecuteFn; // prettier-ignore +export type CreateJobFactory = (server: ServerFacade) => CreateJobFnType; +export type ExecuteJobFactory = (server: ServerFacade) => ExecuteJobFnType; -export interface ExportTypeDefinition { +export interface ExportTypeDefinition< + JobParamsType, + CreateJobFnType, + JobPayloadType, + ExecuteJobFnType +> { id: string; name: string; jobType: string; jobContentEncoding?: string; jobContentExtension: string; - createJobFactory: CreateJobFactory; - executeJobFactory: ExecuteJobFactory; + createJobFactory: CreateJobFactory; + executeJobFactory: ExecuteJobFactory; validLicenses: string[]; } export interface ExportTypesRegistry { - register: (exportTypeDefinition: ExportTypeDefinition) => void; + register: ( + exportTypeDefinition: ExportTypeDefinition< + JobParamsType, + CreateJobFnType, + JobPayloadType, + ExecuteJobFnType + > + ) => void; } export { CancellationToken } from './common/cancellation_token'; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/request_responses.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/request_responses.ts index cf76987aa38ad..3eaa7a6cddcc8 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/request_responses.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/request_responses.ts @@ -116,7 +116,7 @@ export const getCreateRequest = (): ServerInjectOptions => ({ export const createActionResult = (): ActionResult => ({ id: 'result-1', actionTypeId: 'action-id-1', - description: '', + name: '', config: {}, }); @@ -178,6 +178,6 @@ export const getResult = (): RuleAlertType => ({ export const updateActionResult = (): ActionResult => ({ id: 'result-1', actionTypeId: 'action-id-1', - description: '', + name: '', config: {}, }); diff --git a/x-pack/plugins/apm/server/plugin.ts b/x-pack/plugins/apm/server/plugin.ts index b28e00adcc6d1..00945e12db51d 100644 --- a/x-pack/plugins/apm/server/plugin.ts +++ b/x-pack/plugins/apm/server/plugin.ts @@ -29,7 +29,7 @@ export class APMPlugin implements Plugin { this.legacySetup$ = new AsyncSubject(); } - public setup( + public async setup( core: CoreSetup, plugins: { apm_oss: APMOSSPlugin extends Plugin ? TSetup : never; @@ -46,14 +46,17 @@ export class APMPlugin implements Plugin { createApmApi().init(core, { config$: mergedConfig$, logger, __LEGACY }); }); - combineLatest(mergedConfig$, core.elasticsearch.dataClient$).subscribe( - ([config, dataClient]) => { - createApmAgentConfigurationIndex({ - esClient: dataClient, - config, - }); - } - ); + await new Promise(resolve => { + combineLatest(mergedConfig$, core.elasticsearch.dataClient$).subscribe( + async ([config, dataClient]) => { + await createApmAgentConfigurationIndex({ + esClient: dataClient, + config, + }); + resolve(); + } + ); + }); return { config$: mergedConfig$, diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 3b7f3ded77290..c24f04697e3e5 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -9610,8 +9610,6 @@ "xpack.reporting.exportTypes.csv.executeJob.failedToDecryptReportJobDataErrorMessage": "レポートジョブデータの解読に失敗しました{encryptionKey} が設定されていることを確認してこのレポートを再生成してください。{err}", "xpack.reporting.exportTypes.csv.hitIterator.expectedHitsErrorMessage": "次の Elasticsearch からの応答で期待される {hits}: {response}", "xpack.reporting.exportTypes.csv.hitIterator.expectedScrollIdErrorMessage": "次の Elasticsearch からの応答で期待される {scrollId}: {response}", - "xpack.reporting.exportTypes.png.compShim.failedToDecryptReportJobDataErrorMessage": "レポートジョブデータの解読に失敗しました{encryptionKey} が設定されていることを確認してこのレポートを再生成してください。{err}", - "xpack.reporting.exportTypes.printablePdf.compShim.failedToDecryptReportJobDataErrorMessage": "レポートジョブデータの解読に失敗しました{encryptionKey} が設定されていることを確認してこのレポートを再生成してください。{err}", "xpack.reporting.exportTypes.printablePdf.documentStreamIsNotgeneratedErrorMessage": "ドキュメントストリームが生成されていません。", "xpack.reporting.exportTypes.printablePdf.logoDescription": "Elastic 提供", "xpack.reporting.exportTypes.printablePdf.pagingDescription": "{pageCount} ページ中 {currentPage} ページ目", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 017aa7d91d74b..6de1bc2135351 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -9699,8 +9699,6 @@ "xpack.reporting.exportTypes.csv.executeJob.failedToDecryptReportJobDataErrorMessage": "无法解密报告作业数据。请确保已设置 {encryptionKey},然后重新生成此报告。{err}", "xpack.reporting.exportTypes.csv.hitIterator.expectedHitsErrorMessage": "在以下 Elasticsearch 响应中预期 {hits}:{response}", "xpack.reporting.exportTypes.csv.hitIterator.expectedScrollIdErrorMessage": "在以下 Elasticsearch 响应中预期 {scrollId}:{response}", - "xpack.reporting.exportTypes.png.compShim.failedToDecryptReportJobDataErrorMessage": "无法解密报告作业数据。请确保已设置 {encryptionKey},然后重新生成此报告。{err}", - "xpack.reporting.exportTypes.printablePdf.compShim.failedToDecryptReportJobDataErrorMessage": "无法解密报告作业数据。请确保已设置 {encryptionKey},然后重新生成此报告。{err}", "xpack.reporting.exportTypes.printablePdf.documentStreamIsNotgeneratedErrorMessage": "尚未生成文档流", "xpack.reporting.exportTypes.printablePdf.logoDescription": "由 Elastic 提供支持", "xpack.reporting.exportTypes.printablePdf.pagingDescription": "第 {currentPage} 页,共 {pageCount} 页", diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/email.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/email.ts index 659a73394519a..2c1cb966c6b7e 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/email.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/email.ts @@ -23,7 +23,7 @@ export default function emailTest({ getService }: FtrProviderContext) { .post('/api/action') .set('kbn-xsrf', 'foo') .send({ - description: 'An email action', + name: 'An email action', actionTypeId: '.email', config: { service: '__json', @@ -39,7 +39,7 @@ export default function emailTest({ getService }: FtrProviderContext) { createdActionId = createdAction.id; expect(createdAction).to.eql({ id: createdActionId, - description: 'An email action', + name: 'An email action', actionTypeId: '.email', config: { service: '__json', @@ -58,7 +58,7 @@ export default function emailTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, - description: 'An email action', + name: 'An email action', actionTypeId: '.email', config: { from: 'bob@example.com', @@ -139,7 +139,7 @@ export default function emailTest({ getService }: FtrProviderContext) { .post('/api/action') .set('kbn-xsrf', 'foo') .send({ - description: 'An email action', + name: 'An email action', actionTypeId: '.email', config: {}, }) diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/es_index.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/es_index.ts index 648944a9256b2..197ad3ff80094 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/es_index.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/es_index.ts @@ -29,7 +29,7 @@ export default function indexTest({ getService }: FtrProviderContext) { .post('/api/action') .set('kbn-xsrf', 'foo') .send({ - description: 'An index action', + name: 'An index action', actionTypeId: '.index', config: {}, secrets: {}, @@ -38,7 +38,7 @@ export default function indexTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, - description: 'An index action', + name: 'An index action', actionTypeId: '.index', config: { index: null, @@ -53,7 +53,7 @@ export default function indexTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, - description: 'An index action', + name: 'An index action', actionTypeId: '.index', config: { index: null }, }); @@ -63,7 +63,7 @@ export default function indexTest({ getService }: FtrProviderContext) { .post('/api/action') .set('kbn-xsrf', 'foo') .send({ - description: 'An index action with index config', + name: 'An index action with index config', actionTypeId: '.index', config: { index: ES_TEST_INDEX_NAME, @@ -73,7 +73,7 @@ export default function indexTest({ getService }: FtrProviderContext) { expect(createdActionWithIndex).to.eql({ id: createdActionWithIndex.id, - description: 'An index action with index config', + name: 'An index action with index config', actionTypeId: '.index', config: { index: ES_TEST_INDEX_NAME, @@ -88,7 +88,7 @@ export default function indexTest({ getService }: FtrProviderContext) { expect(fetchedActionWithIndex).to.eql({ id: fetchedActionWithIndex.id, - description: 'An index action with index config', + name: 'An index action with index config', actionTypeId: '.index', config: { index: ES_TEST_INDEX_NAME, @@ -101,7 +101,7 @@ export default function indexTest({ getService }: FtrProviderContext) { .post('/api/action') .set('kbn-xsrf', 'foo') .send({ - description: 'An index action', + name: 'An index action', actionTypeId: '.index', config: { index: 666 }, }) diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/pagerduty.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/pagerduty.ts index 4280e85376201..62c8b31209729 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/pagerduty.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/pagerduty.ts @@ -37,7 +37,7 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) { .post('/api/action') .set('kbn-xsrf', 'foo') .send({ - description: 'A pagerduty action', + name: 'A pagerduty action', actionTypeId: '.pagerduty', secrets: { routingKey: 'pager-duty-routing-key', @@ -47,7 +47,7 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, - description: 'A pagerduty action', + name: 'A pagerduty action', actionTypeId: '.pagerduty', config: { apiUrl: null, @@ -62,7 +62,7 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, - description: 'A pagerduty action', + name: 'A pagerduty action', actionTypeId: '.pagerduty', config: { apiUrl: null, @@ -75,7 +75,7 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) { .post('/api/action') .set('kbn-xsrf', 'foo') .send({ - description: 'A pagerduty action', + name: 'A pagerduty action', actionTypeId: '.pagerduty', secrets: {}, }) @@ -95,7 +95,7 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) { .post('/api/action') .set('kbn-xsrf', 'foo') .send({ - description: 'A pagerduty simulator', + name: 'A pagerduty simulator', actionTypeId: '.pagerduty', config: { apiUrl: pagerdutySimulatorURL, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/server_log.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/server_log.ts index 741f006e64bfa..f4ea568cf08c3 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/server_log.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/server_log.ts @@ -23,7 +23,7 @@ export default function serverLogTest({ getService }: FtrProviderContext) { .post('/api/action') .set('kbn-xsrf', 'foo') .send({ - description: 'A server.log action', + name: 'A server.log action', actionTypeId: '.server-log', }) .expect(200); @@ -31,7 +31,7 @@ export default function serverLogTest({ getService }: FtrProviderContext) { serverLogActionId = createdAction.id; expect(createdAction).to.eql({ id: createdAction.id, - description: 'A server.log action', + name: 'A server.log action', actionTypeId: '.server-log', config: {}, }); @@ -44,7 +44,7 @@ export default function serverLogTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, - description: 'A server.log action', + name: 'A server.log action', actionTypeId: '.server-log', config: {}, }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/slack.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/slack.ts index 595058e72af0b..ae1464023c011 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/slack.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/slack.ts @@ -37,7 +37,7 @@ export default function slackTest({ getService }: FtrProviderContext) { .post('/api/action') .set('kbn-xsrf', 'foo') .send({ - description: 'A slack action', + name: 'A slack action', actionTypeId: '.slack', secrets: { webhookUrl: 'http://example.com', @@ -47,7 +47,7 @@ export default function slackTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, - description: 'A slack action', + name: 'A slack action', actionTypeId: '.slack', config: {}, }); @@ -60,7 +60,7 @@ export default function slackTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, - description: 'A slack action', + name: 'A slack action', actionTypeId: '.slack', config: {}, }); @@ -71,7 +71,7 @@ export default function slackTest({ getService }: FtrProviderContext) { .post('/api/action') .set('kbn-xsrf', 'foo') .send({ - description: 'A slack action', + name: 'A slack action', actionTypeId: '.slack', secrets: {}, }) @@ -91,7 +91,7 @@ export default function slackTest({ getService }: FtrProviderContext) { .post('/api/action') .set('kbn-xsrf', 'foo') .send({ - description: 'A slack simulator', + name: 'A slack simulator', actionTypeId: '.slack', secrets: { webhookUrl: slackSimulatorURL, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/webhook.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/webhook.ts index 0f17019518824..53b11525d1b95 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/webhook.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/webhook.ts @@ -48,7 +48,7 @@ export default function webhookTest({ getService }: FtrProviderContext) { .post('/api/action') .set('kbn-xsrf', 'test') .send({ - description: 'A generic Webhook action', + name: 'A generic Webhook action', actionTypeId: '.webhook', secrets: { user, @@ -78,7 +78,7 @@ export default function webhookTest({ getService }: FtrProviderContext) { .post('/api/action') .set('kbn-xsrf', 'test') .send({ - description: 'A generic Webhook action', + name: 'A generic Webhook action', actionTypeId: '.webhook', secrets: { user: 'username', @@ -92,7 +92,7 @@ export default function webhookTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, - description: 'A generic Webhook action', + name: 'A generic Webhook action', actionTypeId: '.webhook', config: { ...defaultValues, @@ -108,7 +108,7 @@ export default function webhookTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, - description: 'A generic Webhook action', + name: 'A generic Webhook action', actionTypeId: '.webhook', config: { ...defaultValues, @@ -167,7 +167,7 @@ export default function webhookTest({ getService }: FtrProviderContext) { .post('/api/action') .set('kbn-xsrf', 'test') .send({ - description: 'A generic Webhook action', + name: 'A generic Webhook action', actionTypeId: '.webhook', secrets: { user: 'username', diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/create.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/create.ts index e044d6a1fd2b0..5d5692685c81b 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/create.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/create.ts @@ -28,7 +28,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { .auth(user.username, user.password) .set('kbn-xsrf', 'foo') .send({ - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, @@ -54,7 +54,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { expect(response.statusCode).to.eql(200); expect(response.body).to.eql({ id: response.body.id, - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, @@ -74,7 +74,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'foo') .auth(user.username, user.password) .send({ - description: 'My action', + name: 'My action', actionTypeId: 'test.unregistered-action-type', config: {}, }); @@ -129,10 +129,10 @@ export default function createActionTests({ getService }: FtrProviderContext) { statusCode: 400, error: 'Bad Request', message: - 'child "description" fails because ["description" is required]. child "actionTypeId" fails because ["actionTypeId" is required]', + 'child "name" fails because ["name" is required]. child "actionTypeId" fails because ["actionTypeId" is required]', validation: { source: 'payload', - keys: ['description', 'actionTypeId'], + keys: ['name', 'actionTypeId'], }, }); break; @@ -147,7 +147,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'foo') .auth(user.username, user.password) .send({ - description: 'my description', + name: 'my name', actionTypeId: 'test.index-record', config: { unencrypted: 'my unencrypted text', diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/delete.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/delete.ts index 6e1bd260cb05f..6fca330887c3e 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/delete.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/delete.ts @@ -28,7 +28,7 @@ export default function deleteActionTests({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(space.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, @@ -71,7 +71,7 @@ export default function deleteActionTests({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(space.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/execute.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/execute.ts index 0c05ad3e3e68a..46c3de18a1196 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/execute.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/execute.ts @@ -46,7 +46,7 @@ export default function({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(space.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, @@ -118,7 +118,7 @@ export default function({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(space.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, @@ -172,7 +172,7 @@ export default function({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(space.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, @@ -188,7 +188,7 @@ export default function({ getService }: FtrProviderContext) { .put(`${getUrlPrefix(space.id)}/api/action/${createdAction.id}`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action updated', + name: 'My action updated', config: { unencrypted: `This value shouldn't get encrypted`, }, @@ -328,7 +328,7 @@ export default function({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(space.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'test email action', + name: 'test email action', actionTypeId: '.email', config: { from: 'email-from@example.com', @@ -347,7 +347,7 @@ export default function({ getService }: FtrProviderContext) { .put(`${getUrlPrefix(space.id)}/api/action/${createdAction.id}`) .set('kbn-xsrf', 'foo') .send({ - description: 'a test email action 2', + name: 'a test email action 2', config: { from: 'email-from@example.com', service: '__json', @@ -399,7 +399,7 @@ export default function({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(space.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action', + name: 'My action', actionTypeId: 'test.authorization', }) .expect(200); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/find.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/find.ts index 1c6d5480e400f..89c5b4f451f82 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/find.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/find.ts @@ -27,7 +27,7 @@ export default function findActionTests({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(space.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, @@ -68,7 +68,7 @@ export default function findActionTests({ getService }: FtrProviderContext) { data: [ { id: createdAction.id, - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, @@ -88,7 +88,7 @@ export default function findActionTests({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(space.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, @@ -129,7 +129,7 @@ export default function findActionTests({ getService }: FtrProviderContext) { data: [ { id: createdAction.id, - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, @@ -149,7 +149,7 @@ export default function findActionTests({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(space.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, @@ -207,7 +207,7 @@ export default function findActionTests({ getService }: FtrProviderContext) { data: [ { id: createdAction.id, - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, @@ -227,7 +227,7 @@ export default function findActionTests({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(space.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get.ts index 69e7341cac009..bed4c805aaf57 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get.ts @@ -27,7 +27,7 @@ export default function getActionTests({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(space.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, @@ -60,7 +60,7 @@ export default function getActionTests({ getService }: FtrProviderContext) { expect(response.body).to.eql({ id: createdAction.id, actionTypeId: 'test.index-record', - description: 'My action', + name: 'My action', config: { unencrypted: `This value shouldn't get encrypted`, }, @@ -76,7 +76,7 @@ export default function getActionTests({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(space.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/manual/pr_40694.js b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/manual/pr_40694.js index bc233bfb629d5..ced6799690d6a 100755 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/manual/pr_40694.js +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/manual/pr_40694.js @@ -17,7 +17,7 @@ async function main() { response = await httpPost('api/action', { actionTypeId: '.email', - description: 'an email action', + name: 'an email action', config: { from: 'patrick.mueller@elastic.co', host: 'localhost', @@ -37,7 +37,7 @@ async function main() { console.log(`action after create: ${JSON.stringify(response, null, 4)}`); response = await httpPut(`api/action/${actionId}`, { - description: 'an email action', + name: 'an email action', config: { from: 'patrick.mueller@elastic.co', service: '__json', diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/update.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/update.ts index 0d42763ba1f04..d41a2a10b770a 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/update.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/update.ts @@ -27,7 +27,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(space.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, @@ -44,7 +44,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { .auth(user.username, user.password) .set('kbn-xsrf', 'foo') .send({ - description: 'My action updated', + name: 'My action updated', config: { unencrypted: `This value shouldn't get encrypted`, }, @@ -70,7 +70,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { expect(response.body).to.eql({ id: createdAction.id, actionTypeId: 'test.index-record', - description: 'My action updated', + name: 'My action updated', config: { unencrypted: `This value shouldn't get encrypted`, }, @@ -86,7 +86,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(space.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, @@ -103,7 +103,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { .auth(user.username, user.password) .set('kbn-xsrf', 'foo') .send({ - description: 'My action updated', + name: 'My action updated', config: { unencrypted: `This value shouldn't get encrypted`, }, @@ -142,7 +142,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'foo') .auth(user.username, user.password) .send({ - description: 'My action updated', + name: 'My action updated', config: null, }); @@ -181,7 +181,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'foo') .auth(user.username, user.password) .send({ - description: 'My action updated', + name: 'My action updated', config: { unencrypted: `This value shouldn't get encrypted`, }, @@ -239,8 +239,8 @@ export default function updateActionTests({ getService }: FtrProviderContext) { expect(response.body).to.eql({ statusCode: 400, error: 'Bad Request', - message: 'child "description" fails because ["description" is required]', - validation: { source: 'payload', keys: ['description'] }, + message: 'child "name" fails because ["name" is required]', + validation: { source: 'payload', keys: ['name'] }, }); break; default: @@ -253,7 +253,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(space.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, @@ -270,7 +270,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'foo') .auth(user.username, user.password) .send({ - description: 'My action updated', + name: 'My action updated', config: { unencrypted: `This value shouldn't get encrypted`, }, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/alerts.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/alerts.ts index 09a642d1d14bb..edfb340bfd784 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/alerts.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/alerts.ts @@ -53,7 +53,7 @@ export default function alertTests({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(space.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, @@ -151,7 +151,7 @@ export default function alertTests({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(space.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'Test rate limit', + name: 'Test rate limit', actionTypeId: 'test.rate-limit', config: {}, }) @@ -344,7 +344,7 @@ export default function alertTests({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(space.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action', + name: 'My action', actionTypeId: 'test.authorization', }) .expect(200); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/es_index.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/es_index.ts index 7e971d033b5c4..79e0da3a4c68a 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/es_index.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/es_index.ts @@ -29,7 +29,7 @@ export default function indexTest({ getService }: FtrProviderContext) { .post('/api/action') .set('kbn-xsrf', 'foo') .send({ - description: 'An index action', + name: 'An index action', actionTypeId: '.index', config: {}, secrets: {}, @@ -38,7 +38,7 @@ export default function indexTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, - description: 'An index action', + name: 'An index action', actionTypeId: '.index', config: { index: null, @@ -53,7 +53,7 @@ export default function indexTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, - description: 'An index action', + name: 'An index action', actionTypeId: '.index', config: { index: null }, }); @@ -63,7 +63,7 @@ export default function indexTest({ getService }: FtrProviderContext) { .post('/api/action') .set('kbn-xsrf', 'foo') .send({ - description: 'An index action with index config', + name: 'An index action with index config', actionTypeId: '.index', config: { index: ES_TEST_INDEX_NAME, @@ -73,7 +73,7 @@ export default function indexTest({ getService }: FtrProviderContext) { expect(createdActionWithIndex).to.eql({ id: createdActionWithIndex.id, - description: 'An index action with index config', + name: 'An index action with index config', actionTypeId: '.index', config: { index: ES_TEST_INDEX_NAME, @@ -88,7 +88,7 @@ export default function indexTest({ getService }: FtrProviderContext) { expect(fetchedActionWithIndex).to.eql({ id: fetchedActionWithIndex.id, - description: 'An index action with index config', + name: 'An index action with index config', actionTypeId: '.index', config: { index: ES_TEST_INDEX_NAME, diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts index bf648890c591b..982688cc45c05 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts @@ -23,7 +23,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(Spaces.space1.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, @@ -36,7 +36,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { expect(response.statusCode).to.eql(200); expect(response.body).to.eql({ id: response.body.id, - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/delete.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/delete.ts index 5fd3a533bbd48..283e51352c272 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/delete.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/delete.ts @@ -22,7 +22,7 @@ export default function deleteActionTests({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(Spaces.space1.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, @@ -44,7 +44,7 @@ export default function deleteActionTests({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(Spaces.space1.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/execute.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/execute.ts index e97b6d480c470..a0eac43d06c66 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/execute.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/execute.ts @@ -42,7 +42,7 @@ export default function({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(Spaces.space1.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, @@ -93,7 +93,7 @@ export default function({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(Spaces.space1.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, @@ -129,7 +129,7 @@ export default function({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(Spaces.space1.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action', + name: 'My action', actionTypeId: 'test.authorization', }) .expect(200); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/find.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/find.ts index 20ea3f3044310..acbc9edc1f2fb 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/find.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/find.ts @@ -22,7 +22,7 @@ export default function findActionTests({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(Spaces.space1.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, @@ -47,7 +47,7 @@ export default function findActionTests({ getService }: FtrProviderContext) { data: [ { id: createdAction.id, - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, @@ -63,7 +63,7 @@ export default function findActionTests({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(Spaces.space1.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts index 804432a12bb7f..0f896bfaa0af9 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts @@ -22,7 +22,7 @@ export default function getActionTests({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(Spaces.space1.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, @@ -39,7 +39,7 @@ export default function getActionTests({ getService }: FtrProviderContext) { .expect(200, { id: createdAction.id, actionTypeId: 'test.index-record', - description: 'My action', + name: 'My action', config: { unencrypted: `This value shouldn't get encrypted`, }, @@ -51,7 +51,7 @@ export default function getActionTests({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(Spaces.space1.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts index f2c1f21712be1..bb1ee31bddfe0 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts @@ -22,7 +22,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(Spaces.space1.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, @@ -38,7 +38,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { .put(`${getUrlPrefix(Spaces.space1.id)}/api/action/${createdAction.id}`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action updated', + name: 'My action updated', config: { unencrypted: `This value shouldn't get encrypted`, }, @@ -49,7 +49,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { .expect(200, { id: createdAction.id, actionTypeId: 'test.index-record', - description: 'My action updated', + name: 'My action updated', config: { unencrypted: `This value shouldn't get encrypted`, }, @@ -61,7 +61,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(Spaces.space1.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, @@ -77,7 +77,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { .put(`${getUrlPrefix(Spaces.other.id)}/api/action/${createdAction.id}`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action updated', + name: 'My action updated', config: { unencrypted: `This value shouldn't get encrypted`, }, diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/alerts.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/alerts.ts index 9af4848c57d7d..5fafd8b0bfb61 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/alerts.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/alerts.ts @@ -37,7 +37,7 @@ export default function alertTests({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(Spaces.space1.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action', + name: 'My action', actionTypeId: 'test.index-record', config: { unencrypted: `This value shouldn't get encrypted`, @@ -110,7 +110,7 @@ export default function alertTests({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(Spaces.space1.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'Test rate limit', + name: 'Test rate limit', actionTypeId: 'test.rate-limit', config: {}, }) @@ -227,7 +227,7 @@ export default function alertTests({ getService }: FtrProviderContext) { .post(`${getUrlPrefix(Spaces.space1.id)}/api/action`) .set('kbn-xsrf', 'foo') .send({ - description: 'My action', + name: 'My action', actionTypeId: 'test.authorization', }) .expect(200); diff --git a/x-pack/test/api_integration/apis/apm/agent_configuration.ts b/x-pack/test/api_integration/apis/apm/agent_configuration.ts index 43ba8616e6872..12e08869fa586 100644 --- a/x-pack/test/api_integration/apis/apm/agent_configuration.ts +++ b/x-pack/test/api_integration/apis/apm/agent_configuration.ts @@ -32,17 +32,56 @@ export default function agentConfigurationTests({ getService }: FtrProviderConte function deleteCreatedConfigurations() { const promises = Promise.all(createdConfigIds.map(deleteConfiguration)); - createdConfigIds = []; return promises; } function deleteConfiguration(configurationId: string) { return supertest .delete(`/api/apm/settings/agent-configuration/${configurationId}`) - .set('kbn-xsrf', 'foo'); + .set('kbn-xsrf', 'foo') + .then((response: any) => { + createdConfigIds = createdConfigIds.filter(id => id === configurationId); + return response; + }); } describe('agent configuration', () => { + describe('when creating one configuration', () => { + let createdConfigId: string; + + const parameters = { + service: { name: 'myservice', environment: 'development' }, + etag: '7312bdcc34999629a3d39df24ed9b2a7553c0c39', + }; + + before(async () => { + log.debug('creating agent configuration'); + + // all / all + const { body } = await createConfiguration({ + service: {}, + settings: { transaction_sample_rate: 0.1 }, + }); + + createdConfigId = body._id; + }); + + it('returns the created configuration', async () => { + const { statusCode, body } = await searchConfigurations(parameters); + + expect(statusCode).to.equal(200); + expect(body._id).to.equal(createdConfigId); + }); + + it('succesfully deletes the configuration', async () => { + await deleteConfiguration(createdConfigId); + + const { statusCode } = await searchConfigurations(parameters); + + expect(statusCode).to.equal(404); + }); + }); + describe('when creating four configurations', () => { before(async () => { log.debug('creating agent configuration'); diff --git a/x-pack/test/api_integration/apis/apm/feature_controls.ts b/x-pack/test/api_integration/apis/apm/feature_controls.ts index 7f841747cdcab..1561a41d7d904 100644 --- a/x-pack/test/api_integration/apis/apm/feature_controls.ts +++ b/x-pack/test/api_integration/apis/apm/feature_controls.ts @@ -39,7 +39,10 @@ export default function featureControlsTests({ getService }: FtrProviderContext) } const endpoints: Endpoint[] = [ { - req: { url: `/api/apm/services/foo/errors?start=${start}&end=${end}&uiFilters=%7B%7D` }, + // this doubles as a smoke test for the _debug query parameter + req: { + url: `/api/apm/services/foo/errors?start=${start}&end=${end}&uiFilters=%7B%7D_debug=true`, + }, expectForbidden: expect404, expectResponse: expect200, }, diff --git a/x-pack/test/functional/apps/graph/graph.ts b/x-pack/test/functional/apps/graph/graph.ts index f640a34b36ddf..58ee1668df701 100644 --- a/x-pack/test/functional/apps/graph/graph.ts +++ b/x-pack/test/functional/apps/graph/graph.ts @@ -82,9 +82,11 @@ export default function({ getService, getPageObjects }: FtrProviderContext) { const { nodes } = await PageObjects.graph.getGraphObjects(); const circlesText = nodes.map(({ label }) => label); expect(circlesText.length).to.equal(expectedNodes.length); - circlesText.forEach(circleText => { - expect(expectedNodes.includes(circleText)).to.be(true); - }); + const unexpectedCircleTexts = circlesText.filter(t => !expectedNodes.includes(t)); + + if (unexpectedCircleTexts.length) { + throw new Error(`Find unexpected circle texts: ${unexpectedCircleTexts}`); + } }); it('should show correct connections', async function() { diff --git a/x-pack/test/functional/apps/machine_learning/anomaly_detection/advanced_job.ts b/x-pack/test/functional/apps/machine_learning/anomaly_detection/advanced_job.ts index 29fd026026efe..9f4506ecccf7c 100644 --- a/x-pack/test/functional/apps/machine_learning/anomaly_detection/advanced_job.ts +++ b/x-pack/test/functional/apps/machine_learning/anomaly_detection/advanced_job.ts @@ -297,7 +297,7 @@ export default function({ getService }: FtrProviderContext) { }); it('job creation loads the job type selection page', async () => { - await ml.jobSourceSelection.selectSource(testData.jobSource); + await ml.jobSourceSelection.selectSourceForAnomalyDetectionJob(testData.jobSource); }); it('job creation loads the advanced job wizard page', async () => { diff --git a/x-pack/test/functional/apps/machine_learning/anomaly_detection/multi_metric_job.ts b/x-pack/test/functional/apps/machine_learning/anomaly_detection/multi_metric_job.ts index 11cb48de260f1..935fbc0102149 100644 --- a/x-pack/test/functional/apps/machine_learning/anomaly_detection/multi_metric_job.ts +++ b/x-pack/test/functional/apps/machine_learning/anomaly_detection/multi_metric_job.ts @@ -92,7 +92,7 @@ export default function({ getService }: FtrProviderContext) { }); it('job creation loads the job type selection page', async () => { - await ml.jobSourceSelection.selectSource('farequote'); + await ml.jobSourceSelection.selectSourceForAnomalyDetectionJob('farequote'); }); it('job creation loads the multi metric job wizard page', async () => { diff --git a/x-pack/test/functional/apps/machine_learning/anomaly_detection/population_job.ts b/x-pack/test/functional/apps/machine_learning/anomaly_detection/population_job.ts index 71e66cc569f4e..ff2275837ce2e 100644 --- a/x-pack/test/functional/apps/machine_learning/anomaly_detection/population_job.ts +++ b/x-pack/test/functional/apps/machine_learning/anomaly_detection/population_job.ts @@ -106,7 +106,7 @@ export default function({ getService }: FtrProviderContext) { }); it('job creation loads the job type selection page', async () => { - await ml.jobSourceSelection.selectSource('ecommerce'); + await ml.jobSourceSelection.selectSourceForAnomalyDetectionJob('ecommerce'); }); it('job creation loads the population job wizard page', async () => { diff --git a/x-pack/test/functional/apps/machine_learning/anomaly_detection/saved_search_job.ts b/x-pack/test/functional/apps/machine_learning/anomaly_detection/saved_search_job.ts index 0330e141b0890..7d989bc6244b8 100644 --- a/x-pack/test/functional/apps/machine_learning/anomaly_detection/saved_search_job.ts +++ b/x-pack/test/functional/apps/machine_learning/anomaly_detection/saved_search_job.ts @@ -294,7 +294,7 @@ export default function({ getService }: FtrProviderContext) { }); it('job creation loads the job type selection page', async () => { - await ml.jobSourceSelection.selectSource(testData.jobSource); + await ml.jobSourceSelection.selectSourceForAnomalyDetectionJob(testData.jobSource); }); it('job creation loads the multi metric job wizard page', async () => { diff --git a/x-pack/test/functional/apps/machine_learning/anomaly_detection/single_metric_job.ts b/x-pack/test/functional/apps/machine_learning/anomaly_detection/single_metric_job.ts index b5a544b7af9f6..1983e98a0123d 100644 --- a/x-pack/test/functional/apps/machine_learning/anomaly_detection/single_metric_job.ts +++ b/x-pack/test/functional/apps/machine_learning/anomaly_detection/single_metric_job.ts @@ -91,7 +91,7 @@ export default function({ getService }: FtrProviderContext) { }); it('job creation loads the job type selection page', async () => { - await ml.jobSourceSelection.selectSource('farequote'); + await ml.jobSourceSelection.selectSourceForAnomalyDetectionJob('farequote'); }); it('job creation loads the single metric job wizard page', async () => { diff --git a/x-pack/test/functional/services/machine_learning/job_source_selection.ts b/x-pack/test/functional/services/machine_learning/job_source_selection.ts index 38dd6070ec321..a1857d882be3d 100644 --- a/x-pack/test/functional/services/machine_learning/job_source_selection.ts +++ b/x-pack/test/functional/services/machine_learning/job_source_selection.ts @@ -8,6 +8,7 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export function MachineLearningJobSourceSelectionProvider({ getService }: FtrProviderContext) { const testSubjects = getService('testSubjects'); + const retry = getService('retry'); return { async assertSourceListContainsEntry(sourceName: string) { @@ -21,16 +22,20 @@ export function MachineLearningJobSourceSelectionProvider({ getService }: FtrPro await this.assertSourceListContainsEntry(sourceName); }, - async selectSource(sourceName: string) { + async selectSource(sourceName: string, nextPageSubj: string) { await this.filterSourceSelection(sourceName); - await testSubjects.clickWhenNotDisabled(`savedObjectTitle${sourceName}`); - await testSubjects.existOrFail('mlPageJobTypeSelection'); + await retry.tryForTime(30 * 1000, async () => { + await testSubjects.clickWhenNotDisabled(`savedObjectTitle${sourceName}`); + await testSubjects.existOrFail(nextPageSubj, { timeout: 10 * 1000 }); + }); + }, + + async selectSourceForAnomalyDetectionJob(sourceName: string) { + await this.selectSource(sourceName, 'mlPageJobTypeSelection'); }, async selectSourceForIndexBasedDataVisualizer(sourceName: string) { - await this.filterSourceSelection(sourceName); - await testSubjects.clickWhenNotDisabled(`savedObjectTitle${sourceName}`); - await testSubjects.existOrFail('mlPageIndexDataVisualizer', { timeout: 10 * 1000 }); + await this.selectSource(sourceName, 'mlPageIndexDataVisualizer'); }, }; } diff --git a/x-pack/test/oidc_api_integration/apis/implicit_flow/oidc_auth.ts b/x-pack/test/oidc_api_integration/apis/implicit_flow/oidc_auth.ts index 0c77ff3a0640e..ed886da4d9ae1 100644 --- a/x-pack/test/oidc_api_integration/apis/implicit_flow/oidc_auth.ts +++ b/x-pack/test/oidc_api_integration/apis/implicit_flow/oidc_auth.ts @@ -99,7 +99,8 @@ export default function({ getService }: FtrProviderContext) { .expect(401); }); - it('should succeed if both the OpenID Connect response and the cookie are provided', async () => { + // FLAKY: https://github.com/elastic/kibana/issues/43938 + it.skip('should succeed if both the OpenID Connect response and the cookie are provided', async () => { const { idToken, accessToken } = createTokens('1', stateAndNonce.nonce); const authenticationResponse = `https://kibana.com/api/security/v1/oidc/implicit#id_token=${idToken}&state=${stateAndNonce.state}&token_type=bearer&access_token=${accessToken}`;