Move kibana-keystore from data/ to config/ (#57856)

* Move kibana-keystore from data/ to config/

This is a breaking change to move the location of kibana-keystore.
Keystores in other stack products live in the config directory, so this
updates our current path to be consistent.

Closes #25746

* add breaking changes

* update comment

* wip

* fix docs

* read from both keystore locations, write priority to non-deprecated

* note data directory fallback

* add tests for get_keystore

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
Jonathan Budzenski 2020-07-13 10:56:25 -05:00 committed by GitHub
parent c44f019790
commit 94ef03dbd3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 125 additions and 9 deletions

View file

@ -115,12 +115,17 @@ URL that it derived from the actual server address and `xpack.security.public` s
*Impact:* Any workflow that involved manually clearing generated bundles will have to be updated with the new path.
[float]]
=== kibana.keystore has moved from the `data` folder to the `config` folder
*Details:* By default, kibana.keystore has moved from the configured `path.data` folder to `<root>/config` for archive distributions
and `/etc/kibana` for package distributions. If a pre-existing keystore exists in the data directory that path will continue to be used.
[float]
[[breaking_80_user_role_changes]]
=== User role changes
[float]
==== `kibana_user` role has been removed and `kibana_admin` has been added.
=== `kibana_user` role has been removed and `kibana_admin` has been added.
*Details:* The `kibana_user` role has been removed and `kibana_admin` has been added to better
reflect its intended use. This role continues to grant all access to every

View file

@ -18,20 +18,16 @@
*/
import _ from 'lodash';
import { join } from 'path';
import { pkg } from '../core/server/utils';
import Command from '../cli/command';
import { getDataPath } from '../core/server/path';
import { Keystore } from '../legacy/server/keystore';
const path = join(getDataPath(), 'kibana.keystore');
const keystore = new Keystore(path);
import { createCli } from './create';
import { listCli } from './list';
import { addCli } from './add';
import { removeCli } from './remove';
import { getKeystore } from './get_keystore';
const argv = process.env.kbnWorkerArgv
? JSON.parse(process.env.kbnWorkerArgv)
@ -42,6 +38,8 @@ program
.version(pkg.version)
.description('A tool for managing settings stored in the Kibana keystore');
const keystore = new Keystore(getKeystore());
createCli(program, keystore);
listCli(program, keystore);
addCli(program, keystore);

View file

@ -0,0 +1,40 @@
/*
* 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 { existsSync } from 'fs';
import { join } from 'path';
import Logger from '../cli_plugin/lib/logger';
import { getConfigDirectory, getDataPath } from '../core/server/path';
export function getKeystore() {
const configKeystore = join(getConfigDirectory(), 'kibana.keystore');
const dataKeystore = join(getDataPath(), 'kibana.keystore');
let keystorePath = null;
if (existsSync(dataKeystore)) {
const logger = new Logger();
logger.log(
`kibana.keystore located in the data folder is deprecated. Future versions will use the config folder.`
);
keystorePath = dataKeystore;
} else {
keystorePath = configKeystore;
}
return keystorePath;
}

View file

@ -0,0 +1,57 @@
/*
* 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 { getKeystore } from './get_keystore';
import Logger from '../cli_plugin/lib/logger';
import fs from 'fs';
import sinon from 'sinon';
describe('get_keystore', () => {
const sandbox = sinon.createSandbox();
beforeEach(() => {
sandbox.stub(Logger.prototype, 'log');
});
afterEach(() => {
sandbox.restore();
});
it('uses the config directory if there is no pre-existing keystore', () => {
sandbox.stub(fs, 'existsSync').returns(false);
expect(getKeystore()).toContain('config');
expect(getKeystore()).not.toContain('data');
});
it('uses the data directory if there is a pre-existing keystore in the data directory', () => {
sandbox.stub(fs, 'existsSync').returns(true);
expect(getKeystore()).toContain('data');
expect(getKeystore()).not.toContain('config');
});
it('logs a deprecation warning if the data directory is used', () => {
sandbox.stub(fs, 'existsSync').returns(true);
getKeystore();
sandbox.assert.calledOnce(Logger.prototype.log);
sandbox.assert.calledWith(
Logger.prototype.log,
'kibana.keystore located in the data folder is deprecated. Future versions will use the config folder.'
);
});
});

View file

@ -18,7 +18,7 @@
*/
import { accessSync, constants } from 'fs';
import { getConfigPath, getDataPath } from './';
import { getConfigPath, getDataPath, getConfigDirectory } from './';
describe('Default path finder', () => {
it('should find a kibana.yml', () => {
@ -30,4 +30,9 @@ describe('Default path finder', () => {
const dataPath = getDataPath();
expect(() => accessSync(dataPath, constants.R_OK)).not.toThrow();
});
it('should find a config directory', () => {
const configDirectory = getConfigDirectory();
expect(() => accessSync(configDirectory, constants.R_OK)).not.toThrow();
});
});

View file

@ -30,6 +30,10 @@ const CONFIG_PATHS = [
fromRoot('config/kibana.yml'),
].filter(isString);
const CONFIG_DIRECTORIES = [process.env.KIBANA_PATH_CONF, fromRoot('config'), '/etc/kibana'].filter(
isString
);
const DATA_PATHS = [
process.env.DATA_PATH, // deprecated
fromRoot('data'),
@ -49,12 +53,19 @@ function findFile(paths: string[]) {
}
/**
* Get the path where the config files are stored
* Get the path of kibana.yml
* @internal
*/
export const getConfigPath = () => findFile(CONFIG_PATHS);
/**
* Get the path where the data can be stored
* Get the directory containing configuration files
* @internal
*/
export const getConfigDirectory = () => findFile(CONFIG_DIRECTORIES);
/**
* Get the directory containing runtime data
* @internal
*/
export const getDataPath = () => findFile(DATA_PATHS);