Allow custom NP plugin paths in production (#53562)
* allow NP plugins --plugin-path in production, logs a warning * remove env.staticFilesDir (unused) * only show warning in development * update rendering tests snapshots * fix typo
This commit is contained in:
parent
c19151d474
commit
24542c3ad7
|
@ -140,23 +140,12 @@ function applyConfigOverrides(rawConfig, opts, extraCliOptions) {
|
||||||
}
|
}
|
||||||
|
|
||||||
set('plugins.scanDirs', _.compact([].concat(get('plugins.scanDirs'), opts.pluginDir)));
|
set('plugins.scanDirs', _.compact([].concat(get('plugins.scanDirs'), opts.pluginDir)));
|
||||||
|
|
||||||
set(
|
set(
|
||||||
'plugins.paths',
|
'plugins.paths',
|
||||||
_.compact(
|
_.compact(
|
||||||
[].concat(
|
[].concat(
|
||||||
get('plugins.paths'),
|
get('plugins.paths'),
|
||||||
opts.pluginPath,
|
opts.pluginPath,
|
||||||
opts.runExamples
|
|
||||||
? [
|
|
||||||
// Ideally this would automatically include all plugins in the examples dir
|
|
||||||
fromRoot('examples/demo_search'),
|
|
||||||
fromRoot('examples/search_explorer'),
|
|
||||||
fromRoot('examples/embeddable_examples'),
|
|
||||||
fromRoot('examples/embeddable_explorer'),
|
|
||||||
]
|
|
||||||
: [],
|
|
||||||
|
|
||||||
XPACK_INSTALLED && !opts.oss ? [XPACK_DIR] : []
|
XPACK_INSTALLED && !opts.oss ? [XPACK_DIR] : []
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -253,6 +242,7 @@ export default function(program) {
|
||||||
silent: !!opts.silent,
|
silent: !!opts.silent,
|
||||||
watch: !!opts.watch,
|
watch: !!opts.watch,
|
||||||
repl: !!opts.repl,
|
repl: !!opts.repl,
|
||||||
|
runExamples: !!opts.runExamples,
|
||||||
// We want to run without base path when the `--run-examples` flag is given so that we can use local
|
// We want to run without base path when the `--run-examples` flag is given so that we can use local
|
||||||
// links in other documentation sources, like "View this tutorial [here](http://localhost:5601/app/tutorial/xyz)".
|
// links in other documentation sources, like "View this tutorial [here](http://localhost:5601/app/tutorial/xyz)".
|
||||||
// We can tell users they only have to run with `yarn start --run-examples` to get those
|
// We can tell users they only have to run with `yarn start --run-examples` to get those
|
||||||
|
|
|
@ -38,6 +38,7 @@ export function getEnvOptions(options: DeepPartial<EnvOptions> = {}): EnvOptions
|
||||||
basePath: false,
|
basePath: false,
|
||||||
optimize: false,
|
optimize: false,
|
||||||
oss: false,
|
oss: false,
|
||||||
|
runExamples: false,
|
||||||
...(options.cliArgs || {}),
|
...(options.cliArgs || {}),
|
||||||
},
|
},
|
||||||
isDevClusterMaster:
|
isDevClusterMaster:
|
||||||
|
|
|
@ -12,6 +12,7 @@ Env {
|
||||||
"oss": false,
|
"oss": false,
|
||||||
"quiet": false,
|
"quiet": false,
|
||||||
"repl": false,
|
"repl": false,
|
||||||
|
"runExamples": false,
|
||||||
"silent": false,
|
"silent": false,
|
||||||
"watch": false,
|
"watch": false,
|
||||||
},
|
},
|
||||||
|
@ -40,7 +41,6 @@ Env {
|
||||||
"/test/kibanaRoot/plugins",
|
"/test/kibanaRoot/plugins",
|
||||||
"/test/kibanaRoot/../kibana-extra",
|
"/test/kibanaRoot/../kibana-extra",
|
||||||
],
|
],
|
||||||
"staticFilesDir": "/test/kibanaRoot/ui",
|
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -56,6 +56,7 @@ Env {
|
||||||
"oss": false,
|
"oss": false,
|
||||||
"quiet": false,
|
"quiet": false,
|
||||||
"repl": false,
|
"repl": false,
|
||||||
|
"runExamples": false,
|
||||||
"silent": false,
|
"silent": false,
|
||||||
"watch": false,
|
"watch": false,
|
||||||
},
|
},
|
||||||
|
@ -84,7 +85,6 @@ Env {
|
||||||
"/test/kibanaRoot/plugins",
|
"/test/kibanaRoot/plugins",
|
||||||
"/test/kibanaRoot/../kibana-extra",
|
"/test/kibanaRoot/../kibana-extra",
|
||||||
],
|
],
|
||||||
"staticFilesDir": "/test/kibanaRoot/ui",
|
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -99,6 +99,7 @@ Env {
|
||||||
"oss": false,
|
"oss": false,
|
||||||
"quiet": false,
|
"quiet": false,
|
||||||
"repl": false,
|
"repl": false,
|
||||||
|
"runExamples": false,
|
||||||
"silent": false,
|
"silent": false,
|
||||||
"watch": false,
|
"watch": false,
|
||||||
},
|
},
|
||||||
|
@ -127,7 +128,6 @@ Env {
|
||||||
"/test/kibanaRoot/plugins",
|
"/test/kibanaRoot/plugins",
|
||||||
"/test/kibanaRoot/../kibana-extra",
|
"/test/kibanaRoot/../kibana-extra",
|
||||||
],
|
],
|
||||||
"staticFilesDir": "/test/kibanaRoot/ui",
|
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -142,6 +142,7 @@ Env {
|
||||||
"oss": false,
|
"oss": false,
|
||||||
"quiet": false,
|
"quiet": false,
|
||||||
"repl": false,
|
"repl": false,
|
||||||
|
"runExamples": false,
|
||||||
"silent": false,
|
"silent": false,
|
||||||
"watch": false,
|
"watch": false,
|
||||||
},
|
},
|
||||||
|
@ -170,7 +171,6 @@ Env {
|
||||||
"/test/kibanaRoot/plugins",
|
"/test/kibanaRoot/plugins",
|
||||||
"/test/kibanaRoot/../kibana-extra",
|
"/test/kibanaRoot/../kibana-extra",
|
||||||
],
|
],
|
||||||
"staticFilesDir": "/test/kibanaRoot/ui",
|
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -185,6 +185,7 @@ Env {
|
||||||
"oss": false,
|
"oss": false,
|
||||||
"quiet": false,
|
"quiet": false,
|
||||||
"repl": false,
|
"repl": false,
|
||||||
|
"runExamples": false,
|
||||||
"silent": false,
|
"silent": false,
|
||||||
"watch": false,
|
"watch": false,
|
||||||
},
|
},
|
||||||
|
@ -213,7 +214,6 @@ Env {
|
||||||
"/test/kibanaRoot/plugins",
|
"/test/kibanaRoot/plugins",
|
||||||
"/test/kibanaRoot/../kibana-extra",
|
"/test/kibanaRoot/../kibana-extra",
|
||||||
],
|
],
|
||||||
"staticFilesDir": "/test/kibanaRoot/ui",
|
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -228,6 +228,7 @@ Env {
|
||||||
"oss": false,
|
"oss": false,
|
||||||
"quiet": false,
|
"quiet": false,
|
||||||
"repl": false,
|
"repl": false,
|
||||||
|
"runExamples": false,
|
||||||
"silent": false,
|
"silent": false,
|
||||||
"watch": false,
|
"watch": false,
|
||||||
},
|
},
|
||||||
|
@ -256,6 +257,5 @@ Env {
|
||||||
"/some/home/dir/plugins",
|
"/some/home/dir/plugins",
|
||||||
"/some/home/dir/../kibana-extra",
|
"/some/home/dir/../kibana-extra",
|
||||||
],
|
],
|
||||||
"staticFilesDir": "/some/home/dir/ui",
|
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -152,3 +152,25 @@ test('pluginSearchPaths does not contains x-pack plugins path if --oss flag is t
|
||||||
|
|
||||||
expect(env.pluginSearchPaths).not.toContain('/some/home/dir/x-pack/plugins');
|
expect(env.pluginSearchPaths).not.toContain('/some/home/dir/x-pack/plugins');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('pluginSearchPaths contains examples plugins path if --run-examples flag is true', () => {
|
||||||
|
const env = new Env(
|
||||||
|
'/some/home/dir',
|
||||||
|
getEnvOptions({
|
||||||
|
cliArgs: { runExamples: true },
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(env.pluginSearchPaths).toContain('/some/home/dir/examples');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('pluginSearchPaths does not contains examples plugins path if --run-examples flag is false', () => {
|
||||||
|
const env = new Env(
|
||||||
|
'/some/home/dir',
|
||||||
|
getEnvOptions({
|
||||||
|
cliArgs: { runExamples: false },
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(env.pluginSearchPaths).not.toContain('/some/home/dir/examples');
|
||||||
|
});
|
||||||
|
|
|
@ -43,6 +43,7 @@ export interface CliArgs {
|
||||||
optimize: boolean;
|
optimize: boolean;
|
||||||
open: boolean;
|
open: boolean;
|
||||||
oss: boolean;
|
oss: boolean;
|
||||||
|
runExamples: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Env {
|
export class Env {
|
||||||
|
@ -61,8 +62,6 @@ export class Env {
|
||||||
/** @internal */
|
/** @internal */
|
||||||
public readonly logDir: string;
|
public readonly logDir: string;
|
||||||
/** @internal */
|
/** @internal */
|
||||||
public readonly staticFilesDir: string;
|
|
||||||
/** @internal */
|
|
||||||
public readonly pluginSearchPaths: readonly string[];
|
public readonly pluginSearchPaths: readonly string[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -100,14 +99,14 @@ export class Env {
|
||||||
this.configDir = resolve(this.homeDir, 'config');
|
this.configDir = resolve(this.homeDir, 'config');
|
||||||
this.binDir = resolve(this.homeDir, 'bin');
|
this.binDir = resolve(this.homeDir, 'bin');
|
||||||
this.logDir = resolve(this.homeDir, 'log');
|
this.logDir = resolve(this.homeDir, 'log');
|
||||||
this.staticFilesDir = resolve(this.homeDir, 'ui');
|
|
||||||
|
|
||||||
this.pluginSearchPaths = [
|
this.pluginSearchPaths = [
|
||||||
resolve(this.homeDir, 'src', 'plugins'),
|
resolve(this.homeDir, 'src', 'plugins'),
|
||||||
options.cliArgs.oss ? '' : resolve(this.homeDir, 'x-pack', 'plugins'),
|
...(options.cliArgs.oss ? [] : [resolve(this.homeDir, 'x-pack', 'plugins')]),
|
||||||
resolve(this.homeDir, 'plugins'),
|
resolve(this.homeDir, 'plugins'),
|
||||||
|
...(options.cliArgs.runExamples ? [resolve(this.homeDir, 'examples')] : []),
|
||||||
resolve(this.homeDir, '..', 'kibana-extra'),
|
resolve(this.homeDir, '..', 'kibana-extra'),
|
||||||
].filter(Boolean);
|
];
|
||||||
|
|
||||||
this.cliArgs = Object.freeze(options.cliArgs);
|
this.cliArgs = Object.freeze(options.cliArgs);
|
||||||
this.configs = Object.freeze(options.configs);
|
this.configs = Object.freeze(options.configs);
|
||||||
|
|
|
@ -19,8 +19,6 @@
|
||||||
|
|
||||||
import uuid from 'uuid';
|
import uuid from 'uuid';
|
||||||
import { config, HttpConfig } from '.';
|
import { config, HttpConfig } from '.';
|
||||||
import { Env } from '../config';
|
|
||||||
import { getEnvOptions } from '../config/__mocks__/env';
|
|
||||||
|
|
||||||
const validHostnames = ['www.example.com', '8.8.8.8', '::1', 'localhost'];
|
const validHostnames = ['www.example.com', '8.8.8.8', '::1', 'localhost'];
|
||||||
const invalidHostname = 'asdf$%^';
|
const invalidHostname = 'asdf$%^';
|
||||||
|
@ -265,8 +263,7 @@ describe('with TLS', () => {
|
||||||
clientAuthentication: 'none',
|
clientAuthentication: 'none',
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
{} as any,
|
{} as any
|
||||||
Env.createDefault(getEnvOptions())
|
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(httpConfig.ssl.requestCert).toBe(false);
|
expect(httpConfig.ssl.requestCert).toBe(false);
|
||||||
|
@ -283,8 +280,7 @@ describe('with TLS', () => {
|
||||||
clientAuthentication: 'optional',
|
clientAuthentication: 'optional',
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
{} as any,
|
{} as any
|
||||||
Env.createDefault(getEnvOptions())
|
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(httpConfig.ssl.requestCert).toBe(true);
|
expect(httpConfig.ssl.requestCert).toBe(true);
|
||||||
|
@ -301,8 +297,7 @@ describe('with TLS', () => {
|
||||||
clientAuthentication: 'required',
|
clientAuthentication: 'required',
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
{} as any,
|
{} as any
|
||||||
Env.createDefault(getEnvOptions())
|
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(httpConfig.ssl.requestCert).toBe(true);
|
expect(httpConfig.ssl.requestCert).toBe(true);
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { ByteSizeValue, schema, TypeOf } from '@kbn/config-schema';
|
import { ByteSizeValue, schema, TypeOf } from '@kbn/config-schema';
|
||||||
import { Env } from '../config';
|
|
||||||
import { CspConfigType, CspConfig, ICspConfig } from '../csp';
|
import { CspConfigType, CspConfig, ICspConfig } from '../csp';
|
||||||
import { SslConfig, sslSchema } from './ssl_config';
|
import { SslConfig, sslSchema } from './ssl_config';
|
||||||
|
|
||||||
|
@ -135,7 +134,6 @@ export class HttpConfig {
|
||||||
public maxPayload: ByteSizeValue;
|
public maxPayload: ByteSizeValue;
|
||||||
public basePath?: string;
|
public basePath?: string;
|
||||||
public rewriteBasePath: boolean;
|
public rewriteBasePath: boolean;
|
||||||
public publicDir: string;
|
|
||||||
public defaultRoute?: string;
|
public defaultRoute?: string;
|
||||||
public ssl: SslConfig;
|
public ssl: SslConfig;
|
||||||
public compression: { enabled: boolean; referrerWhitelist?: string[] };
|
public compression: { enabled: boolean; referrerWhitelist?: string[] };
|
||||||
|
@ -144,7 +142,7 @@ export class HttpConfig {
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
constructor(rawHttpConfig: HttpConfigType, rawCspConfig: CspConfigType, env: Env) {
|
constructor(rawHttpConfig: HttpConfigType, rawCspConfig: CspConfigType) {
|
||||||
this.autoListen = rawHttpConfig.autoListen;
|
this.autoListen = rawHttpConfig.autoListen;
|
||||||
this.host = rawHttpConfig.host;
|
this.host = rawHttpConfig.host;
|
||||||
this.port = rawHttpConfig.port;
|
this.port = rawHttpConfig.port;
|
||||||
|
@ -154,7 +152,6 @@ export class HttpConfig {
|
||||||
this.keepaliveTimeout = rawHttpConfig.keepaliveTimeout;
|
this.keepaliveTimeout = rawHttpConfig.keepaliveTimeout;
|
||||||
this.socketTimeout = rawHttpConfig.socketTimeout;
|
this.socketTimeout = rawHttpConfig.socketTimeout;
|
||||||
this.rewriteBasePath = rawHttpConfig.rewriteBasePath;
|
this.rewriteBasePath = rawHttpConfig.rewriteBasePath;
|
||||||
this.publicDir = env.staticFilesDir;
|
|
||||||
this.ssl = new SslConfig(rawHttpConfig.ssl || {});
|
this.ssl = new SslConfig(rawHttpConfig.ssl || {});
|
||||||
this.defaultRoute = rawHttpConfig.defaultRoute;
|
this.defaultRoute = rawHttpConfig.defaultRoute;
|
||||||
this.compression = rawHttpConfig.compression;
|
this.compression = rawHttpConfig.compression;
|
||||||
|
|
|
@ -61,14 +61,14 @@ export class HttpService implements CoreService<InternalHttpServiceSetup, HttpSe
|
||||||
private requestHandlerContext?: RequestHandlerContextContainer;
|
private requestHandlerContext?: RequestHandlerContextContainer;
|
||||||
|
|
||||||
constructor(private readonly coreContext: CoreContext) {
|
constructor(private readonly coreContext: CoreContext) {
|
||||||
const { logger, configService, env } = coreContext;
|
const { logger, configService } = coreContext;
|
||||||
|
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.log = logger.get('http');
|
this.log = logger.get('http');
|
||||||
this.config$ = combineLatest(
|
this.config$ = combineLatest(
|
||||||
configService.atPath<HttpConfigType>(httpConfig.path),
|
configService.atPath<HttpConfigType>(httpConfig.path),
|
||||||
configService.atPath<CspConfigType>(cspConfig.path)
|
configService.atPath<CspConfigType>(cspConfig.path)
|
||||||
).pipe(map(([http, csp]) => new HttpConfig(http, csp, env)));
|
).pipe(map(([http, csp]) => new HttpConfig(http, csp)));
|
||||||
this.httpServer = new HttpServer(logger, 'Kibana');
|
this.httpServer = new HttpServer(logger, 'Kibana');
|
||||||
this.httpsRedirectServer = new HttpsRedirectServer(logger.get('http', 'redirect', 'server'));
|
this.httpsRedirectServer = new HttpsRedirectServer(logger.get('http', 'redirect', 'server'));
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,8 +31,6 @@ import { HttpConfig, config } from './http_config';
|
||||||
import { Router } from './router';
|
import { Router } from './router';
|
||||||
import { loggingServiceMock } from '../logging/logging_service.mock';
|
import { loggingServiceMock } from '../logging/logging_service.mock';
|
||||||
import { ByteSizeValue } from '@kbn/config-schema';
|
import { ByteSizeValue } from '@kbn/config-schema';
|
||||||
import { Env } from '../config';
|
|
||||||
import { getEnvOptions } from '../config/__mocks__/env';
|
|
||||||
|
|
||||||
const emptyOutput = {
|
const emptyOutput = {
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
|
@ -122,8 +120,7 @@ describe('getServerOptions', () => {
|
||||||
certificate: 'some-certificate-path',
|
certificate: 'some-certificate-path',
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
{} as any,
|
{} as any
|
||||||
Env.createDefault(getEnvOptions())
|
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(getServerOptions(httpConfig).tls).toMatchInlineSnapshot(`
|
expect(getServerOptions(httpConfig).tls).toMatchInlineSnapshot(`
|
||||||
|
@ -152,8 +149,7 @@ describe('getServerOptions', () => {
|
||||||
clientAuthentication: 'required',
|
clientAuthentication: 'required',
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
{} as any,
|
{} as any
|
||||||
Env.createDefault(getEnvOptions())
|
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(getServerOptions(httpConfig).tls).toMatchInlineSnapshot(`
|
expect(getServerOptions(httpConfig).tls).toMatchInlineSnapshot(`
|
||||||
|
|
|
@ -84,7 +84,7 @@ export class LegacyService implements CoreService {
|
||||||
private settings?: LegacyVars;
|
private settings?: LegacyVars;
|
||||||
|
|
||||||
constructor(private readonly coreContext: CoreContext) {
|
constructor(private readonly coreContext: CoreContext) {
|
||||||
const { logger, configService, env } = coreContext;
|
const { logger, configService } = coreContext;
|
||||||
|
|
||||||
this.log = logger.get('legacy-service');
|
this.log = logger.get('legacy-service');
|
||||||
this.devConfig$ = configService
|
this.devConfig$ = configService
|
||||||
|
@ -93,7 +93,7 @@ export class LegacyService implements CoreService {
|
||||||
this.httpConfig$ = combineLatest(
|
this.httpConfig$ = combineLatest(
|
||||||
configService.atPath<HttpConfigType>(httpConfig.path),
|
configService.atPath<HttpConfigType>(httpConfig.path),
|
||||||
configService.atPath<CspConfigType>(cspConfig.path)
|
configService.atPath<CspConfigType>(cspConfig.path)
|
||||||
).pipe(map(([http, csp]) => new HttpConfig(http, csp, env)));
|
).pipe(map(([http, csp]) => new HttpConfig(http, csp)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async discoverPlugins(): Promise<LegacyServiceDiscoverPlugins> {
|
public async discoverPlugins(): Promise<LegacyServiceDiscoverPlugins> {
|
||||||
|
|
|
@ -18,13 +18,14 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { mockPackage, mockReaddir, mockReadFile, mockStat } from './plugins_discovery.test.mocks';
|
import { mockPackage, mockReaddir, mockReadFile, mockStat } from './plugins_discovery.test.mocks';
|
||||||
|
import { rawConfigServiceMock } from '../../config/raw_config_service.mock';
|
||||||
|
import { loggingServiceMock } from '../../logging/logging_service.mock';
|
||||||
|
|
||||||
import { resolve } from 'path';
|
import { resolve } from 'path';
|
||||||
import { first, map, toArray } from 'rxjs/operators';
|
import { first, map, toArray } from 'rxjs/operators';
|
||||||
|
|
||||||
import { ConfigService, Env } from '../../config';
|
import { ConfigService, Env } from '../../config';
|
||||||
import { rawConfigServiceMock } from '../../config/raw_config_service.mock';
|
|
||||||
import { getEnvOptions } from '../../config/__mocks__/env';
|
import { getEnvOptions } from '../../config/__mocks__/env';
|
||||||
import { loggingServiceMock } from '../../logging/logging_service.mock';
|
|
||||||
import { PluginWrapper } from '../plugin';
|
import { PluginWrapper } from '../plugin';
|
||||||
import { PluginsConfig, PluginsConfigType, config } from '../plugins_config';
|
import { PluginsConfig, PluginsConfigType, config } from '../plugins_config';
|
||||||
import { discover } from './plugins_discovery';
|
import { discover } from './plugins_discovery';
|
||||||
|
@ -37,6 +38,7 @@ const TEST_PLUGIN_SEARCH_PATHS = {
|
||||||
const TEST_EXTRA_PLUGIN_PATH = resolve(process.cwd(), 'my-extra-plugin');
|
const TEST_EXTRA_PLUGIN_PATH = resolve(process.cwd(), 'my-extra-plugin');
|
||||||
|
|
||||||
const logger = loggingServiceMock.create();
|
const logger = loggingServiceMock.create();
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mockReaddir.mockImplementation((path, cb) => {
|
mockReaddir.mockImplementation((path, cb) => {
|
||||||
if (path === TEST_PLUGIN_SEARCH_PATHS.nonEmptySrcPlugins) {
|
if (path === TEST_PLUGIN_SEARCH_PATHS.nonEmptySrcPlugins) {
|
||||||
|
@ -182,12 +184,84 @@ test('properly iterates through plugin search locations', async () => {
|
||||||
'kibana.json'
|
'kibana.json'
|
||||||
)})`,
|
)})`,
|
||||||
]);
|
]);
|
||||||
|
});
|
||||||
expect(loggingServiceMock.collect(logger).warn).toMatchInlineSnapshot(`
|
|
||||||
Array [
|
test('logs a warning about --plugin-path when used in development', async () => {
|
||||||
Array [
|
mockPackage.raw = {
|
||||||
"Explicit plugin paths [${TEST_EXTRA_PLUGIN_PATH}] are only supported in development. Relative imports will not work in production.",
|
branch: 'master',
|
||||||
],
|
version: '1.2.3',
|
||||||
]
|
build: {
|
||||||
`);
|
distributable: true,
|
||||||
|
number: 1,
|
||||||
|
sha: '',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const env = Env.createDefault(
|
||||||
|
getEnvOptions({
|
||||||
|
cliArgs: { dev: false, envName: 'development' },
|
||||||
|
})
|
||||||
|
);
|
||||||
|
const configService = new ConfigService(
|
||||||
|
rawConfigServiceMock.create({ rawConfig: { plugins: { paths: [TEST_EXTRA_PLUGIN_PATH] } } }),
|
||||||
|
env,
|
||||||
|
logger
|
||||||
|
);
|
||||||
|
await configService.setSchema(config.path, config.schema);
|
||||||
|
|
||||||
|
const rawConfig = await configService
|
||||||
|
.atPath<PluginsConfigType>('plugins')
|
||||||
|
.pipe(first())
|
||||||
|
.toPromise();
|
||||||
|
|
||||||
|
discover(new PluginsConfig(rawConfig, env), {
|
||||||
|
coreId: Symbol(),
|
||||||
|
configService,
|
||||||
|
env,
|
||||||
|
logger,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(loggingServiceMock.collect(logger).warn).toEqual([
|
||||||
|
[
|
||||||
|
`Explicit plugin paths [${TEST_EXTRA_PLUGIN_PATH}] should only be used in development. Relative imports may not work properly in production.`,
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('does not log a warning about --plugin-path when used in production', async () => {
|
||||||
|
mockPackage.raw = {
|
||||||
|
branch: 'master',
|
||||||
|
version: '1.2.3',
|
||||||
|
build: {
|
||||||
|
distributable: true,
|
||||||
|
number: 1,
|
||||||
|
sha: '',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const env = Env.createDefault(
|
||||||
|
getEnvOptions({
|
||||||
|
cliArgs: { dev: false, envName: 'production' },
|
||||||
|
})
|
||||||
|
);
|
||||||
|
const configService = new ConfigService(
|
||||||
|
rawConfigServiceMock.create({ rawConfig: { plugins: { paths: [TEST_EXTRA_PLUGIN_PATH] } } }),
|
||||||
|
env,
|
||||||
|
logger
|
||||||
|
);
|
||||||
|
await configService.setSchema(config.path, config.schema);
|
||||||
|
|
||||||
|
const rawConfig = await configService
|
||||||
|
.atPath<PluginsConfigType>('plugins')
|
||||||
|
.pipe(first())
|
||||||
|
.toPromise();
|
||||||
|
|
||||||
|
discover(new PluginsConfig(rawConfig, env), {
|
||||||
|
coreId: Symbol(),
|
||||||
|
configService,
|
||||||
|
env,
|
||||||
|
logger,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(loggingServiceMock.collect(logger).warn).toEqual([]);
|
||||||
});
|
});
|
||||||
|
|
|
@ -46,9 +46,9 @@ export function discover(config: PluginsConfig, coreContext: CoreContext) {
|
||||||
const log = coreContext.logger.get('plugins-discovery');
|
const log = coreContext.logger.get('plugins-discovery');
|
||||||
log.debug('Discovering plugins...');
|
log.debug('Discovering plugins...');
|
||||||
|
|
||||||
if (config.additionalPluginPaths.length) {
|
if (config.additionalPluginPaths.length && coreContext.env.mode.dev) {
|
||||||
log.warn(
|
log.warn(
|
||||||
`Explicit plugin paths [${config.additionalPluginPaths}] are only supported in development. Relative imports will not work in production.`
|
`Explicit plugin paths [${config.additionalPluginPaths}] should only be used in development. Relative imports may not work properly in production.`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
44
src/core/server/plugins/plugins_config.test.ts
Normal file
44
src/core/server/plugins/plugins_config.test.ts
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { PluginsConfig, PluginsConfigType } from './plugins_config';
|
||||||
|
import { Env } from '../config';
|
||||||
|
import { getEnvOptions } from '../config/__mocks__/env';
|
||||||
|
|
||||||
|
describe('PluginsConfig', () => {
|
||||||
|
it('retrieves additionalPluginPaths from config.paths when in production mode', () => {
|
||||||
|
const env = Env.createDefault(getEnvOptions({ cliArgs: { dev: false } }));
|
||||||
|
const rawConfig: PluginsConfigType = {
|
||||||
|
initialize: true,
|
||||||
|
paths: ['some-path', 'another-path'],
|
||||||
|
};
|
||||||
|
const config = new PluginsConfig(rawConfig, env);
|
||||||
|
expect(config.additionalPluginPaths).toEqual(['some-path', 'another-path']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('retrieves additionalPluginPaths from config.paths when in development mode', () => {
|
||||||
|
const env = Env.createDefault(getEnvOptions({ cliArgs: { dev: true } }));
|
||||||
|
const rawConfig: PluginsConfigType = {
|
||||||
|
initialize: true,
|
||||||
|
paths: ['some-path', 'another-path'],
|
||||||
|
};
|
||||||
|
const config = new PluginsConfig(rawConfig, env);
|
||||||
|
expect(config.additionalPluginPaths).toEqual(['some-path', 'another-path']);
|
||||||
|
});
|
||||||
|
});
|
|
@ -29,7 +29,6 @@ export const config = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines an array of directories where another plugin should be loaded from.
|
* Defines an array of directories where another plugin should be loaded from.
|
||||||
* Should only be used in a development environment.
|
|
||||||
*/
|
*/
|
||||||
paths: schema.arrayOf(schema.string(), { defaultValue: [] }),
|
paths: schema.arrayOf(schema.string(), { defaultValue: [] }),
|
||||||
}),
|
}),
|
||||||
|
@ -55,7 +54,6 @@ export class PluginsConfig {
|
||||||
constructor(rawConfig: PluginsConfigType, env: Env) {
|
constructor(rawConfig: PluginsConfigType, env: Env) {
|
||||||
this.initialize = rawConfig.initialize;
|
this.initialize = rawConfig.initialize;
|
||||||
this.pluginSearchPaths = env.pluginSearchPaths;
|
this.pluginSearchPaths = env.pluginSearchPaths;
|
||||||
// Only allow custom plugin paths in dev.
|
this.additionalPluginPaths = rawConfig.paths;
|
||||||
this.additionalPluginPaths = env.mode.dev ? rawConfig.paths : [];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ Object {
|
||||||
"oss": false,
|
"oss": false,
|
||||||
"quiet": false,
|
"quiet": false,
|
||||||
"repl": false,
|
"repl": false,
|
||||||
|
"runExamples": false,
|
||||||
"silent": false,
|
"silent": false,
|
||||||
"watch": false,
|
"watch": false,
|
||||||
},
|
},
|
||||||
|
@ -39,7 +40,6 @@ Object {
|
||||||
"version": Any<String>,
|
"version": Any<String>,
|
||||||
},
|
},
|
||||||
"pluginSearchPaths": Any<Array>,
|
"pluginSearchPaths": Any<Array>,
|
||||||
"staticFilesDir": Any<String>,
|
|
||||||
},
|
},
|
||||||
"i18n": Object {
|
"i18n": Object {
|
||||||
"translationsUrl": "/mock-server-basepath/translations/en.json",
|
"translationsUrl": "/mock-server-basepath/translations/en.json",
|
||||||
|
@ -89,6 +89,7 @@ Object {
|
||||||
"oss": false,
|
"oss": false,
|
||||||
"quiet": false,
|
"quiet": false,
|
||||||
"repl": false,
|
"repl": false,
|
||||||
|
"runExamples": false,
|
||||||
"silent": false,
|
"silent": false,
|
||||||
"watch": false,
|
"watch": false,
|
||||||
},
|
},
|
||||||
|
@ -110,7 +111,6 @@ Object {
|
||||||
"version": Any<String>,
|
"version": Any<String>,
|
||||||
},
|
},
|
||||||
"pluginSearchPaths": Any<Array>,
|
"pluginSearchPaths": Any<Array>,
|
||||||
"staticFilesDir": Any<String>,
|
|
||||||
},
|
},
|
||||||
"i18n": Object {
|
"i18n": Object {
|
||||||
"translationsUrl": "/mock-server-basepath/translations/en.json",
|
"translationsUrl": "/mock-server-basepath/translations/en.json",
|
||||||
|
@ -160,6 +160,7 @@ Object {
|
||||||
"oss": false,
|
"oss": false,
|
||||||
"quiet": false,
|
"quiet": false,
|
||||||
"repl": false,
|
"repl": false,
|
||||||
|
"runExamples": false,
|
||||||
"silent": false,
|
"silent": false,
|
||||||
"watch": false,
|
"watch": false,
|
||||||
},
|
},
|
||||||
|
@ -181,7 +182,6 @@ Object {
|
||||||
"version": Any<String>,
|
"version": Any<String>,
|
||||||
},
|
},
|
||||||
"pluginSearchPaths": Any<Array>,
|
"pluginSearchPaths": Any<Array>,
|
||||||
"staticFilesDir": Any<String>,
|
|
||||||
},
|
},
|
||||||
"i18n": Object {
|
"i18n": Object {
|
||||||
"translationsUrl": "/mock-server-basepath/translations/en.json",
|
"translationsUrl": "/mock-server-basepath/translations/en.json",
|
||||||
|
@ -235,6 +235,7 @@ Object {
|
||||||
"oss": false,
|
"oss": false,
|
||||||
"quiet": false,
|
"quiet": false,
|
||||||
"repl": false,
|
"repl": false,
|
||||||
|
"runExamples": false,
|
||||||
"silent": false,
|
"silent": false,
|
||||||
"watch": false,
|
"watch": false,
|
||||||
},
|
},
|
||||||
|
@ -256,7 +257,6 @@ Object {
|
||||||
"version": Any<String>,
|
"version": Any<String>,
|
||||||
},
|
},
|
||||||
"pluginSearchPaths": Any<Array>,
|
"pluginSearchPaths": Any<Array>,
|
||||||
"staticFilesDir": Any<String>,
|
|
||||||
},
|
},
|
||||||
"i18n": Object {
|
"i18n": Object {
|
||||||
"translationsUrl": "/translations/en.json",
|
"translationsUrl": "/translations/en.json",
|
||||||
|
@ -306,6 +306,7 @@ Object {
|
||||||
"oss": false,
|
"oss": false,
|
||||||
"quiet": false,
|
"quiet": false,
|
||||||
"repl": false,
|
"repl": false,
|
||||||
|
"runExamples": false,
|
||||||
"silent": false,
|
"silent": false,
|
||||||
"watch": false,
|
"watch": false,
|
||||||
},
|
},
|
||||||
|
@ -327,7 +328,6 @@ Object {
|
||||||
"version": Any<String>,
|
"version": Any<String>,
|
||||||
},
|
},
|
||||||
"pluginSearchPaths": Any<Array>,
|
"pluginSearchPaths": Any<Array>,
|
||||||
"staticFilesDir": Any<String>,
|
|
||||||
},
|
},
|
||||||
"i18n": Object {
|
"i18n": Object {
|
||||||
"translationsUrl": "/mock-server-basepath/translations/en.json",
|
"translationsUrl": "/mock-server-basepath/translations/en.json",
|
||||||
|
@ -377,6 +377,7 @@ Object {
|
||||||
"oss": false,
|
"oss": false,
|
||||||
"quiet": false,
|
"quiet": false,
|
||||||
"repl": false,
|
"repl": false,
|
||||||
|
"runExamples": false,
|
||||||
"silent": false,
|
"silent": false,
|
||||||
"watch": false,
|
"watch": false,
|
||||||
},
|
},
|
||||||
|
@ -398,7 +399,6 @@ Object {
|
||||||
"version": Any<String>,
|
"version": Any<String>,
|
||||||
},
|
},
|
||||||
"pluginSearchPaths": Any<Array>,
|
"pluginSearchPaths": Any<Array>,
|
||||||
"staticFilesDir": Any<String>,
|
|
||||||
},
|
},
|
||||||
"i18n": Object {
|
"i18n": Object {
|
||||||
"translationsUrl": "/mock-server-basepath/translations/en.json",
|
"translationsUrl": "/mock-server-basepath/translations/en.json",
|
||||||
|
@ -448,6 +448,7 @@ Object {
|
||||||
"oss": false,
|
"oss": false,
|
||||||
"quiet": false,
|
"quiet": false,
|
||||||
"repl": false,
|
"repl": false,
|
||||||
|
"runExamples": false,
|
||||||
"silent": false,
|
"silent": false,
|
||||||
"watch": false,
|
"watch": false,
|
||||||
},
|
},
|
||||||
|
@ -469,7 +470,6 @@ Object {
|
||||||
"version": Any<String>,
|
"version": Any<String>,
|
||||||
},
|
},
|
||||||
"pluginSearchPaths": Any<Array>,
|
"pluginSearchPaths": Any<Array>,
|
||||||
"staticFilesDir": Any<String>,
|
|
||||||
},
|
},
|
||||||
"i18n": Object {
|
"i18n": Object {
|
||||||
"translationsUrl": "/translations/en.json",
|
"translationsUrl": "/translations/en.json",
|
||||||
|
@ -519,6 +519,7 @@ Object {
|
||||||
"oss": false,
|
"oss": false,
|
||||||
"quiet": false,
|
"quiet": false,
|
||||||
"repl": false,
|
"repl": false,
|
||||||
|
"runExamples": false,
|
||||||
"silent": false,
|
"silent": false,
|
||||||
"watch": false,
|
"watch": false,
|
||||||
},
|
},
|
||||||
|
@ -540,7 +541,6 @@ Object {
|
||||||
"version": Any<String>,
|
"version": Any<String>,
|
||||||
},
|
},
|
||||||
"pluginSearchPaths": Any<Array>,
|
"pluginSearchPaths": Any<Array>,
|
||||||
"staticFilesDir": Any<String>,
|
|
||||||
},
|
},
|
||||||
"i18n": Object {
|
"i18n": Object {
|
||||||
"translationsUrl": "/mock-server-basepath/translations/en.json",
|
"translationsUrl": "/mock-server-basepath/translations/en.json",
|
||||||
|
@ -592,6 +592,7 @@ Object {
|
||||||
"oss": false,
|
"oss": false,
|
||||||
"quiet": false,
|
"quiet": false,
|
||||||
"repl": false,
|
"repl": false,
|
||||||
|
"runExamples": false,
|
||||||
"silent": false,
|
"silent": false,
|
||||||
"watch": false,
|
"watch": false,
|
||||||
},
|
},
|
||||||
|
@ -613,7 +614,6 @@ Object {
|
||||||
"version": Any<String>,
|
"version": Any<String>,
|
||||||
},
|
},
|
||||||
"pluginSearchPaths": Any<Array>,
|
"pluginSearchPaths": Any<Array>,
|
||||||
"staticFilesDir": Any<String>,
|
|
||||||
},
|
},
|
||||||
"i18n": Object {
|
"i18n": Object {
|
||||||
"translationsUrl": "/mock-server-basepath/translations/en.json",
|
"translationsUrl": "/mock-server-basepath/translations/en.json",
|
||||||
|
@ -663,6 +663,7 @@ Object {
|
||||||
"oss": false,
|
"oss": false,
|
||||||
"quiet": false,
|
"quiet": false,
|
||||||
"repl": false,
|
"repl": false,
|
||||||
|
"runExamples": false,
|
||||||
"silent": false,
|
"silent": false,
|
||||||
"watch": false,
|
"watch": false,
|
||||||
},
|
},
|
||||||
|
@ -684,7 +685,6 @@ Object {
|
||||||
"version": Any<String>,
|
"version": Any<String>,
|
||||||
},
|
},
|
||||||
"pluginSearchPaths": Any<Array>,
|
"pluginSearchPaths": Any<Array>,
|
||||||
"staticFilesDir": Any<String>,
|
|
||||||
},
|
},
|
||||||
"i18n": Object {
|
"i18n": Object {
|
||||||
"translationsUrl": "/mock-server-basepath/translations/en.json",
|
"translationsUrl": "/mock-server-basepath/translations/en.json",
|
||||||
|
|
|
@ -41,7 +41,6 @@ const INJECTED_METADATA = {
|
||||||
version: expect.any(String),
|
version: expect.any(String),
|
||||||
},
|
},
|
||||||
pluginSearchPaths: expect.any(Array),
|
pluginSearchPaths: expect.any(Array),
|
||||||
staticFilesDir: expect.any(String),
|
|
||||||
},
|
},
|
||||||
legacyMetadata: {
|
legacyMetadata: {
|
||||||
branch: expect.any(String),
|
branch: expect.any(String),
|
||||||
|
@ -50,6 +49,7 @@ const INJECTED_METADATA = {
|
||||||
version: expect.any(String),
|
version: expect.any(String),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const { createKibanaRequest, createRawRequest } = httpServerMock;
|
const { createKibanaRequest, createRawRequest } = httpServerMock;
|
||||||
const legacyApp = { getId: () => 'legacy' };
|
const legacyApp = { getId: () => 'legacy' };
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,7 @@ export function createRootWithSettings(
|
||||||
repl: false,
|
repl: false,
|
||||||
basePath: false,
|
basePath: false,
|
||||||
optimize: false,
|
optimize: false,
|
||||||
|
runExamples: false,
|
||||||
oss: true,
|
oss: true,
|
||||||
...cliArgs,
|
...cliArgs,
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue