mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
* [Reporting] Open test page in reporting browser self-check * comment correction * fix tests * fix test * fix tests more * remove test of open Kibana URL
This commit is contained in:
parent
b7113c02e4
commit
87357b3ef7
15 changed files with 121 additions and 86 deletions
|
@ -4,7 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { createMockServer } from '../../../test_helpers/create_mock_server';
|
||||
import { createMockServer } from '../test_helpers/create_mock_server';
|
||||
import { getAbsoluteUrlFactory } from './get_absolute_url';
|
||||
|
||||
test(`by default it builds url using information from server.info.protocol and the server.config`, () => {
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
import url from 'url';
|
||||
// @ts-ignore
|
||||
import { oncePerServer } from '../../../server/lib/once_per_server';
|
||||
import { ConfigObject, KbnServer } from '../../../types';
|
||||
import { oncePerServer } from '../server/lib/once_per_server';
|
||||
import { ConfigObject, KbnServer } from '../types';
|
||||
|
||||
function getAbsoluteUrlFn(server: KbnServer) {
|
||||
const config: ConfigObject = server.config();
|
|
@ -5,8 +5,8 @@
|
|||
*/
|
||||
// @ts-ignore
|
||||
import url from 'url';
|
||||
import { getAbsoluteUrlFactory } from '../../../common/get_absolute_url';
|
||||
import { ConditionalHeaders, KbnServer, ReportingJob } from '../../../types';
|
||||
import { getAbsoluteUrlFactory } from './get_absolute_url';
|
||||
|
||||
function getSavedObjectAbsoluteUrl(job: ReportingJob, relativeUrl: string, server: KbnServer) {
|
||||
const getAbsoluteUrl: any = getAbsoluteUrlFactory(server);
|
||||
|
|
|
@ -9,4 +9,3 @@ export { decryptJobHeaders } from './decrypt_job_headers';
|
|||
export { getConditionalHeaders } from './get_conditional_headers';
|
||||
export { getCustomLogo } from './get_custom_logo';
|
||||
export { omitBlacklistedHeaders } from './omit_blacklisted_headers';
|
||||
export { getAbsoluteUrlFactory } from './get_absolute_url';
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import url from 'url';
|
||||
import { getAbsoluteUrlFactory } from '../../../common/execute_job/get_absolute_url';
|
||||
import { getAbsoluteUrlFactory } from '../../../../common/get_absolute_url';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export function compatibilityShimFactory(server) {
|
||||
|
|
|
@ -12,9 +12,7 @@ import { registerRoutes } from './server/routes';
|
|||
import { createQueueFactory } from './server/lib/create_queue';
|
||||
import { config as appConfig } from './server/config/config';
|
||||
import { checkLicenseFactory } from './server/lib/check_license';
|
||||
import { validateConfig } from './server/lib/validate_config';
|
||||
import { validateMaxContentLength } from './server/lib/validate_max_content_length';
|
||||
import { validateBrowser } from './server/lib/validate_browser';
|
||||
import { runValidations } from './server/lib/validate';
|
||||
import { exportTypesRegistryFactory } from './server/lib/export_types_registry';
|
||||
import { CHROMIUM, createBrowserDriverFactory, getDefaultChromiumSandboxDisabled } from './server/browsers';
|
||||
import { logConfiguration } from './log_configuration';
|
||||
|
@ -149,15 +147,14 @@ export const reporting = (kibana) => {
|
|||
server.expose('exportTypesRegistry', exportTypesRegistry);
|
||||
|
||||
const config = server.config();
|
||||
const logWarning = message => server.log(['reporting', 'warning'], message);
|
||||
|
||||
validateConfig(config, logWarning);
|
||||
validateMaxContentLength(server, logWarning);
|
||||
validateBrowser(browserFactory, logWarning);
|
||||
logConfiguration(config, message => server.log(['reporting', 'debug'], message));
|
||||
const logger = {
|
||||
debug: message => server.log(['reporting', 'debug'], message),
|
||||
warning: message => server.log(['reporting', 'warning'], message),
|
||||
};
|
||||
logConfiguration(config, logger);
|
||||
runValidations(server, config, logger, browserFactory);
|
||||
|
||||
const { xpack_main: xpackMainPlugin } = server.plugins;
|
||||
|
||||
mirrorPluginStatus(xpackMainPlugin, this);
|
||||
const checkLicense = checkLicenseFactory(exportTypesRegistry);
|
||||
xpackMainPlugin.status.once('green', () => {
|
||||
|
|
|
@ -9,14 +9,14 @@ import { promisify } from 'util';
|
|||
|
||||
const getos = promisify(getosSync);
|
||||
|
||||
export async function logConfiguration(config, log) {
|
||||
export async function logConfiguration(config, logger) {
|
||||
const browserType = config.get('xpack.reporting.capture.browser.type');
|
||||
log(`Browser type: ${browserType}`);
|
||||
logger.debug(`Browser type: ${browserType}`);
|
||||
|
||||
if (browserType === 'chromium') {
|
||||
log(`Chromium sandbox disabled: ${config.get('xpack.reporting.capture.browser.chromium.disableSandbox')}`);
|
||||
logger.debug(`Chromium sandbox disabled: ${config.get('xpack.reporting.capture.browser.chromium.disableSandbox')}`);
|
||||
}
|
||||
|
||||
const os = await getos();
|
||||
log(`Running on os "${os.os}", distribution "${os.dist}", release "${os.release}"`);
|
||||
logger.debug(`Running on os "${os.os}", distribution "${os.dist}", release "${os.release}"`);
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ export class HeadlessChromiumDriverFactory {
|
|||
|
||||
type = 'chromium';
|
||||
|
||||
test({ viewport, browserTimezone }, log) {
|
||||
test({ viewport, browserTimezone }, logger) {
|
||||
const userDataDir = fs.mkdtempSync(path.join(os.tmpdir(), 'chromium-'));
|
||||
const chromiumArgs = args({
|
||||
userDataDir,
|
||||
|
@ -49,10 +49,10 @@ export class HeadlessChromiumDriverFactory {
|
|||
},
|
||||
})
|
||||
.catch(error => {
|
||||
log(
|
||||
logger.warning(
|
||||
`The Reporting plugin encountered issues launching Chromium in a self-test. You may have trouble generating reports: [${error}]`
|
||||
);
|
||||
log(`See Chromium's log output at "${getChromeLogLocation(this.binaryPath)}"`);
|
||||
logger.warning(`See Chromium's log output at "${getChromeLogLocation(this.binaryPath)}"`);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -8,25 +8,27 @@ import expect from 'expect.js';
|
|||
import sinon from 'sinon';
|
||||
import { validateConfig } from '../validate_config';
|
||||
|
||||
describe('Reporting: Validate config', function () {
|
||||
const log = sinon.spy();
|
||||
describe('Reporting: Validate config', () => {
|
||||
const logger = {
|
||||
warning: sinon.spy(),
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
log.resetHistory();
|
||||
logger.warning.resetHistory();
|
||||
});
|
||||
|
||||
[undefined, null].forEach(value => {
|
||||
it(`should log a warning and set xpack.reporting.encryptionKey if encryptionKey is ${value}`, function () {
|
||||
it(`should log a warning and set xpack.reporting.encryptionKey if encryptionKey is ${value}`, () => {
|
||||
const config = {
|
||||
get: sinon.stub().returns(value),
|
||||
set: sinon.stub()
|
||||
set: sinon.stub(),
|
||||
};
|
||||
|
||||
expect(() => validateConfig(config, log)).not.to.throwError();
|
||||
expect(() => validateConfig(config, logger)).not.to.throwError();
|
||||
|
||||
sinon.assert.calledWith(config.set, 'xpack.reporting.encryptionKey');
|
||||
sinon.assert.calledWithMatch(log, /Generating a random key/);
|
||||
sinon.assert.calledWithMatch(log, /please set xpack.reporting.encryptionKey/);
|
||||
sinon.assert.calledWithMatch(logger.warning, /Generating a random key/);
|
||||
sinon.assert.calledWithMatch(logger.warning, /please set xpack.reporting.encryptionKey/);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -11,10 +11,12 @@ const FIVE_HUNDRED_MEGABYTES = 524288000;
|
|||
const ONE_HUNDRED_MEGABYTES = 104857600;
|
||||
|
||||
describe('Reporting: Validate Max Content Length', () => {
|
||||
const log = sinon.spy();
|
||||
const logger = {
|
||||
warning: sinon.spy(),
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
log.resetHistory();
|
||||
logger.warning.resetHistory();
|
||||
});
|
||||
|
||||
it('should log warning messages when reporting has a higher max-size than elasticsearch', async () => {
|
||||
|
@ -37,12 +39,12 @@ describe('Reporting: Validate Max Content Length', () => {
|
|||
},
|
||||
};
|
||||
|
||||
await validateMaxContentLength(server, log);
|
||||
await validateMaxContentLength(server, logger);
|
||||
|
||||
sinon.assert.calledWithMatch(log, `xpack.reporting.csv.maxSizeBytes (524288000) is higher`);
|
||||
sinon.assert.calledWithMatch(log, `than ElasticSearch's http.max_content_length (104857600)`);
|
||||
sinon.assert.calledWithMatch(log, 'Please set http.max_content_length in ElasticSearch to match');
|
||||
sinon.assert.calledWithMatch(log, 'or lower your xpack.reporting.csv.maxSizeBytes in Kibana');
|
||||
sinon.assert.calledWithMatch(logger.warning, `xpack.reporting.csv.maxSizeBytes (524288000) is higher`);
|
||||
sinon.assert.calledWithMatch(logger.warning, `than ElasticSearch's http.max_content_length (104857600)`);
|
||||
sinon.assert.calledWithMatch(logger.warning, 'Please set http.max_content_length in ElasticSearch to match');
|
||||
sinon.assert.calledWithMatch(logger.warning, 'or lower your xpack.reporting.csv.maxSizeBytes in Kibana');
|
||||
});
|
||||
|
||||
it('should do nothing when reporting has the same max-size as elasticsearch', async () => {
|
||||
|
@ -65,7 +67,7 @@ describe('Reporting: Validate Max Content Length', () => {
|
|||
},
|
||||
};
|
||||
|
||||
expect(async () => validateMaxContentLength(server, log)).not.to.throwError();
|
||||
sinon.assert.notCalled(log);
|
||||
expect(async () => validateMaxContentLength(server, logger.warning)).not.to.throwError();
|
||||
sinon.assert.notCalled(logger.warning);
|
||||
});
|
||||
});
|
31
x-pack/plugins/reporting/server/lib/validate/index.ts
Normal file
31
x-pack/plugins/reporting/server/lib/validate/index.ts
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { ConfigObject, KbnServer, Logger } from '../../../types';
|
||||
import { validateBrowser } from './validate_browser';
|
||||
// @ts-ignore
|
||||
import { validateConfig } from './validate_config';
|
||||
import { validateMaxContentLength } from './validate_max_content_length';
|
||||
|
||||
export async function runValidations(
|
||||
server: KbnServer,
|
||||
config: ConfigObject,
|
||||
logger: Logger,
|
||||
browserFactory: any
|
||||
) {
|
||||
try {
|
||||
await Promise.all([
|
||||
validateBrowser(server, browserFactory, logger),
|
||||
validateConfig(config, logger),
|
||||
validateMaxContentLength(server, logger),
|
||||
]);
|
||||
logger.debug(`Reporting plugin self-check ok!`);
|
||||
} catch (err) {
|
||||
logger.warning(
|
||||
`Reporting plugin self-check failed. Please check the Kibana Reporting settings. ${err}`
|
||||
);
|
||||
}
|
||||
}
|
|
@ -4,23 +4,27 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import * as puppeteer from 'puppeteer-core';
|
||||
import { CHROMIUM } from '../browsers/browser_types';
|
||||
import { KbnServer, Logger } from '../../../types';
|
||||
import { CHROMIUM } from '../../browsers/browser_types';
|
||||
|
||||
export const validateBrowser = async (browserFactory: any, log: (message: string) => any) => {
|
||||
/*
|
||||
* Validate the Reporting headless browser can launch, and that it can connect
|
||||
* to the locally running Kibana instance.
|
||||
*/
|
||||
export const validateBrowser = async (server: KbnServer, browserFactory: any, logger: Logger) => {
|
||||
if (browserFactory.type === CHROMIUM) {
|
||||
return browserFactory
|
||||
.test(
|
||||
{
|
||||
viewport: {
|
||||
width: 800,
|
||||
height: 600,
|
||||
},
|
||||
viewport: { width: 800, height: 600 },
|
||||
},
|
||||
log
|
||||
logger
|
||||
)
|
||||
.then((browser: puppeteer.Browser | null) => {
|
||||
if (browser && browser.close) {
|
||||
browser.close();
|
||||
} else {
|
||||
throw new Error('Could not close browser client handle!');
|
||||
}
|
||||
});
|
||||
}
|
|
@ -6,11 +6,13 @@
|
|||
|
||||
import crypto from 'crypto';
|
||||
|
||||
export function validateConfig(config, log) {
|
||||
export function validateConfig(config, logger) {
|
||||
const encryptionKey = config.get('xpack.reporting.encryptionKey');
|
||||
if (encryptionKey === null || encryptionKey === undefined) {
|
||||
log('Generating a random key for xpack.reporting.encryptionKey. To prevent pending reports from failing on ' +
|
||||
'restart, please set xpack.reporting.encryptionKey in kibana.yml');
|
||||
if (encryptionKey == null) {
|
||||
logger.warning(
|
||||
`Generating a random key for xpack.reporting.encryptionKey. To prevent pending reports from failing on restart, please set ` +
|
||||
`xpack.reporting.encryptionKey in kibana.yml`
|
||||
);
|
||||
config.set('xpack.reporting.encryptionKey', crypto.randomBytes(16).toString('hex'));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import numeral from '@elastic/numeral';
|
||||
import { defaults, get } from 'lodash';
|
||||
import { Logger } from '../../../types';
|
||||
|
||||
const KIBANA_MAX_SIZE_BYTES_PATH = 'xpack.reporting.csv.maxSizeBytes';
|
||||
const ES_MAX_SIZE_BYTES_PATH = 'http.max_content_length';
|
||||
|
||||
export async function validateMaxContentLength(server: any, logger: Logger) {
|
||||
const config = server.config();
|
||||
const { callWithInternalUser } = server.plugins.elasticsearch.getCluster('data');
|
||||
|
||||
const elasticClusterSettingsResponse = await callWithInternalUser('cluster.getSettings', {
|
||||
includeDefaults: true,
|
||||
});
|
||||
const { persistent, transient, defaults: defaultSettings } = elasticClusterSettingsResponse;
|
||||
const elasticClusterSettings = defaults({}, persistent, transient, defaultSettings);
|
||||
|
||||
const elasticSearchMaxContent = get(elasticClusterSettings, 'http.max_content_length', '100mb');
|
||||
const elasticSearchMaxContentBytes = numeral().unformat(elasticSearchMaxContent.toUpperCase());
|
||||
const kibanaMaxContentBytes = config.get(KIBANA_MAX_SIZE_BYTES_PATH);
|
||||
|
||||
if (kibanaMaxContentBytes > elasticSearchMaxContentBytes) {
|
||||
logger.warning(
|
||||
`${KIBANA_MAX_SIZE_BYTES_PATH} (${kibanaMaxContentBytes}) is higher than ElasticSearch's ${ES_MAX_SIZE_BYTES_PATH} (${elasticSearchMaxContentBytes}). ` +
|
||||
`Please set ${ES_MAX_SIZE_BYTES_PATH} in ElasticSearch to match, or lower your ${KIBANA_MAX_SIZE_BYTES_PATH} in Kibana to avoid this warning.`
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import numeral from '@elastic/numeral';
|
||||
import { defaults, get } from 'lodash';
|
||||
const KIBANA_MAX_SIZE_BYTES_PATH = 'xpack.reporting.csv.maxSizeBytes';
|
||||
const ES_MAX_SIZE_BYTES_PATH = 'http.max_content_length';
|
||||
|
||||
export async function validateMaxContentLength(server: any, log: (message: string) => any) {
|
||||
const config = server.config();
|
||||
const { callWithInternalUser } = server.plugins.elasticsearch.getCluster('data');
|
||||
|
||||
try {
|
||||
const elasticClusterSettingsResponse = await callWithInternalUser('cluster.getSettings', {
|
||||
includeDefaults: true,
|
||||
});
|
||||
const { persistent, transient, defaults: defaultSettings } = elasticClusterSettingsResponse;
|
||||
const elasticClusterSettings = defaults({}, persistent, transient, defaultSettings);
|
||||
|
||||
const elasticSearchMaxContent = get(elasticClusterSettings, 'http.max_content_length', '100mb');
|
||||
const elasticSearchMaxContentBytes = numeral().unformat(elasticSearchMaxContent.toUpperCase());
|
||||
const kibanaMaxContentBytes = config.get(KIBANA_MAX_SIZE_BYTES_PATH);
|
||||
|
||||
if (kibanaMaxContentBytes > elasticSearchMaxContentBytes) {
|
||||
log(
|
||||
`${KIBANA_MAX_SIZE_BYTES_PATH} (${kibanaMaxContentBytes}) is higher than ElasticSearch's ${ES_MAX_SIZE_BYTES_PATH} (${elasticSearchMaxContentBytes}). ` +
|
||||
`Please set ${ES_MAX_SIZE_BYTES_PATH} in ElasticSearch to match, or lower your ${KIBANA_MAX_SIZE_BYTES_PATH} in Kibana to avoid this warning.`
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
log(`Could not retrieve cluster settings, because of ${e.message}`);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue