From 957dbdcd1f270d4db350845d6cb9600f8696a8b4 Mon Sep 17 00:00:00 2001 From: Joshua Li Date: Fri, 8 Oct 2021 16:15:16 -0700 Subject: [PATCH 1/5] Update validation for observability notebooks integration Signed-off-by: Joshua Li --- dashboards-reports/server/routes/report.ts | 2 +- dashboards-reports/server/utils/validationHelper.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dashboards-reports/server/routes/report.ts b/dashboards-reports/server/routes/report.ts index b2a88658..d4b5658c 100644 --- a/dashboards-reports/server/routes/report.ts +++ b/dashboards-reports/server/routes/report.ts @@ -70,7 +70,7 @@ export default function (router: IRouter, accessInfo: AccessInfoType) { // input validation try { report.report_definition.report_params.core_params.origin = - request.headers.origin; + request.headers.origin || request.headers.host; report = await validateReport( context.core.opensearch.legacy.client, report, diff --git a/dashboards-reports/server/utils/validationHelper.ts b/dashboards-reports/server/utils/validationHelper.ts index 705c8cd0..252ac9a1 100644 --- a/dashboards-reports/server/utils/validationHelper.ts +++ b/dashboards-reports/server/utils/validationHelper.ts @@ -37,7 +37,7 @@ import { REPORT_TYPE } from '../../server/routes/utils/constants'; export const isValidRelativeUrl = (relativeUrl: string) => { let normalizedRelativeUrl = relativeUrl - if (!relativeUrl.includes('notebooks-dashboards')) { + if (!relativeUrl.includes('observability#/notebooks')) { normalizedRelativeUrl = path.posix.normalize(relativeUrl); } @@ -55,7 +55,7 @@ export const isValidRelativeUrl = (relativeUrl: string) => { export const regexDuration = /^(-?)P(?=\d|T\d)(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)([DW]))?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+(?:\.\d+)?)S)?)?$/; export const regexEmailAddress = /\S+@\S+\.\S+/; export const regexReportName = /^[\w\-\s\(\)\[\]\,\_\-+]+$/; -export const regexRelativeUrl = /^\/(_plugin\/kibana\/|_dashboards\/)?app\/(dashboards|visualize|discover|notebooks-dashboards\?view=output_only)([?&]security_tenant=.+|)#\/(view\/|edit\/)?[^\/]+$/; +export const regexRelativeUrl = /^\/(_plugin\/kibana\/|_dashboards\/)?app\/(dashboards|visualize|discover|observability)([?&]security_tenant=.+|)#\/(notebooks\/|view\/|edit\/)?[^\/]+$/; export const validateReport = async ( client: ILegacyScopedClusterClient, From cb4fb5620569de80db06ad79fe5a63e459cf4277 Mon Sep 17 00:00:00 2001 From: Joshua Li Date: Fri, 8 Oct 2021 16:34:14 -0700 Subject: [PATCH 2/5] Update test Signed-off-by: Joshua Li --- .../server/utils/__tests__/validationHelper.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dashboards-reports/server/utils/__tests__/validationHelper.test.ts b/dashboards-reports/server/utils/__tests__/validationHelper.test.ts index 41ce3b49..692d9fe4 100644 --- a/dashboards-reports/server/utils/__tests__/validationHelper.test.ts +++ b/dashboards-reports/server/utils/__tests__/validationHelper.test.ts @@ -71,7 +71,7 @@ const createReportDefinitionNotebookInput: ReportDefinitionSchemaType = { report_source: REPORT_TYPE.notebook, description: 'Hi this is your Notebook on demand', core_params: { - base_url: `/app/notebooks-dashboards?view=output_only#/${SAMPLE_SAVED_OBJECT_ID}`, + base_url: `/app/observability#/notebooks/${SAMPLE_SAVED_OBJECT_ID}`, window_width: 1300, window_height: 900, report_format: FORMAT.pdf, From ab2ae98042d1a7c9e39756985fc7f924b4fa4f29 Mon Sep 17 00:00:00 2001 From: Joshua Li Date: Wed, 13 Oct 2021 10:40:08 -0700 Subject: [PATCH 3/5] Support legacy notebooks url in validation Signed-off-by: Joshua Li --- .../utils/__tests__/validationHelper.test.ts | 36 +++++++++++++++++++ .../server/utils/validationHelper.ts | 7 ++-- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/dashboards-reports/server/utils/__tests__/validationHelper.test.ts b/dashboards-reports/server/utils/__tests__/validationHelper.test.ts index 692d9fe4..cacd3d61 100644 --- a/dashboards-reports/server/utils/__tests__/validationHelper.test.ts +++ b/dashboards-reports/server/utils/__tests__/validationHelper.test.ts @@ -65,6 +65,32 @@ const createReportInput: ReportSchemaType = { report_definition: createReportDefinitionInput, }; +// this is the url format used before notebooks merged into observability +const createReportDefinitionNotebookLegacyInput: ReportDefinitionSchemaType = { + report_params: { + report_name: 'test notebooks report', + report_source: REPORT_TYPE.notebook, + description: 'Hi this is your Notebook on demand', + core_params: { + base_url: `/app/notebooks-dashboards?view=output_only#/${SAMPLE_SAVED_OBJECT_ID}`, + window_width: 1300, + window_height: 900, + report_format: FORMAT.pdf, + time_duration: 'PT5M', + origin: 'http://localhost:5601', + }, + }, + delivery: { + configIds: [], + title: 'title', + textDescription: 'text description', + htmlDescription: 'html description' + }, + trigger: { + trigger_type: TRIGGER_TYPE.onDemand, + }, +} + const createReportDefinitionNotebookInput: ReportDefinitionSchemaType = { report_params: { report_name: 'test notebooks report', @@ -118,6 +144,16 @@ describe('test input validation', () => { expect(report).toBeDefined(); }); + test('create notebook report definition with legacy base url format', async () => { + const savedObjectIds = [`notebook:${SAMPLE_SAVED_OBJECT_ID}`]; + const client = mockOpenSearchClient(savedObjectIds); + const report = await validateReportDefinition( + client, + createReportDefinitionNotebookLegacyInput + ); + expect(report).toBeDefined(); + }); + test('create notebook report definition with correct base url format', async () => { const savedObjectIds = [`notebook:${SAMPLE_SAVED_OBJECT_ID}`]; const client = mockOpenSearchClient(savedObjectIds); diff --git a/dashboards-reports/server/utils/validationHelper.ts b/dashboards-reports/server/utils/validationHelper.ts index 252ac9a1..590e1e9a 100644 --- a/dashboards-reports/server/utils/validationHelper.ts +++ b/dashboards-reports/server/utils/validationHelper.ts @@ -37,7 +37,10 @@ import { REPORT_TYPE } from '../../server/routes/utils/constants'; export const isValidRelativeUrl = (relativeUrl: string) => { let normalizedRelativeUrl = relativeUrl - if (!relativeUrl.includes('observability#/notebooks')) { + if ( + !relativeUrl.includes('observability#/notebooks') && + !relativeUrl.includes('notebooks-dashboards') + ) { normalizedRelativeUrl = path.posix.normalize(relativeUrl); } @@ -55,7 +58,7 @@ export const isValidRelativeUrl = (relativeUrl: string) => { export const regexDuration = /^(-?)P(?=\d|T\d)(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)([DW]))?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+(?:\.\d+)?)S)?)?$/; export const regexEmailAddress = /\S+@\S+\.\S+/; export const regexReportName = /^[\w\-\s\(\)\[\]\,\_\-+]+$/; -export const regexRelativeUrl = /^\/(_plugin\/kibana\/|_dashboards\/)?app\/(dashboards|visualize|discover|observability)([?&]security_tenant=.+|)#\/(notebooks\/|view\/|edit\/)?[^\/]+$/; +export const regexRelativeUrl = /^\/(_plugin\/kibana\/|_dashboards\/)?app\/(dashboards|visualize|discover|observability|notebooks-dashboards\?view=output_only)([?&]security_tenant=.+|)#\/(notebooks\/|view\/|edit\/)?[^\/]+$/; export const validateReport = async ( client: ILegacyScopedClusterClient, From 88c1ac2749c3ddabe10a4d8f7b07eb2d7a7eb636 Mon Sep 17 00:00:00 2001 From: Joshua Li Date: Fri, 15 Oct 2021 14:09:52 -0700 Subject: [PATCH 4/5] Add updated api for getting notebooks Signed-off-by: Joshua Li --- .../report_definitions/report_settings/report_settings.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dashboards-reports/public/components/report_definitions/report_settings/report_settings.tsx b/dashboards-reports/public/components/report_definitions/report_settings/report_settings.tsx index 2ecf927a..3317bb5a 100644 --- a/dashboards-reports/public/components/report_definitions/report_settings/report_settings.tsx +++ b/dashboards-reports/public/components/report_definitions/report_settings/report_settings.tsx @@ -658,7 +658,11 @@ export function ReportSettings(props: ReportSettingProps) { }); await httpClientProps - .get('../api/notebooks/') + .get('../api/observability/notebooks/') + .catch((error: any) => { + console.error('error fetching notebooks, retrying with legacy api', error) + return httpClientProps.get('../api/notebooks/') + }) .then(async (response: any) => { let notebooksOptions = getNotebooksOptions(response.data); reportSourceOptions.notebooks = notebooksOptions; From 53906156fe0799d02415e2f3449b172f677ca97d Mon Sep 17 00:00:00 2001 From: Joshua Li Date: Fri, 15 Oct 2021 14:38:19 -0700 Subject: [PATCH 5/5] Update httpClient mock Signed-off-by: Joshua Li --- dashboards-reports/test/httpMockClient.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dashboards-reports/test/httpMockClient.js b/dashboards-reports/test/httpMockClient.js index 084f1b85..40efdc2a 100644 --- a/dashboards-reports/test/httpMockClient.js +++ b/dashboards-reports/test/httpMockClient.js @@ -38,6 +38,12 @@ httpClientMock.get = jest.fn(() => ({ })), catch: jest.fn(), })), + catch: jest.fn(() => ({ + then: jest.fn(() => ({ + catch: jest.fn() + })), + catch: jest.fn(), + })), })); httpClientMock.head = jest.fn(); httpClientMock.post = jest.fn(() => ({