Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into details-pages-fix
Browse files Browse the repository at this point in the history
  • Loading branch information
davidcui1225 committed Oct 27, 2021
2 parents b344e97 + 56008de commit 71c59e2
Show file tree
Hide file tree
Showing 11 changed files with 71 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import {
import { timeRangeMatcher } from '../utils/utils';
import { parse } from 'url';
import { unhashUrl } from '../../../../../src/plugins/opensearch_dashboards_utils/public';
import { uiSettingsService } from '../utils/settings_service';

const generateInContextReport = async (
timeRanges,
Expand Down Expand Up @@ -106,7 +107,7 @@ const generateInContextReport = async (
fetch(
`../api/reporting/generateReport?timezone=${
Intl.DateTimeFormat().resolvedOptions().timeZone
}`,
}&dateFormat=${uiSettingsService.get('dateFormat')}`,
{
headers: {
'Content-Type': 'application/json',
Expand Down
11 changes: 9 additions & 2 deletions dashboards-reports/public/components/main/main_utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import 'babel-polyfill';
import { i18n } from '@osd/i18n';
import { HttpFetchOptions, HttpSetup } from '../../../../../src/core/public';
import { uiSettingsService } from '../utils/settings_service';

export const displayDeliveryChannels = (configIds: Array<string>, channels: Array<{label: string, id: string}>) => {
let displayChannels = [];
Expand Down Expand Up @@ -193,7 +194,10 @@ export const generateReportFromDefinitionId = async (
headers: {
'Content-Type': 'application/json',
},
query: { timezone: Intl.DateTimeFormat().resolvedOptions().timeZone },
query: {
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
dateFormat: uiSettingsService.get('dateFormat'),
},
})
.then(async (response: any) => {
// for emailing a report, this API response doesn't have response body
Expand Down Expand Up @@ -226,7 +230,10 @@ export const generateReportById = async (
) => {
await httpClient
.get(`../api/reporting/generateReport/${reportId}`, {
query: { timezone: Intl.DateTimeFormat().resolvedOptions().timeZone },
query: {
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
dateFormat: uiSettingsService.get('dateFormat'),
},
})
.then(async (response) => {
//TODO: duplicate code, extract to be a function that can reuse. e.g. handleResponse(response)
Expand Down
23 changes: 23 additions & 0 deletions dashboards-reports/public/components/utils/settings_service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*
* Modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*/

import { IUiSettingsClient } from '../../../../../src/core/public';

let uiSettings: IUiSettingsClient;

export const uiSettingsService = {
init: (client: IUiSettingsClient) => {
uiSettings = client;
},
get: (key: string, defaultOverride?: any) => {
return uiSettings?.get(key, defaultOverride) || '';
},
};
2 changes: 2 additions & 0 deletions dashboards-reports/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,13 @@ import {
import { i18n } from '@osd/i18n';
import './components/context_menu/context_menu';
import { PLUGIN_ID, PLUGIN_NAME } from '../common';
import { uiSettingsService } from './components/utils/settings_service';

export class ReportsDashboardsPlugin
implements Plugin<ReportsDashboardsPluginSetup, ReportsDashboardsPluginStart>
{
public setup(core: CoreSetup): ReportsDashboardsPluginSetup {
uiSettingsService.init(core.uiSettings);
// Register an application into the side navigation menu
core.application.register({
id: PLUGIN_ID,
Expand Down
42 changes: 10 additions & 32 deletions dashboards-reports/server/routes/lib/createReport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ import {
REPORT_TYPE,
REPORT_STATE,
DELIVERY_TYPE,
SECURITY_CONSTANTS,
DATA_REPORT_CONFIG,
EXTRA_HEADERS,
} from '../utils/constants';

import {
Expand All @@ -46,6 +47,7 @@ import { updateReportState } from './updateReportState';
import { saveReport } from './saveReport';
import { SemaphoreInterface } from 'async-mutex';
import { AccessInfoType } from 'server';
import _ from 'lodash';

export const createReport = async (
request: OpenSearchDashboardsRequest,
Expand All @@ -66,6 +68,8 @@ export const createReport = async (
const opensearchClient = context.core.opensearch.legacy.client;
// @ts-ignore
const timezone = request.query.timezone;
// @ts-ignore
const dateFormat = request.query.dateFormat || DATA_REPORT_CONFIG.excelDateFormat;
const {
basePath,
serverInfo: { protocol, port, hostname },
Expand All @@ -75,9 +79,7 @@ export const createReport = async (
let reportId;

const {
report_definition: {
report_params: reportParams,
},
report_definition: { report_params: reportParams },
} = report;
const { report_source: reportSource } = reportParams;

Expand All @@ -94,6 +96,7 @@ export const createReport = async (
createReportResult = await createSavedSearchReport(
report,
opensearchClient,
dateFormat,
isScheduledTask
);
} else {
Expand All @@ -103,40 +106,15 @@ export const createReport = async (
? report.query_url
: `${basePath}${report.query_url}`;
const completeQueryUrl = `${protocol}://${hostname}:${port}${relativeUrl}`;
// Check if security is enabled. TODO: is there a better way to check?
let cookieObject: SetCookie | undefined;
if (request.headers.cookie) {
const cookies = request.headers.cookie.split(';');
cookies.map((item: string) => {
const cookie = item.trim().split('=');
if (cookie[0] === SECURITY_CONSTANTS.AUTH_COOKIE_NAME) {
cookieObject = {
name: cookie[0],
value: cookie[1],
url: completeQueryUrl,
path: basePath,
};
}
});
}
// If header exists assuming that it needs forwarding
let additionalHeaders: Headers | undefined;
if (request.headers[SECURITY_CONSTANTS.PROXY_AUTH_USER_HEADER]) {
additionalHeaders = {}
additionalHeaders[SECURITY_CONSTANTS.PROXY_AUTH_USER_HEADER] = request.headers[SECURITY_CONSTANTS.PROXY_AUTH_USER_HEADER];
additionalHeaders[SECURITY_CONSTANTS.PROXY_AUTH_IP_HEADER] = request.headers[SECURITY_CONSTANTS.PROXY_AUTH_IP_HEADER];
if (request.headers[SECURITY_CONSTANTS.PROXY_AUTH_ROLES_HEADER]) {
additionalHeaders[SECURITY_CONSTANTS.PROXY_AUTH_ROLES_HEADER] = request.headers[SECURITY_CONSTANTS.PROXY_AUTH_ROLES_HEADER]
}
}
const extraHeaders = _.pick(request.headers, EXTRA_HEADERS);

const [value, release] = await semaphore.acquire();
try {
createReportResult = await createVisualReport(
reportParams,
completeQueryUrl,
logger,
cookieObject,
additionalHeaders,
extraHeaders,
timezone
);
} finally {
Expand Down
3 changes: 3 additions & 0 deletions dashboards-reports/server/routes/report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export default function (router: IRouter, accessInfo: AccessInfoType) {
body: schema.any(),
query: schema.object({
timezone: schema.maybe(schema.string()),
dateFormat: schema.maybe(schema.string()),
}),
},
},
Expand Down Expand Up @@ -121,6 +122,7 @@ export default function (router: IRouter, accessInfo: AccessInfoType) {
}),
query: schema.object({
timezone: schema.string(),
dateFormat: schema.maybe(schema.string()),
}),
},
},
Expand Down Expand Up @@ -186,6 +188,7 @@ export default function (router: IRouter, accessInfo: AccessInfoType) {
}),
query: schema.object({
timezone: schema.string(),
dateFormat: schema.maybe(schema.string()),
}),
},
},
Expand Down
13 changes: 8 additions & 5 deletions dashboards-reports/server/routes/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export enum REPORT_TYPE {
}

export enum DATA_REPORT_CONFIG {
excelDateFormat = 'MM/DD/YYYY h:mm:ss a',
excelDateFormat = 'MM/DD/YYYY h:mm:ss.SSS a',
}

export enum TRIGGER_TYPE {
Expand All @@ -89,13 +89,16 @@ export const DEFAULT_MAX_SIZE = 10000;
export const DEFAULT_REPORT_HEADER = '<h1>OpenSearch Dashboards Reports</h1>';

export const SECURITY_CONSTANTS = {
AUTH_COOKIE_NAME: 'security_authentication',
TENANT_LOCAL_STORAGE_KEY: 'opendistro::security::tenant::show_popup',
PROXY_AUTH_USER_HEADER: 'x-proxy-user',
PROXY_AUTH_ROLES_HEADER: 'x-proxy-roles',
PROXY_AUTH_IP_HEADER: 'x-forwarded-for',
};

export const EXTRA_HEADERS = [
'cookie',
'x-proxy-user',
'x-proxy-roles',
'x-forwarded-for',
];

export const CHROMIUM_PATH = `${__dirname}/../../../.chromium/headless_shell`;

/**
Expand Down
6 changes: 2 additions & 4 deletions dashboards-reports/server/routes/utils/dataReportHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,17 +178,15 @@ export const buildQuery = (report, is_count) => {
};

// Fetch the data from OpenSearch
export const getOpenSearchData = (arrayHits, report, params) => {
export const getOpenSearchData = (arrayHits, report, params, dateFormat: string) => {
let hits: any = [];
for (let valueRes of arrayHits) {
for (let data of valueRes.hits) {
const fields = data.fields;
// get all the fields of type date and format them to excel format
for (let dateType of report._source.dateFields) {
if (data._source[dateType]) {
data._source[dateType] = moment(fields[dateType][0]).format(
DATA_REPORT_CONFIG.excelDateFormat
);
data._source[dateType] = moment(fields[dateType][0]).format(dateFormat);
}
}
delete data['fields'];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ const scrollTimeout = '1m';
export async function createSavedSearchReport(
report: any,
client: ILegacyClusterClient | ILegacyScopedClusterClient,
dateFormat: string,
isScheduledTask: boolean = true
): Promise<CreateReportResultType> {
const params = report.report_definition.report_params;
Expand All @@ -58,6 +59,7 @@ export async function createSavedSearchReport(
const data = await generateReportData(
client,
params.core_params,
dateFormat,
isScheduledTask
);

Expand Down Expand Up @@ -141,6 +143,7 @@ async function populateMetaData(
async function generateReportData(
client: ILegacyClusterClient | ILegacyScopedClusterClient,
params: any,
dateFormat: string,
isScheduledTask: boolean
) {
let opensearchData: any = {};
Expand Down Expand Up @@ -267,7 +270,7 @@ async function generateReportData(
for (const dateType of report._source.dateFields) {
docvalues.push({
field: dateType,
format: 'date_hour_minute',
format: 'date_hour_minute_second_fraction',
});
}

Expand All @@ -282,7 +285,7 @@ async function generateReportData(
// Parse OpenSearch data and convert to CSV
async function convertOpenSearchDataToCsv() {
const dataset: any = [];
dataset.push(getOpenSearchData(arrayHits, report, params));
dataset.push(getOpenSearchData(arrayHits, report, params, dateFormat));
return await convertToCSV(dataset);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
* permissions and limitations under the License.
*/

import puppeteer, { SetCookie, Headers } from 'puppeteer-core';
import puppeteer, { Headers } from 'puppeteer-core';
import createDOMPurify from 'dompurify';
import { JSDOM } from 'jsdom';
import { Logger } from '../../../../../../src/core/server';
Expand All @@ -40,13 +40,13 @@ import { getFileName } from '../helpers';
import { CreateReportResultType } from '../types';
import { ReportParamsSchemaType, VisualReportSchemaType } from 'server/model';
import fs from 'fs';
import _ from 'lodash';

export const createVisualReport = async (
reportParams: ReportParamsSchemaType,
queryUrl: string,
logger: Logger,
cookie?: SetCookie,
additionalheaders?: Headers,
extraHeaders: Headers,
timezone?: string
): Promise<CreateReportResultType> => {
const {
Expand Down Expand Up @@ -95,13 +95,9 @@ export const createVisualReport = async (
const page = await browser.newPage();
page.setDefaultNavigationTimeout(0);
page.setDefaultTimeout(100000); // use 100s timeout instead of default 30s
if (cookie) {
logger.info('domain enables security, use session cookie to access');
await page.setCookie(cookie);
}
if (additionalheaders) {
logger.info('domain passed proxy auth headers, passing to backend');
await page.setExtraHTTPHeaders(additionalheaders);
// Set extra headers that are needed
if (!_.isEmpty(extraHeaders)) {
await page.setExtraHTTPHeaders(extraHeaders);
}
logger.info(`original queryUrl ${queryUrl}`);
await page.goto(queryUrl, { waitUntil: 'networkidle0' });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ internal object ReportInstanceActions {
Metrics.REPORT_FROM_DEFINITION_ID_SYSTEM_ERROR.counter.increment()
throw OpenSearchStatusException("Report Instance Creation failed", RestStatus.INTERNAL_SERVER_ERROR)
}
if (reportDefinitionDetails.reportDefinition.delivery != null) {
if (reportDefinitionDetails.reportDefinition.delivery != null && reportDefinitionDetails.reportDefinition.delivery.configIds.isNotEmpty()) {
val reportName = reportInstance.reportDefinitionDetails!!.reportDefinition.name
val reportLink = buildReportLink(reportDefinitionDetails.reportDefinition.source.origin, reportInstance.tenant, docId)
NotificationsActions.send(reportDefinitionDetails.reportDefinition.delivery, docId, reportLink, reportName)
Expand Down

0 comments on commit 71c59e2

Please sign in to comment.