Skip to content

Commit afe7ea1

Browse files
committed
fix config validation (#96502)
1 parent 6de70f8 commit afe7ea1

5 files changed

Lines changed: 58 additions & 40 deletions

File tree

src/core/server/config/ensure_valid_configuration.test.ts

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,40 @@ describe('ensureValidConfiguration', () => {
1616
beforeEach(() => {
1717
jest.clearAllMocks();
1818
configService = configServiceMock.create();
19-
configService.getUsedPaths.mockReturnValue(Promise.resolve(['core', 'elastic']));
19+
20+
configService.validate.mockResolvedValue();
21+
configService.getUsedPaths.mockReturnValue(Promise.resolve([]));
2022
});
2123

22-
it('returns normally when there is no unused keys', async () => {
23-
configService.getUnusedPaths.mockResolvedValue([]);
24+
it('returns normally when there is no unused keys and when the config validates', async () => {
2425
await expect(ensureValidConfiguration(configService as any)).resolves.toBeUndefined();
2526
});
2627

28+
it('throws when config validation fails', async () => {
29+
configService.validate.mockImplementation(() => {
30+
throw new Error('some message');
31+
});
32+
33+
await expect(ensureValidConfiguration(configService as any)).rejects.toMatchInlineSnapshot(
34+
`[Error: some message]`
35+
);
36+
});
37+
38+
it('throws a `CriticalError` with the correct processExitCode value when config validation fails', async () => {
39+
expect.assertions(2);
40+
41+
configService.validate.mockImplementation(() => {
42+
throw new Error('some message');
43+
});
44+
45+
try {
46+
await ensureValidConfiguration(configService as any);
47+
} catch (e) {
48+
expect(e).toBeInstanceOf(CriticalError);
49+
expect(e.processExitCode).toEqual(78);
50+
}
51+
});
52+
2753
it('throws when there are some unused keys', async () => {
2854
configService.getUnusedPaths.mockResolvedValue(['some.key', 'some.other.key']);
2955

@@ -44,4 +70,18 @@ describe('ensureValidConfiguration', () => {
4470
expect(e.processExitCode).toEqual(64);
4571
}
4672
});
73+
74+
it('does not throw when all unused keys are included in the ignored paths', async () => {
75+
configService.getUnusedPaths.mockResolvedValue(['dev.someDevKey', 'elastic.apm.enabled']);
76+
77+
await expect(ensureValidConfiguration(configService as any)).resolves.toBeUndefined();
78+
});
79+
80+
it('throws when only some keys are included in the ignored paths', async () => {
81+
configService.getUnusedPaths.mockResolvedValue(['dev.someDevKey', 'some.key']);
82+
83+
await expect(ensureValidConfiguration(configService as any)).rejects.toMatchInlineSnapshot(
84+
`[Error: Unknown configuration key(s): "some.key". Check for spelling errors and ensure that expected plugins are installed.]`
85+
);
86+
});
4787
});

src/core/server/config/ensure_valid_configuration.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,27 @@
99
import { ConfigService } from '@kbn/config';
1010
import { CriticalError } from '../errors';
1111

12+
const ignoredPaths = ['dev.', 'elastic.apm.'];
13+
14+
const invalidConfigExitCode = 78;
15+
const legacyInvalidConfigExitCode = 64;
16+
1217
export async function ensureValidConfiguration(configService: ConfigService) {
13-
await configService.validate();
18+
try {
19+
await configService.validate();
20+
} catch (e) {
21+
throw new CriticalError(e.message, 'InvalidConfig', invalidConfigExitCode, e);
22+
}
1423

15-
const unusedConfigKeys = await configService.getUnusedPaths();
24+
const unusedPaths = await configService.getUnusedPaths();
25+
const unusedConfigKeys = unusedPaths.filter((unusedPath) => {
26+
return !ignoredPaths.some((ignoredPath) => unusedPath.startsWith(ignoredPath));
27+
});
1628

1729
if (unusedConfigKeys.length > 0) {
1830
const message = `Unknown configuration key(s): ${unusedConfigKeys
1931
.map((key) => `"${key}"`)
2032
.join(', ')}. Check for spelling errors and ensure that expected plugins are installed.`;
21-
throw new InvalidConfigurationError(message);
22-
}
23-
}
24-
25-
class InvalidConfigurationError extends CriticalError {
26-
constructor(message: string) {
27-
super(message, 'InvalidConfig', 64);
28-
Object.setPrototypeOf(this, InvalidConfigurationError.prototype);
33+
throw new CriticalError(message, 'InvalidConfig', legacyInvalidConfigExitCode);
2934
}
3035
}

src/core/server/dev/dev_config.ts

Lines changed: 0 additions & 16 deletions
This file was deleted.

src/core/server/dev/index.ts

Lines changed: 0 additions & 9 deletions
This file was deleted.

src/core/server/server.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ import { config as cspConfig } from './csp';
3636
import { config as elasticsearchConfig } from './elasticsearch';
3737
import { config as httpConfig } from './http';
3838
import { config as loggingConfig } from './logging';
39-
import { config as devConfig } from './dev';
4039
import { config as kibanaConfig } from './kibana_config';
4140
import { savedObjectsConfig, savedObjectsMigrationConfig } from './saved_objects';
4241
import { config as uiSettingsConfig } from './ui_settings';
@@ -303,7 +302,6 @@ export class Server {
303302
loggingConfig,
304303
httpConfig,
305304
pluginsConfig,
306-
devConfig,
307305
kibanaConfig,
308306
savedObjectsConfig,
309307
savedObjectsMigrationConfig,

0 commit comments

Comments
 (0)