mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
Validate server UUID retrieved from data/uuid using the same match from config validation (#123680)
Exports the uuid regexp used in to validate configuration for use in validating the data/uuid file. Also includes a `trim()` to allow newlines that could have been edited automatically via file editing or configuration management.
This commit is contained in:
parent
2eccc81a45
commit
f021f75aea
3 changed files with 47 additions and 17 deletions
|
@ -22,8 +22,8 @@ jest.mock('./fs', () => ({
|
|||
writeFile: jest.fn(() => Promise.resolve('')),
|
||||
}));
|
||||
|
||||
const DEFAULT_FILE_UUID = 'FILE_UUID';
|
||||
const DEFAULT_CONFIG_UUID = 'CONFIG_UUID';
|
||||
const DEFAULT_FILE_UUID = 'ffffffff-bbbb-0ccc-0ddd-eeeeeeeeeeee';
|
||||
const DEFAULT_CONFIG_UUID = 'cccccccc-bbbb-0ccc-0ddd-eeeeeeeeeeee';
|
||||
const fileNotFoundError = { code: 'ENOENT' };
|
||||
const permissionError = { code: 'EACCES' };
|
||||
const isDirectoryError = { code: 'EISDIR' };
|
||||
|
@ -91,7 +91,7 @@ describe('resolveInstanceUuid', () => {
|
|||
expect(logger.debug).toHaveBeenCalledTimes(1);
|
||||
expect(logger.debug.mock.calls[0]).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
"Updating Kibana instance UUID to: CONFIG_UUID (was: FILE_UUID)",
|
||||
"Updating Kibana instance UUID to: cccccccc-bbbb-0ccc-0ddd-eeeeeeeeeeee (was: ffffffff-bbbb-0ccc-0ddd-eeeeeeeeeeee)",
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
@ -106,7 +106,7 @@ describe('resolveInstanceUuid', () => {
|
|||
expect(logger.debug).toHaveBeenCalledTimes(1);
|
||||
expect(logger.debug.mock.calls[0]).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
"Kibana instance UUID: CONFIG_UUID",
|
||||
"Kibana instance UUID: cccccccc-bbbb-0ccc-0ddd-eeeeeeeeeeee",
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
@ -126,25 +126,45 @@ describe('resolveInstanceUuid', () => {
|
|||
expect(logger.debug).toHaveBeenCalledTimes(1);
|
||||
expect(logger.debug.mock.calls[0]).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
"Setting new Kibana instance UUID: CONFIG_UUID",
|
||||
"Setting new Kibana instance UUID: cccccccc-bbbb-0ccc-0ddd-eeeeeeeeeeee",
|
||||
]
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when file is present and config property is not set', () => {
|
||||
it('does not write to file and returns the file uuid', async () => {
|
||||
beforeEach(() => {
|
||||
serverConfig = createServerConfig(undefined);
|
||||
});
|
||||
|
||||
it('does not write to file and returns the file uuid', async () => {
|
||||
const uuid = await resolveInstanceUuid({ pathConfig, serverConfig, logger });
|
||||
expect(uuid).toEqual(DEFAULT_FILE_UUID);
|
||||
expect(writeFile).not.toHaveBeenCalled();
|
||||
expect(logger.debug).toHaveBeenCalledTimes(1);
|
||||
expect(logger.debug.mock.calls[0]).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
"Resuming persistent Kibana instance UUID: FILE_UUID",
|
||||
"Resuming persistent Kibana instance UUID: ffffffff-bbbb-0ccc-0ddd-eeeeeeeeeeee",
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
describe('when file contains an invalid uuid', () => {
|
||||
it('throws an explicit error for uuid formatting', async () => {
|
||||
mockReadFile({ uuid: 'invalid uuid in data file' });
|
||||
await expect(
|
||||
resolveInstanceUuid({ pathConfig, serverConfig, logger })
|
||||
).rejects.toThrowErrorMatchingInlineSnapshot(`"data-folder/uuid contains an invalid UUID"`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when file contains a trailing new line', () => {
|
||||
it('returns the trimmed file uuid', async () => {
|
||||
mockReadFile({ uuid: DEFAULT_FILE_UUID + '\n' });
|
||||
const uuid = await resolveInstanceUuid({ pathConfig, serverConfig, logger });
|
||||
expect(uuid).toEqual(DEFAULT_FILE_UUID);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when file is present with 7.6.0 UUID', () => {
|
||||
|
@ -193,7 +213,7 @@ describe('resolveInstanceUuid', () => {
|
|||
"UUID from 7.6.0 bug detected, ignoring file UUID",
|
||||
],
|
||||
Array [
|
||||
"Setting new Kibana instance UUID: CONFIG_UUID",
|
||||
"Setting new Kibana instance UUID: cccccccc-bbbb-0ccc-0ddd-eeeeeeeeeeee",
|
||||
],
|
||||
]
|
||||
`);
|
||||
|
|
|
@ -12,6 +12,7 @@ import { PathConfigType } from '@kbn/utils';
|
|||
import { readFile, writeFile } from './fs';
|
||||
import { HttpConfigType } from '../http';
|
||||
import { Logger } from '../logging';
|
||||
import { uuidRegexp } from '../http/http_config';
|
||||
|
||||
const FILE_ENCODING = 'utf8';
|
||||
const FILE_NAME = 'uuid';
|
||||
|
@ -63,16 +64,24 @@ export async function resolveInstanceUuid({
|
|||
}
|
||||
|
||||
async function readUuidFromFile(filepath: string, logger: Logger): Promise<string | undefined> {
|
||||
const content = await readFileContent(filepath);
|
||||
|
||||
if (content === UUID_7_6_0_BUG) {
|
||||
logger.debug(`UUID from 7.6.0 bug detected, ignoring file UUID`);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (content && !content.match(uuidRegexp)) {
|
||||
throw new Error(`${filepath} contains an invalid UUID`);
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
async function readFileContent(filepath: string): Promise<string | undefined> {
|
||||
try {
|
||||
const content = await readFile(filepath);
|
||||
const decoded = content.toString(FILE_ENCODING);
|
||||
|
||||
if (decoded === UUID_7_6_0_BUG) {
|
||||
logger.debug(`UUID from 7.6.0 bug detected, ignoring file UUID`);
|
||||
return undefined;
|
||||
} else {
|
||||
return decoded;
|
||||
}
|
||||
return content.toString(FILE_ENCODING).trim();
|
||||
} catch (e) {
|
||||
if (e.code === 'ENOENT') {
|
||||
// non-existent uuid file is ok, we will create it.
|
||||
|
|
|
@ -21,7 +21,8 @@ import {
|
|||
} from './security_response_headers_config';
|
||||
|
||||
const validBasePathRegex = /^\/.*[^\/]$/;
|
||||
const uuidRegexp = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
||||
export const uuidRegexp =
|
||||
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
||||
const hostURISchema = schema.uri({ scheme: ['http', 'https'] });
|
||||
const match = (regex: RegExp, errorMsg: string) => (str: string) =>
|
||||
regex.test(str) ? undefined : errorMsg;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue