diff --git a/src/cli/cluster/worker.js b/src/cli/cluster/worker.js index d6f0c71cfd04353..5261f18ccb70448 100644 --- a/src/cli/cluster/worker.js +++ b/src/cli/cluster/worker.js @@ -24,7 +24,14 @@ import { EventEmitter } from 'events'; import { BinderFor, fromRoot } from '../../utils'; const cliPath = fromRoot('src/core/cli'); -const baseArgs = _.difference(process.argv.slice(2), ['--no-watch']); +const baseArgs = process.argv.slice(2).filter((arg) => { + // The following arguments should be consumed by main process only, + // workers will receive these only from cluster manager if needed. + return arg !== 'no-watch' + && !arg.startsWith('--server.port') + && !arg.startsWith('--server.basePath') + && !arg.startsWith('--server.rewriteBasePath'); +}); const baseArgv = [process.execPath, cliPath].concat(baseArgs); cluster.setupMaster({ diff --git a/src/core/cli/__tests__/read_keystore.test.ts b/src/core/cli/__tests__/read_keystore.test.ts new file mode 100644 index 000000000000000..b9c7c564fab425d --- /dev/null +++ b/src/core/cli/__tests__/read_keystore.test.ts @@ -0,0 +1,46 @@ +/* + * 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. + */ + +jest.mock('../../../server/keystore'); + +import path from 'path'; +// @ts-ignore: implicit any for JS file +import { Keystore } from '../../../server/keystore'; +import { readKeystore } from '../read_keystore'; + +describe('core/cli/read_keystore', () => { + beforeEach(() => { + jest.resetAllMocks(); + }); + + test('returns keystore data', () => { + const keystoreData = { foo: 'bar' }; + Keystore.prototype.data = keystoreData; + + expect(readKeystore()).toEqual(keystoreData); + }); + + test('uses data path provided', () => { + const keystoreDir = '/foo/'; + const keystorePath = path.join(keystoreDir, 'kibana.keystore'); + + readKeystore(keystoreDir); + expect(Keystore.mock.calls[0][0]).toEqual(keystorePath); + }); +}); diff --git a/src/core/cli/args.ts b/src/core/cli/args.ts index 744309b8b9ba7d9..8d18acece2525b7 100644 --- a/src/core/cli/args.ts +++ b/src/core/cli/args.ts @@ -18,8 +18,8 @@ */ import chalk from 'chalk'; +import { getServeCommandOptions } from './commands'; import { InstallationFeatures } from './installation_features'; -import { getServeCommandOptions } from './serve'; export const usage = 'Usage: bin/kibana [options]'; export const description = diff --git a/src/core/cli/cli.ts b/src/core/cli/cli.ts index 6bae98b34a9626f..a9ebc241f44f704 100644 --- a/src/core/cli/cli.ts +++ b/src/core/cli/cli.ts @@ -32,13 +32,13 @@ import { LoggingConfig } from '../server/logging'; import { MutableLoggerFactory } from '../server/logging/logger_factory'; import { LoggingService } from '../server/logging/logging_service'; import * as args from './args'; +import { createServeCommand } from './commands'; import { CLUSTER_MANAGER_PATH, detectInstallationFeatures, REPL_PATH, } from './installation_features'; import { overrideConfigWithArgv } from './override_config_with_argv'; -import { createServeCommand } from './serve'; const installationFeatures = detectInstallationFeatures(); @@ -137,15 +137,11 @@ export const run = (argv: string[]) => { const kbnServer = new KbnServer(rawConfig.getRaw(), env.legacy); const legacyService = new LegacyService(env, loggerFactory, configService, kbnServer); - if (parsedArgs.repl) { - if (!installationFeatures.isReplModeSupported) { - throw new Error('Kibana REPL mode can only be run in development mode.'); - } else if (process.env.kbnWorkerType === 'server') { - // The kbnWorkerType check is necessary to prevent the repl - // from being started multiple times in different processes. - // We only want one REPL. - require(REPL_PATH).startRepl(kbnServer); - } + // The kbnWorkerType check is necessary to prevent the repl + // from being started multiple times in different processes. + // We only want one REPL. + if (parsedArgs.repl && process.env.kbnWorkerType === 'server') { + require(REPL_PATH).startRepl(kbnServer); } const root = new Root( diff --git a/src/core/cli/commands/index.ts b/src/core/cli/commands/index.ts new file mode 100644 index 000000000000000..b836873418be11e --- /dev/null +++ b/src/core/cli/commands/index.ts @@ -0,0 +1,20 @@ +/* + * 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. + */ + +export { createServeCommand, getServeCommandOptions } from './serve'; diff --git a/src/core/cli/serve/index.ts b/src/core/cli/commands/serve.ts similarity index 97% rename from src/core/cli/serve/index.ts rename to src/core/cli/commands/serve.ts index 36d0a5081d633f1..d115ba7df11a338 100644 --- a/src/core/cli/serve/index.ts +++ b/src/core/cli/commands/serve.ts @@ -229,6 +229,10 @@ export function createServeCommand(installationFeatures: InstallationFeatures): } } + if (argv.repl && !installationFeatures.isReplModeSupported) { + throw new Error('[repl] Kibana REPL mode can only be run in development mode.'); + } + if (argv.port !== undefined && isNaN(argv.port)) { throw new Error(`[port] must be a number, but was a string`); } diff --git a/src/core/cli/override_config_with_argv.ts b/src/core/cli/override_config_with_argv.ts index a2096c39de8fa16..a2d726beddc6abc 100644 --- a/src/core/cli/override_config_with_argv.ts +++ b/src/core/cli/override_config_with_argv.ts @@ -21,6 +21,7 @@ import { RawConfig } from '../server/config'; import * as args from './args'; import { DEV_SSL_CERT_PATH, DEV_SSL_KEY_PATH } from './dev_ssl'; import { InstallationFeatures, XPACK_INSTALLED_PATH } from './installation_features'; +import { readKeystore } from './read_keystore'; /** * Overrides some config values with ones from argv. @@ -111,6 +112,7 @@ export function overrideConfigWithArgv( ] ); + // Merge unknown CLI args into config. for (const unknownArgKey of args.getUnknownOptions(argv, installationFeatures)) { let unknownArgValue = argv[unknownArgKey]; try { @@ -122,5 +124,10 @@ export function overrideConfigWithArgv( config.set(unknownArgKey, unknownArgValue); } + // Merge keystore content into config. + for (const [key, value] of Object.entries(readKeystore(config.get(['path', 'data'])))) { + config.set(key, value); + } + return config; } diff --git a/src/core/cli/read_keystore.ts b/src/core/cli/read_keystore.ts new file mode 100644 index 000000000000000..4866dafe5ac24bc --- /dev/null +++ b/src/core/cli/read_keystore.ts @@ -0,0 +1,31 @@ +/* + * 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 path from 'path'; + +// @ts-ignore: implicit any for JS file +import { Keystore } from '../../server/keystore'; +import { getData } from '../../server/path'; + +export function readKeystore(dataPath = getData()): Record { + const keystore = new Keystore(path.join(dataPath, 'kibana.keystore')); + keystore.load(); + + return keystore.data; +}