Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backport bugfix to 1.1 #236

Merged
merged 9 commits into from
Dec 1, 2021
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ on: [pull_request, push]
env:
PLUGIN_NAME: reportsDashboards
ARTIFACT_NAME: reports-dashboards
OPENSEARCH_VERSION: '1.x'
OPENSEARCH_PLUGIN_VERSION: 1.1.0.0
OPENSEARCH_VERSION: '1.1'
OPENSEARCH_PLUGIN_VERSION: 1.1.1.0

jobs:
build:
Expand Down
38 changes: 1 addition & 37 deletions .github/workflows/reports-scheduler-test-and-build-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@ name: Test and Build Reports Scheduler
on: [push, pull_request]

env:
OPENSEARCH_VERSION: '1.1.0-SNAPSHOT'
OPENSEARCH_BRANCH: '1.1'
COMMON_UTILS_BRANCH: 'main'
JOB_SCHEDULER_BRANCH: 'main'
OPENSEARCH_VERSION: '1.1.0'

jobs:
build:
Expand All @@ -18,39 +15,6 @@ jobs:
with:
java-version: 1.14

# dependencies: OpenSearch
- name: Checkout OpenSearch
uses: actions/checkout@v2
with:
repository: 'opensearch-project/OpenSearch'
path: OpenSearch
ref: ${{ env.OPENSEARCH_BRANCH }}
- name: Build OpenSearch
working-directory: ./OpenSearch
run: ./gradlew publishToMavenLocal

# dependencies: common-utils
- name: Checkout common-utils
uses: actions/checkout@v2
with:
repository: 'opensearch-project/common-utils'
ref: ${{ env.COMMON_UTILS_BRANCH }}
path: common-utils
- name: Build common-utils
working-directory: ./common-utils
run: ./gradlew publishToMavenLocal -Dopensearch.version=${{ env.OPENSEARCH_VERSION }}

# dependencies: job-scheduler
- name: Checkout job-scheduler
uses: actions/checkout@v2
with:
repository: 'opensearch-project/job-scheduler'
ref: ${{ env.JOB_SCHEDULER_BRANCH }}
path: job-scheduler
- name: Build job-scheduler
working-directory: ./job-scheduler
run: ./gradlew publishToMavenLocal -Dopensearch.version=${{ env.OPENSEARCH_VERSION }}

# reports-scheduler
- name: Checkout Reports Scheduler
uses: actions/checkout@v2
Expand Down
18 changes: 0 additions & 18 deletions dashboards-reports/.babelrc

This file was deleted.

23 changes: 23 additions & 0 deletions dashboards-reports/babel.config.js
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.
*/

module.exports = {
presets: [
require('@babel/preset-env', {
targets: { node: '10' },
}),
require('@babel/preset-react'),
require('@babel/preset-typescript'),
],
plugins: [
require('@babel/plugin-proposal-class-properties'),
require('@babel/plugin-proposal-object-rest-spread'),
['@babel/plugin-transform-modules-commonjs', { allowTopLevelThis: true }],
[require('@babel/plugin-transform-runtime'), { regenerator: true }],
],
};
2 changes: 1 addition & 1 deletion dashboards-reports/opensearch_dashboards.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"id": "reportsDashboards",
"version": "1.1.0.0",
"version": "1.1.1.0",
"opensearchDashboardsVersion": "1.1.0",
"requiredPlugins": ["navigation", "data", "opensearchDashboardsUtils"],
"optionalPlugins": ["share"],
Expand Down
5 changes: 2 additions & 3 deletions dashboards-reports/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "reports-dashboards",
"version": "1.1.0.0",
"version": "1.1.1.0",
"description": "OpenSearch Dashboards Reports Plugin",
"license": "Apache-2.0",
"main": "index.ts",
Expand Down Expand Up @@ -66,8 +66,7 @@
"identity-obj-proxy": "^3.0.0",
"jest-dom": "^4.0.0",
"react-test-renderer": "^16.12.0",
"ts-jest": "^26.1.0",
"tsc": "^1.20150623.0"
"ts-jest": "^26.1.0"
},
"resolutions": {
"trim": "^1.0.0",
Expand Down
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 @@ -104,9 +105,9 @@ const generateInContextReport = async (
};

fetch(
`../api/reporting/generateReport?timezone=${
Intl.DateTimeFormat().resolvedOptions().timeZone
}`,
`../api/reporting/generateReport?${new URLSearchParams(
uiSettingsService.getSearchParams()
)}`,
{
headers: {
'Content-Type': 'application/json',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,13 @@ export const getTimeFieldsFromUrl = () => {
const url = unhashUrl(window.location.href);

let [, fromDateString, toDateString] = url.match(timeRangeMatcher);
fromDateString = fromDateString.replace(/[']+/g, '');
fromDateString = decodeURIComponent(fromDateString.replace(/[']+/g, ''));
// convert time range to from date format in case time range is relative
const fromDateFormat = dateMath.parse(fromDateString);
toDateString = toDateString.replace(/[']+/g, '');
const toDateFormat = dateMath.parse(toDateString);
toDateString = decodeURIComponent(toDateString.replace(/[']+/g, ''));
const toDateFormat = dateMath.parse(toDateString, { roundUp: true });

const timeDuration = moment.duration(
dateMath.parse(toDateString).diff(dateMath.parse(fromDateString))
);
const timeDuration = moment.duration(toDateFormat.diff(fromDateFormat));

return {
time_from: fromDateFormat,
Expand Down Expand Up @@ -141,22 +139,23 @@ export const replaceQueryURL = (pageUrl) => {
// we unhash the url in case OpenSearch Dashboards advanced UI setting 'state:storeInSessionStorage' is turned on
const unhashedUrl = new URL(unhashUrl(pageUrl));
let queryUrl = unhashedUrl.pathname + unhashedUrl.hash;
let [, fromDateString, toDateString] = queryUrl.match(timeRangeMatcher);
fromDateString = fromDateString.replace(/[']+/g, '');
let [, fromDateStringMatch, toDateStringMatch] =
queryUrl.match(timeRangeMatcher);
const fromDateString = decodeURIComponent(fromDateStringMatch.replace(/[']+/g, ''));

// convert time range to from date format in case time range is relative
const fromDateFormat = dateMath.parse(fromDateString);
toDateString = toDateString.replace(/[']+/g, '');
const toDateFormat = dateMath.parse(toDateString);
const toDateString = decodeURIComponent(toDateStringMatch.replace(/[']+/g, ''));
const toDateFormat = dateMath.parse(toDateString, { roundUp: true });

// replace to and from dates with absolute date
queryUrl = queryUrl.replace(
fromDateString,
fromDateStringMatch,
"'" + fromDateFormat.toISOString() + "'"
);
queryUrl = queryUrl.replace(
toDateString + '))',
"'" + toDateFormat.toISOString() + "'))"
toDateStringMatch,
"'" + toDateFormat.toISOString() + "'"
);
return queryUrl;
};
5 changes: 3 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 fileFormatsUpper = {
csv: 'CSV',
Expand Down Expand Up @@ -163,7 +164,7 @@ export const generateReportFromDefinitionId = async (
headers: {
'Content-Type': 'application/json',
},
query: { timezone: Intl.DateTimeFormat().resolvedOptions().timeZone },
query: uiSettingsService.getSearchParams(),
})
.then(async (response: any) => {
// for emailing a report, this API response doesn't have response body
Expand Down Expand Up @@ -196,7 +197,7 @@ export const generateReportById = async (
) => {
await httpClient
.get(`../api/reporting/generateReport/${reportId}`, {
query: { timezone: Intl.DateTimeFormat().resolvedOptions().timeZone },
query: uiSettingsService.getSearchParams(),
})
.then(async (response) => {
//TODO: duplicate code, extract to be a function that can reuse. e.g. handleResponse(response)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,11 +171,11 @@ export function ReportDetails(props) {
timeRangeMatcher
);

fromDateString = fromDateString.replace(/[']+/g, '');
toDateString = toDateString.replace(/[']+/g, '');
fromDateString = decodeURIComponent(fromDateString.replace(/[']+/g, ''));
toDateString = decodeURIComponent(toDateString.replace(/[']+/g, ''));

let fromDateParsed = dateMath.parse(fromDateString);
let toDateParsed = dateMath.parse(toDateString);
let toDateParsed = dateMath.parse(toDateString, { roundUp: true });

const fromTimePeriod = fromDateParsed?.toDate();
const toTimePeriod = toDateParsed?.toDate();
Expand Down
37 changes: 37 additions & 0 deletions dashboards-reports/public/components/utils/settings_service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* 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) || '';
},
getSearchParams: function () {
const rawTimeZone = this.get('dateFormat:tz');
const timezone =
!rawTimeZone || rawTimeZone === 'Browser'
? Intl.DateTimeFormat().resolvedOptions().timeZone
: rawTimeZone;
const dateFormat = this.get('dateFormat');
const csvSeparator = this.get('csv:separator');
return {
timezone,
dateFormat,
csvSeparator,
};
},
};
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
49 changes: 16 additions & 33 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,11 @@ 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;
// @ts-ignore
const csvSeparator = request.query.csvSeparator || ',';
const {
basePath,
serverInfo: { protocol, port, hostname },
Expand All @@ -75,9 +82,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,7 +99,10 @@ export const createReport = async (
createReportResult = await createSavedSearchReport(
report,
opensearchClient,
isScheduledTask
dateFormat,
csvSeparator,
isScheduledTask,
logger
);
} else {
// report source can only be one of [saved search, visualization, dashboard, notebook]
Expand All @@ -103,40 +111,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
Loading