@@ -23,19 +23,32 @@ import {
2323 mockReadPkcs12Truststore ,
2424} from './elasticsearch_config.test.mocks' ;
2525
26- import { ElasticsearchConfig , config , ElasticsearchConfigType } from './elasticsearch_config' ;
27- import { loggingServiceMock } from '../mocks' ;
28- import { Logger } from '../logging' ;
29-
30- const createElasticsearchConfig = ( rawConfig : ElasticsearchConfigType , log ?: Logger ) => {
31- if ( ! log ) {
32- log = loggingServiceMock . create ( ) . get ( 'config' ) ;
33- }
34- return new ElasticsearchConfig ( rawConfig , log ) ;
26+ import { ElasticsearchConfig , config } from './elasticsearch_config' ;
27+ import { applyDeprecations , configDeprecationFactory } from '../config/deprecation' ;
28+
29+ const CONFIG_PATH = 'elasticsearch' ;
30+
31+ const applyElasticsearchDeprecations = ( settings : Record < string , any > = { } ) => {
32+ const deprecations = config . deprecations ! ( configDeprecationFactory ) ;
33+ const deprecationMessages : string [ ] = [ ] ;
34+ const _config : any = { } ;
35+ _config [ CONFIG_PATH ] = settings ;
36+ const migrated = applyDeprecations (
37+ _config ,
38+ deprecations . map ( deprecation => ( {
39+ deprecation,
40+ path : CONFIG_PATH ,
41+ } ) ) ,
42+ msg => deprecationMessages . push ( msg )
43+ ) ;
44+ return {
45+ messages : deprecationMessages ,
46+ migrated,
47+ } ;
3548} ;
3649
3750test ( 'set correct defaults' , ( ) => {
38- const configValue = createElasticsearchConfig ( config . schema . validate ( { } ) ) ;
51+ const configValue = new ElasticsearchConfig ( config . schema . validate ( { } ) ) ;
3952 expect ( configValue ) . toMatchInlineSnapshot ( `
4053 ElasticsearchConfig {
4154 "apiVersion": "master",
@@ -70,17 +83,17 @@ test('set correct defaults', () => {
7083} ) ;
7184
7285test ( '#hosts accepts both string and array of strings' , ( ) => {
73- let configValue = createElasticsearchConfig (
86+ let configValue = new ElasticsearchConfig (
7487 config . schema . validate ( { hosts : 'http://some.host:1234' } )
7588 ) ;
7689 expect ( configValue . hosts ) . toEqual ( [ 'http://some.host:1234' ] ) ;
7790
78- configValue = createElasticsearchConfig (
91+ configValue = new ElasticsearchConfig (
7992 config . schema . validate ( { hosts : [ 'http://some.host:1234' ] } )
8093 ) ;
8194 expect ( configValue . hosts ) . toEqual ( [ 'http://some.host:1234' ] ) ;
8295
83- configValue = createElasticsearchConfig (
96+ configValue = new ElasticsearchConfig (
8497 config . schema . validate ( {
8598 hosts : [ 'http://some.host:1234' , 'https://some.another.host' ] ,
8699 } )
@@ -89,17 +102,17 @@ test('#hosts accepts both string and array of strings', () => {
89102} ) ;
90103
91104test ( '#requestHeadersWhitelist accepts both string and array of strings' , ( ) => {
92- let configValue = createElasticsearchConfig (
105+ let configValue = new ElasticsearchConfig (
93106 config . schema . validate ( { requestHeadersWhitelist : 'token' } )
94107 ) ;
95108 expect ( configValue . requestHeadersWhitelist ) . toEqual ( [ 'token' ] ) ;
96109
97- configValue = createElasticsearchConfig (
110+ configValue = new ElasticsearchConfig (
98111 config . schema . validate ( { requestHeadersWhitelist : [ 'token' ] } )
99112 ) ;
100113 expect ( configValue . requestHeadersWhitelist ) . toEqual ( [ 'token' ] ) ;
101114
102- configValue = createElasticsearchConfig (
115+ configValue = new ElasticsearchConfig (
103116 config . schema . validate ( {
104117 requestHeadersWhitelist : [ 'token' , 'X-Forwarded-Proto' ] ,
105118 } )
@@ -122,37 +135,37 @@ describe('reads files', () => {
122135 } ) ;
123136
124137 it ( 'reads certificate authorities when ssl.keystore.path is specified' , ( ) => {
125- const configValue = createElasticsearchConfig (
138+ const configValue = new ElasticsearchConfig (
126139 config . schema . validate ( { ssl : { keystore : { path : 'some-path' } } } )
127140 ) ;
128141 expect ( mockReadPkcs12Keystore ) . toHaveBeenCalledTimes ( 1 ) ;
129142 expect ( configValue . ssl . certificateAuthorities ) . toEqual ( [ 'content-of-some-path.ca' ] ) ;
130143 } ) ;
131144
132145 it ( 'reads certificate authorities when ssl.truststore.path is specified' , ( ) => {
133- const configValue = createElasticsearchConfig (
146+ const configValue = new ElasticsearchConfig (
134147 config . schema . validate ( { ssl : { truststore : { path : 'some-path' } } } )
135148 ) ;
136149 expect ( mockReadPkcs12Truststore ) . toHaveBeenCalledTimes ( 1 ) ;
137150 expect ( configValue . ssl . certificateAuthorities ) . toEqual ( [ 'content-of-some-path' ] ) ;
138151 } ) ;
139152
140153 it ( 'reads certificate authorities when ssl.certificateAuthorities is specified' , ( ) => {
141- let configValue = createElasticsearchConfig (
154+ let configValue = new ElasticsearchConfig (
142155 config . schema . validate ( { ssl : { certificateAuthorities : 'some-path' } } )
143156 ) ;
144157 expect ( mockReadFileSync ) . toHaveBeenCalledTimes ( 1 ) ;
145158 expect ( configValue . ssl . certificateAuthorities ) . toEqual ( [ 'content-of-some-path' ] ) ;
146159
147160 mockReadFileSync . mockClear ( ) ;
148- configValue = createElasticsearchConfig (
161+ configValue = new ElasticsearchConfig (
149162 config . schema . validate ( { ssl : { certificateAuthorities : [ 'some-path' ] } } )
150163 ) ;
151164 expect ( mockReadFileSync ) . toHaveBeenCalledTimes ( 1 ) ;
152165 expect ( configValue . ssl . certificateAuthorities ) . toEqual ( [ 'content-of-some-path' ] ) ;
153166
154167 mockReadFileSync . mockClear ( ) ;
155- configValue = createElasticsearchConfig (
168+ configValue = new ElasticsearchConfig (
156169 config . schema . validate ( {
157170 ssl : { certificateAuthorities : [ 'some-path' , 'another-path' ] } ,
158171 } )
@@ -165,7 +178,7 @@ describe('reads files', () => {
165178 } ) ;
166179
167180 it ( 'reads certificate authorities when ssl.keystore.path, ssl.truststore.path, and ssl.certificateAuthorities are specified' , ( ) => {
168- const configValue = createElasticsearchConfig (
181+ const configValue = new ElasticsearchConfig (
169182 config . schema . validate ( {
170183 ssl : {
171184 keystore : { path : 'some-path' } ,
@@ -185,7 +198,7 @@ describe('reads files', () => {
185198 } ) ;
186199
187200 it ( 'reads a private key and certificate when ssl.keystore.path is specified' , ( ) => {
188- const configValue = createElasticsearchConfig (
201+ const configValue = new ElasticsearchConfig (
189202 config . schema . validate ( { ssl : { keystore : { path : 'some-path' } } } )
190203 ) ;
191204 expect ( mockReadPkcs12Keystore ) . toHaveBeenCalledTimes ( 1 ) ;
@@ -194,15 +207,15 @@ describe('reads files', () => {
194207 } ) ;
195208
196209 it ( 'reads a private key when ssl.key is specified' , ( ) => {
197- const configValue = createElasticsearchConfig (
210+ const configValue = new ElasticsearchConfig (
198211 config . schema . validate ( { ssl : { key : 'some-path' } } )
199212 ) ;
200213 expect ( mockReadFileSync ) . toHaveBeenCalledTimes ( 1 ) ;
201214 expect ( configValue . ssl . key ) . toEqual ( 'content-of-some-path' ) ;
202215 } ) ;
203216
204217 it ( 'reads a certificate when ssl.certificate is specified' , ( ) => {
205- const configValue = createElasticsearchConfig (
218+ const configValue = new ElasticsearchConfig (
206219 config . schema . validate ( { ssl : { certificate : 'some-path' } } )
207220 ) ;
208221 expect ( mockReadFileSync ) . toHaveBeenCalledTimes ( 1 ) ;
@@ -225,52 +238,58 @@ describe('throws when config is invalid', () => {
225238
226239 it ( 'throws if key is invalid' , ( ) => {
227240 const value = { ssl : { key : '/invalid/key' } } ;
228- expect ( ( ) =>
229- createElasticsearchConfig ( config . schema . validate ( value ) )
241+ expect (
242+ ( ) => new ElasticsearchConfig ( config . schema . validate ( value ) )
230243 ) . toThrowErrorMatchingInlineSnapshot (
231244 `"ENOENT: no such file or directory, open '/invalid/key'"`
232245 ) ;
233246 } ) ;
234247
235248 it ( 'throws if certificate is invalid' , ( ) => {
236249 const value = { ssl : { certificate : '/invalid/cert' } } ;
237- expect ( ( ) =>
238- createElasticsearchConfig ( config . schema . validate ( value ) )
250+ expect (
251+ ( ) => new ElasticsearchConfig ( config . schema . validate ( value ) )
239252 ) . toThrowErrorMatchingInlineSnapshot (
240253 `"ENOENT: no such file or directory, open '/invalid/cert'"`
241254 ) ;
242255 } ) ;
243256
244257 it ( 'throws if certificateAuthorities is invalid' , ( ) => {
245258 const value = { ssl : { certificateAuthorities : '/invalid/ca' } } ;
246- expect ( ( ) =>
247- createElasticsearchConfig ( config . schema . validate ( value ) )
259+ expect (
260+ ( ) => new ElasticsearchConfig ( config . schema . validate ( value ) )
248261 ) . toThrowErrorMatchingInlineSnapshot ( `"ENOENT: no such file or directory, open '/invalid/ca'"` ) ;
249262 } ) ;
250263
251264 it ( 'throws if keystore path is invalid' , ( ) => {
252265 const value = { ssl : { keystore : { path : '/invalid/keystore' } } } ;
253- expect ( ( ) =>
254- createElasticsearchConfig ( config . schema . validate ( value ) )
266+ expect (
267+ ( ) => new ElasticsearchConfig ( config . schema . validate ( value ) )
255268 ) . toThrowErrorMatchingInlineSnapshot (
256269 `"ENOENT: no such file or directory, open '/invalid/keystore'"`
257270 ) ;
258271 } ) ;
259272
260- it ( 'throws if keystore does not contain a key or certificate ' , ( ) => {
273+ it ( 'throws if keystore does not contain a key' , ( ) => {
261274 mockReadPkcs12Keystore . mockReturnValueOnce ( { } ) ;
262275 const value = { ssl : { keystore : { path : 'some-path' } } } ;
263- expect ( ( ) =>
264- createElasticsearchConfig ( config . schema . validate ( value ) )
265- ) . toThrowErrorMatchingInlineSnapshot (
266- `"Did not find key or certificate in Elasticsearch keystore."`
267- ) ;
276+ expect (
277+ ( ) => new ElasticsearchConfig ( config . schema . validate ( value ) )
278+ ) . toThrowErrorMatchingInlineSnapshot ( `"Did not find key in Elasticsearch keystore."` ) ;
279+ } ) ;
280+
281+ it ( 'throws if keystore does not contain a certificate' , ( ) => {
282+ mockReadPkcs12Keystore . mockReturnValueOnce ( { key : 'foo' } ) ;
283+ const value = { ssl : { keystore : { path : 'some-path' } } } ;
284+ expect (
285+ ( ) => new ElasticsearchConfig ( config . schema . validate ( value ) )
286+ ) . toThrowErrorMatchingInlineSnapshot ( `"Did not find certificate in Elasticsearch keystore."` ) ;
268287 } ) ;
269288
270289 it ( 'throws if truststore path is invalid' , ( ) => {
271290 const value = { ssl : { keystore : { path : '/invalid/truststore' } } } ;
272- expect ( ( ) =>
273- createElasticsearchConfig ( config . schema . validate ( value ) )
291+ expect (
292+ ( ) => new ElasticsearchConfig ( config . schema . validate ( value ) )
274293 ) . toThrowErrorMatchingInlineSnapshot (
275294 `"ENOENT: no such file or directory, open '/invalid/truststore'"`
276295 ) ;
@@ -291,31 +310,47 @@ describe('throws when config is invalid', () => {
291310 } ) ;
292311} ) ;
293312
294- describe ( 'logs warnings' , ( ) => {
295- let logger : ReturnType < typeof loggingServiceMock . create > ;
296- let log : Logger ;
313+ describe ( 'deprecations' , ( ) => {
314+ it ( 'logs a warning if elasticsearch.username is set to "elastic"' , ( ) => {
315+ const { messages } = applyElasticsearchDeprecations ( { username : 'elastic' } ) ;
316+ expect ( messages ) . toMatchInlineSnapshot ( `
317+ Array [
318+ "Setting [${ CONFIG_PATH } .username] to \\"elastic\\" is deprecated. You should use the \\"kibana\\" user instead.",
319+ ]
320+ ` ) ;
321+ } ) ;
297322
298- beforeAll ( ( ) => {
299- mockReadFileSync . mockResolvedValue ( 'foo' ) ;
323+ it ( 'does not log a warning if elasticsearch.username is set to something besides "elastic"' , ( ) => {
324+ const { messages } = applyElasticsearchDeprecations ( { username : 'otheruser' } ) ;
325+ expect ( messages ) . toHaveLength ( 0 ) ;
300326 } ) ;
301327
302- beforeEach ( ( ) => {
303- logger = loggingServiceMock . create ( ) ;
304- log = logger . get ( 'config' ) ;
328+ it ( 'does not log a warning if elasticsearch.username is unset' , ( ) => {
329+ const { messages } = applyElasticsearchDeprecations ( { } ) ;
330+ expect ( messages ) . toHaveLength ( 0 ) ;
305331 } ) ;
306332
307- it ( 'warns if ssl.key is set and ssl.certificate is not' , ( ) => {
308- createElasticsearchConfig ( config . schema . validate ( { ssl : { key : 'some-path' } } ) , log ) ;
309- expect ( loggingServiceMock . collect ( logger ) . warn [ 0 ] [ 0 ] ) . toMatchInlineSnapshot (
310- `"Detected a key without a certificate; mutual TLS authentication is disabled."`
311- ) ;
333+ it ( 'logs a warning if ssl.key is set and ssl.certificate is not' , ( ) => {
334+ const { messages } = applyElasticsearchDeprecations ( { ssl : { key : '' } } ) ;
335+ expect ( messages ) . toMatchInlineSnapshot ( `
336+ Array [
337+ "Setting [${ CONFIG_PATH } .ssl.key] without [${ CONFIG_PATH } .ssl.certificate] is deprecated. This has no effect, you should use both settings to enable TLS client authentication to Elasticsearch.",
338+ ]
339+ ` ) ;
312340 } ) ;
313341
314- it ( 'warns if ssl.certificate is set and ssl.key is not' , ( ) => {
315- createElasticsearchConfig ( config . schema . validate ( { ssl : { certificate : 'some-path' } } ) , log ) ;
316- expect ( loggingServiceMock . collect ( logger ) . warn [ 0 ] [ 0 ] ) . toMatchInlineSnapshot (
317- `"Detected a certificate without a key; mutual TLS authentication is disabled."`
318- ) ;
342+ it ( 'logs a warning if ssl.certificate is set and ssl.key is not' , ( ) => {
343+ const { messages } = applyElasticsearchDeprecations ( { ssl : { certificate : '' } } ) ;
344+ expect ( messages ) . toMatchInlineSnapshot ( `
345+ Array [
346+ "Setting [${ CONFIG_PATH } .ssl.certificate] without [${ CONFIG_PATH } .ssl.key] is deprecated. This has no effect, you should use both settings to enable TLS client authentication to Elasticsearch.",
347+ ]
348+ ` ) ;
349+ } ) ;
350+
351+ it ( 'does not log a warning if both ssl.key and ssl.certificate are set' , ( ) => {
352+ const { messages } = applyElasticsearchDeprecations ( { ssl : { key : '' , certificate : '' } } ) ;
353+ expect ( messages ) . toEqual ( [ ] ) ;
319354 } ) ;
320355} ) ;
321356
0 commit comments