-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Reporting] Internally correct the hostname to "localhost" if "server.host" is "0.0.0.0" #117022
Changes from all commits
42a1296
3b4cd51
987abef
86fd8ce
7af5772
6480620
3d91c33
5ca5a4d
82053bc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -5,27 +5,29 @@ | |||||||||||||||||||||||||||||||||||||
* 2.0. | ||||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
import { CoreSetup, PluginInitializerContext } from 'src/core/server'; | ||||||||||||||||||||||||||||||||||||||
import * as Rx from 'rxjs'; | ||||||||||||||||||||||||||||||||||||||
import { CoreSetup, HttpServerInfo, PluginInitializerContext } from 'src/core/server'; | ||||||||||||||||||||||||||||||||||||||
import { coreMock } from 'src/core/server/mocks'; | ||||||||||||||||||||||||||||||||||||||
import { LevelLogger } from '../lib'; | ||||||||||||||||||||||||||||||||||||||
import { createMockConfigSchema } from '../test_helpers'; | ||||||||||||||||||||||||||||||||||||||
import { LevelLogger } from '../lib/level_logger'; | ||||||||||||||||||||||||||||||||||||||
import { createMockConfigSchema, createMockLevelLogger } from '../test_helpers'; | ||||||||||||||||||||||||||||||||||||||
import { ReportingConfigType } from './'; | ||||||||||||||||||||||||||||||||||||||
import { createConfig$ } from './create_config'; | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
const createMockConfig = ( | ||||||||||||||||||||||||||||||||||||||
mockInitContext: PluginInitializerContext<unknown> | ||||||||||||||||||||||||||||||||||||||
): Rx.Observable<ReportingConfigType> => mockInitContext.config.create(); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
describe('Reporting server createConfig$', () => { | ||||||||||||||||||||||||||||||||||||||
let mockCoreSetup: CoreSetup; | ||||||||||||||||||||||||||||||||||||||
let mockInitContext: PluginInitializerContext; | ||||||||||||||||||||||||||||||||||||||
let mockLogger: LevelLogger; | ||||||||||||||||||||||||||||||||||||||
let mockLogger: jest.Mocked<LevelLogger>; | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
beforeEach(() => { | ||||||||||||||||||||||||||||||||||||||
mockCoreSetup = coreMock.createSetup(); | ||||||||||||||||||||||||||||||||||||||
mockInitContext = coreMock.createPluginInitializerContext( | ||||||||||||||||||||||||||||||||||||||
createMockConfigSchema({ kibanaServer: {} }) | ||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||
mockLogger = { | ||||||||||||||||||||||||||||||||||||||
warn: jest.fn(), | ||||||||||||||||||||||||||||||||||||||
debug: jest.fn(), | ||||||||||||||||||||||||||||||||||||||
clone: jest.fn().mockImplementation(() => mockLogger), | ||||||||||||||||||||||||||||||||||||||
} as unknown as LevelLogger; | ||||||||||||||||||||||||||||||||||||||
mockLogger = createMockLevelLogger(); | ||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
afterEach(() => { | ||||||||||||||||||||||||||||||||||||||
|
@@ -37,19 +39,12 @@ describe('Reporting server createConfig$', () => { | |||||||||||||||||||||||||||||||||||||
...createMockConfigSchema({ kibanaServer: {} }), | ||||||||||||||||||||||||||||||||||||||
encryptionKey: undefined, | ||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||
const mockConfig$: any = mockInitContext.config.create(); | ||||||||||||||||||||||||||||||||||||||
const mockConfig$ = createMockConfig(mockInitContext); | ||||||||||||||||||||||||||||||||||||||
const result = await createConfig$(mockCoreSetup, mockConfig$, mockLogger).toPromise(); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
expect(result.encryptionKey).toMatch(/\S{32,}/); // random 32 characters | ||||||||||||||||||||||||||||||||||||||
expect(result.kibanaServer).toMatchInlineSnapshot(` | ||||||||||||||||||||||||||||||||||||||
Object { | ||||||||||||||||||||||||||||||||||||||
"hostname": "localhost", | ||||||||||||||||||||||||||||||||||||||
"port": 80, | ||||||||||||||||||||||||||||||||||||||
"protocol": "http", | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
`); | ||||||||||||||||||||||||||||||||||||||
expect((mockLogger.warn as any).mock.calls.length).toBe(1); | ||||||||||||||||||||||||||||||||||||||
expect((mockLogger.warn as any).mock.calls[0]).toMatchObject([ | ||||||||||||||||||||||||||||||||||||||
expect(mockLogger.warn.mock.calls.length).toBe(1); | ||||||||||||||||||||||||||||||||||||||
expect(mockLogger.warn.mock.calls[0]).toMatchObject([ | ||||||||||||||||||||||||||||||||||||||
'Generating a random key for xpack.reporting.encryptionKey. To prevent sessions from being invalidated on restart, please set xpack.reporting.encryptionKey in the kibana.yml or use the bin/kibana-encryption-keys command.', | ||||||||||||||||||||||||||||||||||||||
]); | ||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||
|
@@ -60,10 +55,10 @@ describe('Reporting server createConfig$', () => { | |||||||||||||||||||||||||||||||||||||
encryptionKey: 'iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii', | ||||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||
const mockConfig$: any = mockInitContext.config.create(); | ||||||||||||||||||||||||||||||||||||||
const mockConfig$ = createMockConfig(mockInitContext); | ||||||||||||||||||||||||||||||||||||||
const result = await createConfig$(mockCoreSetup, mockConfig$, mockLogger).toPromise(); | ||||||||||||||||||||||||||||||||||||||
expect(result.encryptionKey).toMatch('iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii'); | ||||||||||||||||||||||||||||||||||||||
expect((mockLogger.warn as any).mock.calls.length).toBe(0); | ||||||||||||||||||||||||||||||||||||||
expect(mockLogger.warn.mock.calls.length).toBe(0); | ||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
it('uses the user-provided encryption key, reporting kibanaServer settings to override server info', async () => { | ||||||||||||||||||||||||||||||||||||||
|
@@ -77,7 +72,7 @@ describe('Reporting server createConfig$', () => { | |||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||
const mockConfig$: any = mockInitContext.config.create(); | ||||||||||||||||||||||||||||||||||||||
const mockConfig$ = createMockConfig(mockInitContext); | ||||||||||||||||||||||||||||||||||||||
const result = await createConfig$(mockCoreSetup, mockConfig$, mockLogger).toPromise(); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
expect(result).toMatchInlineSnapshot(` | ||||||||||||||||||||||||||||||||||||||
|
@@ -108,7 +103,7 @@ describe('Reporting server createConfig$', () => { | |||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
`); | ||||||||||||||||||||||||||||||||||||||
expect((mockLogger.warn as any).mock.calls.length).toBe(0); | ||||||||||||||||||||||||||||||||||||||
expect(mockLogger.warn.mock.calls.length).toBe(0); | ||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
it('uses user-provided disableSandbox: false', async () => { | ||||||||||||||||||||||||||||||||||||||
|
@@ -118,11 +113,11 @@ describe('Reporting server createConfig$', () => { | |||||||||||||||||||||||||||||||||||||
capture: { browser: { chromium: { disableSandbox: false } } }, | ||||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||
const mockConfig$: any = mockInitContext.config.create(); | ||||||||||||||||||||||||||||||||||||||
const mockConfig$ = createMockConfig(mockInitContext); | ||||||||||||||||||||||||||||||||||||||
const result = await createConfig$(mockCoreSetup, mockConfig$, mockLogger).toPromise(); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
expect(result.capture.browser.chromium).toMatchObject({ disableSandbox: false }); | ||||||||||||||||||||||||||||||||||||||
expect((mockLogger.warn as any).mock.calls.length).toBe(0); | ||||||||||||||||||||||||||||||||||||||
expect(mockLogger.warn.mock.calls.length).toBe(0); | ||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
it('uses user-provided disableSandbox: true', async () => { | ||||||||||||||||||||||||||||||||||||||
|
@@ -132,11 +127,11 @@ describe('Reporting server createConfig$', () => { | |||||||||||||||||||||||||||||||||||||
capture: { browser: { chromium: { disableSandbox: true } } }, | ||||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||
const mockConfig$: any = mockInitContext.config.create(); | ||||||||||||||||||||||||||||||||||||||
const mockConfig$ = createMockConfig(mockInitContext); | ||||||||||||||||||||||||||||||||||||||
const result = await createConfig$(mockCoreSetup, mockConfig$, mockLogger).toPromise(); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
expect(result.capture.browser.chromium).toMatchObject({ disableSandbox: true }); | ||||||||||||||||||||||||||||||||||||||
expect((mockLogger.warn as any).mock.calls.length).toBe(0); | ||||||||||||||||||||||||||||||||||||||
expect(mockLogger.warn.mock.calls.length).toBe(0); | ||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
it('provides a default for disableSandbox', async () => { | ||||||||||||||||||||||||||||||||||||||
|
@@ -145,10 +140,49 @@ describe('Reporting server createConfig$', () => { | |||||||||||||||||||||||||||||||||||||
encryptionKey: '888888888888888888888888888888888', | ||||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||
const mockConfig$: any = mockInitContext.config.create(); | ||||||||||||||||||||||||||||||||||||||
const mockConfig$ = createMockConfig(mockInitContext); | ||||||||||||||||||||||||||||||||||||||
const result = await createConfig$(mockCoreSetup, mockConfig$, mockLogger).toPromise(); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
expect(result.capture.browser.chromium).toMatchObject({ disableSandbox: expect.any(Boolean) }); | ||||||||||||||||||||||||||||||||||||||
expect((mockLogger.warn as any).mock.calls.length).toBe(0); | ||||||||||||||||||||||||||||||||||||||
expect(mockLogger.warn.mock.calls.length).toBe(0); | ||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
for (const hostname of [ | ||||||||||||||||||||||||||||||||||||||
'0', | ||||||||||||||||||||||||||||||||||||||
'0.0', | ||||||||||||||||||||||||||||||||||||||
'0.0.0', | ||||||||||||||||||||||||||||||||||||||
'0.0.0.0', | ||||||||||||||||||||||||||||||||||||||
'0000:0000:0000:0000:0000:0000:0000:0000', | ||||||||||||||||||||||||||||||||||||||
'::', | ||||||||||||||||||||||||||||||||||||||
]) { | ||||||||||||||||||||||||||||||||||||||
it(`apply failover logic when hostname is given as ${hostname}`, async () => { | ||||||||||||||||||||||||||||||||||||||
Comment on lines
+150
to
+158
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Jest provides tooling for such cases. Please use
Suggested change
|
||||||||||||||||||||||||||||||||||||||
mockInitContext = coreMock.createPluginInitializerContext( | ||||||||||||||||||||||||||||||||||||||
createMockConfigSchema({ | ||||||||||||||||||||||||||||||||||||||
encryptionKey: 'aaaaaaaaaaaaabbbbbbbbbbbbaaaaaaaaa', | ||||||||||||||||||||||||||||||||||||||
// overwrite settings added by createMockConfigSchema and apply the default settings | ||||||||||||||||||||||||||||||||||||||
// TODO make createMockConfigSchema _not_ default xpack.reporting.kibanaServer.hostname to 'localhost' | ||||||||||||||||||||||||||||||||||||||
kibanaServer: { | ||||||||||||||||||||||||||||||||||||||
hostname: undefined, | ||||||||||||||||||||||||||||||||||||||
port: undefined, | ||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||
mockCoreSetup.http.getServerInfo = jest.fn().mockImplementation( | ||||||||||||||||||||||||||||||||||||||
(): HttpServerInfo => ({ | ||||||||||||||||||||||||||||||||||||||
name: 'cool server', | ||||||||||||||||||||||||||||||||||||||
hostname, | ||||||||||||||||||||||||||||||||||||||
port: 5601, | ||||||||||||||||||||||||||||||||||||||
protocol: 'http', | ||||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||
Comment on lines
+170
to
+177
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could be simplified a bit.
Suggested change
|
||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
const mockConfig$ = createMockConfig(mockInitContext); | ||||||||||||||||||||||||||||||||||||||
const result = await createConfig$(mockCoreSetup, mockConfig$, mockLogger).toPromise(); | ||||||||||||||||||||||||||||||||||||||
expect(result.kibanaServer).toMatchObject({ | ||||||||||||||||||||||||||||||||||||||
hostname: 'localhost', | ||||||||||||||||||||||||||||||||||||||
port: 5601, | ||||||||||||||||||||||||||||||||||||||
protocol: 'http', | ||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||
Comment on lines
+180
to
+185
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it would be better to check that the promise is resolved and the result is not empty and has the property. In case when the test fails, jest can provide additional logging of where exactly it went wrong (e.g. promises rejects or empty result).
Suggested change
|
||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
}); |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -288,11 +288,25 @@ describe('Reporting Config Schema', () => { | |||||||||||||||||||||||||||||||||||||||||||||||||||
`); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
it(`logs the proper validation messages`, () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
// kibanaServer | ||||||||||||||||||||||||||||||||||||||||||||||||||||
const throwValidationErr = () => ConfigSchema.validate({ kibanaServer: { hostname: '0' } }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
expect(throwValidationErr).toThrowError( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
`[kibanaServer.hostname]: value must be a valid hostname (see RFC 1123).` | ||||||||||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
for (const address of ['0', '0.0', '0.0.0']) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
it(`fails to validate "kibanaServer.hostname" with an invalid hostname: "${address}"`, () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
expect(() => | ||||||||||||||||||||||||||||||||||||||||||||||||||||
ConfigSchema.validate({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
kibanaServer: { hostname: address }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
).toThrowError(`[kibanaServer.hostname]: value must be a valid hostname (see RFC 1123).`); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+291
to
+299
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
for (const address of ['0.0.0.0', '0000:0000:0000:0000:0000:0000:0000:0000', '::']) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
it(`fails to validate "kibanaServer.hostname" hostname as zero: "${address}"`, () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
expect(() => | ||||||||||||||||||||||||||||||||||||||||||||||||||||
ConfigSchema.validate({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
kibanaServer: { hostname: address }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
).toThrowError( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
`[kibanaServer.hostname]: cannot use '0.0.0.0' as Kibana host name, consider using the default (localhost) instead` | ||||||||||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+301
to
+311
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
}); |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -6,10 +6,22 @@ | |||||
*/ | ||||||
|
||||||
import { ByteSizeValue, schema, TypeOf } from '@kbn/config-schema'; | ||||||
import ipaddr from 'ipaddr.js'; | ||||||
import { sum } from 'lodash'; | ||||||
import moment from 'moment'; | ||||||
|
||||||
const KibanaServerSchema = schema.object({ | ||||||
hostname: schema.maybe(schema.string({ hostname: true })), | ||||||
hostname: schema.maybe( | ||||||
schema.string({ | ||||||
hostname: true, | ||||||
validate(value) { | ||||||
if (ipaddr.isValid(value) && !sum(ipaddr.parse(value).toByteArray())) { | ||||||
// prevent setting a hostname that fails in Chromium on Windows | ||||||
return `cannot use '0.0.0.0' as Kibana host name, consider using the default (localhost) instead`; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we substitute the actual value here? It is going to be a valid IP address, so that it should not print anything insecure.
Suggested change
|
||||||
} | ||||||
}, | ||||||
}) | ||||||
), | ||||||
port: schema.maybe(schema.number()), | ||||||
protocol: schema.maybe( | ||||||
schema.string({ | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand that the change was about removing the
any
. Since I have more relevant feedback below, maybe we can commit the following to prettify the code even more.