logstash-output-elasticsearch-test 11.16.0-x86_64-linux

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +649 -0
  3. data/CONTRIBUTORS +34 -0
  4. data/Gemfile +16 -0
  5. data/LICENSE +202 -0
  6. data/NOTICE.TXT +5 -0
  7. data/README.md +106 -0
  8. data/docs/index.asciidoc +1369 -0
  9. data/lib/logstash/outputs/elasticsearch/data_stream_support.rb +282 -0
  10. data/lib/logstash/outputs/elasticsearch/default-ilm-policy.json +14 -0
  11. data/lib/logstash/outputs/elasticsearch/http_client/manticore_adapter.rb +155 -0
  12. data/lib/logstash/outputs/elasticsearch/http_client/pool.rb +534 -0
  13. data/lib/logstash/outputs/elasticsearch/http_client.rb +497 -0
  14. data/lib/logstash/outputs/elasticsearch/http_client_builder.rb +201 -0
  15. data/lib/logstash/outputs/elasticsearch/ilm.rb +92 -0
  16. data/lib/logstash/outputs/elasticsearch/license_checker.rb +52 -0
  17. data/lib/logstash/outputs/elasticsearch/template_manager.rb +131 -0
  18. data/lib/logstash/outputs/elasticsearch/templates/ecs-disabled/elasticsearch-6x.json +45 -0
  19. data/lib/logstash/outputs/elasticsearch/templates/ecs-disabled/elasticsearch-7x.json +44 -0
  20. data/lib/logstash/outputs/elasticsearch/templates/ecs-disabled/elasticsearch-8x.json +50 -0
  21. data/lib/logstash/outputs/elasticsearch.rb +699 -0
  22. data/lib/logstash/plugin_mixins/elasticsearch/api_configs.rb +237 -0
  23. data/lib/logstash/plugin_mixins/elasticsearch/common.rb +409 -0
  24. data/lib/logstash/plugin_mixins/elasticsearch/noop_license_checker.rb +9 -0
  25. data/logstash-output-elasticsearch.gemspec +40 -0
  26. data/spec/es_spec_helper.rb +225 -0
  27. data/spec/fixtures/_nodes/6x.json +81 -0
  28. data/spec/fixtures/_nodes/7x.json +92 -0
  29. data/spec/fixtures/htpasswd +2 -0
  30. data/spec/fixtures/license_check/active.json +16 -0
  31. data/spec/fixtures/license_check/inactive.json +5 -0
  32. data/spec/fixtures/nginx_reverse_proxy.conf +22 -0
  33. data/spec/fixtures/scripts/painless/scripted_update.painless +2 -0
  34. data/spec/fixtures/scripts/painless/scripted_update_nested.painless +1 -0
  35. data/spec/fixtures/scripts/painless/scripted_upsert.painless +1 -0
  36. data/spec/fixtures/template-with-policy-es6x.json +48 -0
  37. data/spec/fixtures/template-with-policy-es7x.json +45 -0
  38. data/spec/fixtures/template-with-policy-es8x.json +50 -0
  39. data/spec/fixtures/test_certs/ca.crt +29 -0
  40. data/spec/fixtures/test_certs/ca.der.sha256 +1 -0
  41. data/spec/fixtures/test_certs/ca.key +51 -0
  42. data/spec/fixtures/test_certs/renew.sh +13 -0
  43. data/spec/fixtures/test_certs/test.crt +30 -0
  44. data/spec/fixtures/test_certs/test.der.sha256 +1 -0
  45. data/spec/fixtures/test_certs/test.key +51 -0
  46. data/spec/fixtures/test_certs/test.p12 +0 -0
  47. data/spec/fixtures/test_certs/test_invalid.crt +36 -0
  48. data/spec/fixtures/test_certs/test_invalid.key +51 -0
  49. data/spec/fixtures/test_certs/test_invalid.p12 +0 -0
  50. data/spec/fixtures/test_certs/test_self_signed.crt +32 -0
  51. data/spec/fixtures/test_certs/test_self_signed.key +54 -0
  52. data/spec/fixtures/test_certs/test_self_signed.p12 +0 -0
  53. data/spec/integration/outputs/compressed_indexing_spec.rb +70 -0
  54. data/spec/integration/outputs/create_spec.rb +67 -0
  55. data/spec/integration/outputs/data_stream_spec.rb +68 -0
  56. data/spec/integration/outputs/delete_spec.rb +63 -0
  57. data/spec/integration/outputs/ilm_spec.rb +534 -0
  58. data/spec/integration/outputs/index_spec.rb +421 -0
  59. data/spec/integration/outputs/index_version_spec.rb +98 -0
  60. data/spec/integration/outputs/ingest_pipeline_spec.rb +75 -0
  61. data/spec/integration/outputs/metrics_spec.rb +66 -0
  62. data/spec/integration/outputs/no_es_on_startup_spec.rb +78 -0
  63. data/spec/integration/outputs/painless_update_spec.rb +99 -0
  64. data/spec/integration/outputs/parent_spec.rb +94 -0
  65. data/spec/integration/outputs/retry_spec.rb +182 -0
  66. data/spec/integration/outputs/routing_spec.rb +61 -0
  67. data/spec/integration/outputs/sniffer_spec.rb +94 -0
  68. data/spec/integration/outputs/templates_spec.rb +133 -0
  69. data/spec/integration/outputs/unsupported_actions_spec.rb +75 -0
  70. data/spec/integration/outputs/update_spec.rb +114 -0
  71. data/spec/spec_helper.rb +10 -0
  72. data/spec/support/elasticsearch/api/actions/delete_ilm_policy.rb +19 -0
  73. data/spec/support/elasticsearch/api/actions/get_alias.rb +18 -0
  74. data/spec/support/elasticsearch/api/actions/get_ilm_policy.rb +18 -0
  75. data/spec/support/elasticsearch/api/actions/put_alias.rb +24 -0
  76. data/spec/support/elasticsearch/api/actions/put_ilm_policy.rb +25 -0
  77. data/spec/unit/http_client_builder_spec.rb +185 -0
  78. data/spec/unit/outputs/elasticsearch/data_stream_support_spec.rb +612 -0
  79. data/spec/unit/outputs/elasticsearch/http_client/manticore_adapter_spec.rb +151 -0
  80. data/spec/unit/outputs/elasticsearch/http_client/pool_spec.rb +501 -0
  81. data/spec/unit/outputs/elasticsearch/http_client_spec.rb +339 -0
  82. data/spec/unit/outputs/elasticsearch/template_manager_spec.rb +189 -0
  83. data/spec/unit/outputs/elasticsearch_proxy_spec.rb +103 -0
  84. data/spec/unit/outputs/elasticsearch_spec.rb +1573 -0
  85. data/spec/unit/outputs/elasticsearch_ssl_spec.rb +197 -0
  86. data/spec/unit/outputs/error_whitelist_spec.rb +56 -0
  87. data/spec/unit/outputs/license_check_spec.rb +57 -0
  88. metadata +423 -0
@@ -0,0 +1,612 @@
1
+ require_relative '../../../../spec/spec_helper'
2
+ require "logstash/outputs/elasticsearch/data_stream_support"
3
+
4
+ describe LogStash::Outputs::ElasticSearch::DataStreamSupport do
5
+
6
+ subject { LogStash::Outputs::ElasticSearch.new(options) }
7
+
8
+ let(:options) { { 'hosts' => [ 'localhost:12345' ] } }
9
+ let(:es_version) { '7.10.1' }
10
+
11
+ # All data-streams features require that the plugin be run in a non-disabled ECS compatibility mode.
12
+ # We run the plugin in ECS by default, and add test scenarios specifically for it being disabled.
13
+ let(:ecs_compatibility) { :v1 }
14
+ before(:each) do
15
+ allow_any_instance_of(LogStash::Outputs::ElasticSearch).to receive(:ecs_compatibility).and_return(ecs_compatibility)
16
+ end
17
+
18
+ let(:do_register) { false }
19
+ let(:stub_plugin_register!) do
20
+ allow(subject).to receive(:last_es_version).and_return(es_version)
21
+
22
+ allow_any_instance_of(LogStash::Outputs::ElasticSearch::HttpClient::Pool).to receive(:start)
23
+
24
+ # stub-out unrelated (finish_register) setup:
25
+ allow(subject).to receive(:discover_cluster_uuid)
26
+ allow(subject).to receive(:install_template)
27
+ allow(subject).to receive(:ilm_in_use?).and_return nil
28
+
29
+ # emulate 'successful' ES connection on the same thread
30
+ allow(subject).to receive(:after_successful_connection) { |&block| block.call }
31
+ allow(subject).to receive(:stop_after_successful_connection_thread)
32
+
33
+ subject.register
34
+
35
+ allow(subject.client).to receive(:maximum_seen_major_version).and_return(Integer(es_version.split('.').first))
36
+
37
+ # allow( subject.logger ).to receive(:info) do |msg|
38
+ # expect(msg).to include "New Elasticsearch output"
39
+ # end
40
+ end
41
+
42
+ before(:each) do
43
+ stub_plugin_register! if do_register
44
+ end
45
+
46
+ after(:each) do
47
+ subject.close if do_register
48
+ end
49
+
50
+ context "default configuration" do
51
+
52
+ let(:options) { {} }
53
+
54
+ before { allow(subject).to receive(:last_es_version).and_return(es_version) }
55
+
56
+ it "does not use data-streams on LS 7.x" do
57
+ change_constant :LOGSTASH_VERSION, '7.10.0' do
58
+ expect( subject.data_stream_config? ).to be false
59
+ end
60
+ end
61
+
62
+ it "warns when configuration is data-stream compliant (LS 7.x)" do
63
+ expect( subject.logger ).to receive(:warn).with(a_string_including "Configuration is data stream compliant but due backwards compatibility Logstash 7.x")
64
+ change_constant :LOGSTASH_VERSION, '7.11.0' do
65
+ expect( subject.data_stream_config? ).to be false
66
+ end
67
+ end
68
+
69
+ it "defaults to using data-streams on LS 8.0" do
70
+ change_constant :LOGSTASH_VERSION, '8.0.0' do
71
+ expect( subject.data_stream_config? ).to be true
72
+ end
73
+ end
74
+
75
+ context 'ecs_compatibility disabled' do
76
+ let(:ecs_compatibility) { :disabled }
77
+
78
+ {
79
+ '7.x (pre-DS)' => '7.9.0',
80
+ '7.x (with DS)' => '7.11.0',
81
+ '8.0' => '8.0.0',
82
+ '8.x' => '8.1.2',
83
+ }.each do |ls_version_desc, ls_version|
84
+ context "on LS #{ls_version_desc}" do
85
+ around(:each) { |example| change_constant(:LOGSTASH_VERSION, ls_version, &example) }
86
+ it "does not use data-streams" do
87
+ expect( subject.logger ).to receive(:info).with(a_string_including "ecs_compatibility is not enabled")
88
+ expect( subject.logger ).to receive(:info).with(a_string_including "Data streams auto configuration (`data_stream => auto` or unset) resolved to `false`")
89
+ expect( subject.data_stream_config? ).to be false
90
+ end
91
+ end
92
+ end
93
+ end
94
+
95
+ context 'non-compatible ES' do
96
+
97
+ let(:es_version) { '7.8.0' }
98
+
99
+ it "does not print an error (from after_successful_connection thread)" do
100
+ change_constant :LOGSTASH_VERSION, '7.8.1' do
101
+ expect( subject.logger ).to_not receive(:error)
102
+ expect( subject ).to receive(:finish_register).once.and_call_original
103
+ stub_plugin_register!
104
+ end
105
+ end
106
+
107
+ end
108
+
109
+ end
110
+
111
+ context "ds-compatible configuration" do
112
+
113
+ let(:options) do
114
+ {
115
+ 'hosts' => [ 'http://127.0.0.1:12345' ],
116
+ 'http_compression' => 'true', 'bulk_path' => '_bulk', 'timeout' => '30',
117
+ 'user' => 'elastic', 'password' => 'ForSearch!', 'ssl_enabled' => 'false'
118
+ }
119
+ end
120
+
121
+ before { allow(subject).to receive(:last_es_version).and_return(es_version) }
122
+
123
+ it "does not use data-streams on LS 7.x" do
124
+ expect( subject.logger ).to receive(:warn).with(a_string_including "Logstash 7.x will not assume writing to a data-stream")
125
+ change_constant :LOGSTASH_VERSION, '7.10.0' do
126
+ expect( subject.data_stream_config? ).to be false
127
+ end
128
+ end
129
+
130
+ it "defaults to using data-streams on LS 8.0" do
131
+ change_constant :LOGSTASH_VERSION, '8.0.1' do
132
+ expect( subject.data_stream_config? ).to be true
133
+ end
134
+ change_constant :LOGSTASH_VERSION, '8.1.0' do
135
+ expect( subject.send(:check_data_stream_config!) ).to be true
136
+ end
137
+ end
138
+
139
+ context 'old ES' do
140
+
141
+ let(:es_version) { '7.8.1' }
142
+
143
+ it "prints an error (from after_successful_connection thread) on LS 8.0" do
144
+ change_constant :LOGSTASH_VERSION, '8.0.0' do
145
+ expect( subject.logger ).to receive(:error).with(/Elasticsearch version does not support data streams/,
146
+ {:es_version=>"7.8.1"})
147
+ stub_plugin_register!
148
+ end
149
+ end
150
+
151
+ end
152
+
153
+ end
154
+
155
+ context 'ds value-dependent configuration' do
156
+ context 'with valid values' do
157
+ let(:options) { super().merge(
158
+ 'action' => 'create',
159
+ 'routing' => 'any',
160
+ 'pipeline' => 'any',
161
+ 'manage_template' => 'false',
162
+ 'data_stream' => 'true',
163
+ 'data_stream_type' => 'logs',
164
+ 'data_stream_dataset' => 'any',
165
+ 'data_stream_namespace' => 'any',
166
+ 'data_stream_sync_fields' => true,
167
+ 'data_stream_auto_routing' => true,
168
+ 'dlq_custom_codes' => [ 404 ],
169
+ 'dlq_on_failed_indexname_interpolation' => false)
170
+ }
171
+
172
+ it 'should enable data-streams by default' do
173
+ expect( subject.data_stream_config? ).to be_truthy
174
+ end
175
+ end
176
+
177
+ context 'with invalid values' do
178
+ let(:options) { super().merge(
179
+ 'data_stream' => 'true',
180
+ 'action' => 'index',
181
+ 'manage_template' => 'true')
182
+ }
183
+
184
+ it 'should raise a configuration error' do
185
+ expect { subject.data_stream_config? }.to raise_error(LogStash::ConfigurationError, 'Invalid data stream configuration: ["action", "manage_template"]')
186
+ end
187
+ end
188
+ end
189
+
190
+ context "default (non data-stream) configuration (on 7.x)" do
191
+
192
+ let(:options) do
193
+ { 'data_stream_dataset' => 'test', 'data_stream_auto_routing' => 'false', 'user' => 'elastic' }
194
+ end
195
+
196
+ before { allow(subject).to receive(:last_es_version).and_return(es_version) }
197
+
198
+ it "does not default to data-streams" do
199
+ expect( subject.logger ).to receive(:error) do |msg|
200
+ expect(msg).to include "Ambiguous configuration; data stream settings must not be present when data streams are disabled"
201
+ end
202
+ change_constant :LOGSTASH_VERSION, '7.10.2' do
203
+ expect { subject.data_stream_config? }.to raise_error(LogStash::ConfigurationError, /Ambiguous configuration/i)
204
+ end
205
+ end
206
+
207
+ context 'explicit data_stream => false' do
208
+
209
+ let(:options) { super().merge('data_stream' => 'false') }
210
+
211
+ it "raises a configuration error (due ds specific settings)" do
212
+ expect( subject.logger ).to receive(:error).with(/Ambiguous configuration; data stream settings must not be present when data streams are disabled/,
213
+ {"data_stream_auto_routing"=>"false", "data_stream_dataset"=>"test"})
214
+ change_constant :LOGSTASH_VERSION, '7.10.2' do
215
+ expect { subject.data_stream_config? }.to raise_error(LogStash::ConfigurationError, /Ambiguous configuration/i)
216
+ end
217
+ end
218
+
219
+ end
220
+
221
+ end
222
+
223
+ context "(explicit) ds disabled configuration" do
224
+
225
+ let(:options) { super().merge('data_stream' => false.to_s) }
226
+
227
+ before { allow(subject).to receive(:last_es_version).and_return(es_version) }
228
+
229
+ it "does not use data-streams on LS 7.x" do
230
+ change_constant :LOGSTASH_VERSION, '7.10.0' do
231
+ expect( subject.data_stream_config? ).to be false
232
+ end
233
+ end
234
+
235
+ it "does not use data-streams on LS 8.0" do
236
+ change_constant :LOGSTASH_VERSION, '8.0.0' do
237
+ expect( subject.data_stream_config? ).to be false
238
+ end
239
+ end
240
+
241
+ it "does not print a warning" do
242
+ expect( subject.logger ).to_not receive(:warn)
243
+ change_constant :LOGSTASH_VERSION, '7.10.2' do
244
+ expect( subject.data_stream_config? ).to be false
245
+ end
246
+ end
247
+
248
+ end
249
+
250
+ context "(explicit) ds enabled configuration" do
251
+
252
+ let(:options) { super().merge('data_stream' => true.to_s) }
253
+
254
+ before { allow(subject).to receive(:last_es_version).and_return(es_version) }
255
+
256
+ it "does use data-streams on LS 7.x" do
257
+ change_constant :LOGSTASH_VERSION, '7.9.1' do
258
+ expect( subject.data_stream_config? ).to be true
259
+ end
260
+ end
261
+
262
+ it "does use data-streams on LS 8.x" do
263
+ change_constant :LOGSTASH_VERSION, '8.1.0' do
264
+ expect( subject.data_stream_config? ).to be true
265
+ end
266
+ end
267
+
268
+ context 'with ecs_compatibility disabled' do
269
+ let(:ecs_compatibility) { :disabled }
270
+
271
+ context 'when running on LS 7.x' do
272
+ around(:each) { |example| change_constant(:LOGSTASH_VERSION, '7.15.1', &example) }
273
+
274
+ it "emits a deprecation warning and uses data streams anway" do
275
+ expect( subject.deprecation_logger ).to receive(:deprecated).with(a_string_including "`data_stream => true` will require the plugin to be run in ECS compatibility mode")
276
+ expect( subject.data_stream_config? ).to be true
277
+ end
278
+ end
279
+
280
+ context 'when running on LS 8.x' do
281
+ around(:each) { |example| change_constant(:LOGSTASH_VERSION, '8.0.0', &example) }
282
+
283
+ it "errors helpfully" do
284
+ expect{ subject.data_stream_config? }.to raise_error(LogStash::ConfigurationError, a_string_including("Invalid data stream configuration: `ecs_compatibility => disabled`"))
285
+ end
286
+ end
287
+
288
+ end
289
+
290
+ context 'non-compatible ES' do
291
+
292
+ let(:es_version) { '6.8.11' }
293
+
294
+ it "prints an error (from after_successful_connection thread) on LS 7.x" do
295
+ change_constant :LOGSTASH_VERSION, '7.12.0' do
296
+ expect( subject.logger ).to receive(:error).with(/Elasticsearch version does not support data streams/,
297
+ {:es_version=>"6.8.11"})
298
+ stub_plugin_register!
299
+ end
300
+ end
301
+
302
+ it "prints an error (from after_successful_connection thread) on LS 8.0" do
303
+ change_constant :LOGSTASH_VERSION, '8.0.5' do
304
+ expect( subject.logger ).to receive(:error).with(/Elasticsearch version does not support data streams/,
305
+ {:es_version=>"6.8.11"})
306
+ stub_plugin_register!
307
+ end
308
+ end
309
+
310
+ end
311
+
312
+ end
313
+
314
+ describe "auto routing" do
315
+
316
+ let(:options) { super().merge('data_stream' => 'true') }
317
+ let(:do_register) { true }
318
+
319
+ let(:event) do
320
+ event = LogStash::Event.new
321
+ event.set '[host][hostname]', 'orangutan'
322
+ event
323
+ end
324
+
325
+ context 'with data_stream.* event data' do
326
+
327
+ let(:event) do
328
+ super().tap do |event|
329
+ event.set '[data_stream][type]', 'metrics'
330
+ event.set '[data_stream][dataset]', 'src1'
331
+ event.set '[data_stream][namespace]', 'test'
332
+ end
333
+ end
334
+
335
+ it 'uses event specified target' do
336
+ tuple = subject.map_events([ event ]).first
337
+ expect( tuple.size ).to eql 3
338
+ expect( tuple[0] ).to eql 'create'
339
+ expect( tuple[1] ).to include :_index => 'metrics-src1-test'
340
+ end
341
+
342
+ end
343
+
344
+ context 'with routing turned off' do
345
+
346
+ let(:options) { super().merge('data_stream_auto_routing' => 'false') }
347
+
348
+ let(:event) do
349
+ super().tap do |event|
350
+ event.set '[data_stream][type]', 'metrics'
351
+ event.set '[data_stream][dataset]', 'src1'
352
+ event.set '[data_stream][namespace]', 'test'
353
+ end
354
+ end
355
+
356
+ it 'uses event specified target' do
357
+ tuple = subject.map_events([ event ]).first
358
+ expect( tuple.size ).to eql 3
359
+ expect( tuple[0] ).to eql 'create'
360
+ expect( tuple[1] ).to include :_index => 'logs-generic-default'
361
+ end
362
+
363
+ end
364
+
365
+ context 'with partial data_stream.* data' do
366
+
367
+ let(:options) { super().merge('data_stream_dataset' => 'data') }
368
+
369
+ let(:event) do
370
+ super().tap do |event|
371
+ event.set '[data_stream][type]', 'metrics'
372
+ event.set '[data_stream][dataset]', 'src1'
373
+ end
374
+ end
375
+
376
+ it 'uses event specified target' do
377
+ tuple = subject.map_events([ event ]).first
378
+ expect( tuple.size ).to eql 3
379
+ expect( tuple[0] ).to eql 'create'
380
+ expect( tuple[1] ).to include :_index => 'metrics-src1-default'
381
+ end
382
+
383
+ end
384
+
385
+ context 'with no data_stream.* fields' do
386
+
387
+ let(:options) { super().merge('data_stream_dataset' => 'stats', 'data_stream_type' => 'metrics') }
388
+
389
+ it 'uses configuration target' do
390
+ tuple = subject.map_events([ event ]).first
391
+ expect( tuple.size ).to eql 3
392
+ expect( tuple[0] ).to eql 'create'
393
+ expect( tuple[1] ).to include :_index => 'metrics-stats-default'
394
+ end
395
+
396
+ end
397
+
398
+ context 'with default configuration' do
399
+
400
+ it 'uses default target' do
401
+ tuple = subject.map_events([ event ]).first
402
+ expect( tuple.size ).to eql 3
403
+ expect( tuple[0] ).to eql 'create'
404
+ expect( tuple[1] ).to include :_index => 'logs-generic-default'
405
+ end
406
+
407
+ end
408
+
409
+ end
410
+
411
+ describe "field sync" do
412
+
413
+ let(:options) { super().merge('data_stream' => 'true') }
414
+
415
+ let(:do_register) { true }
416
+
417
+ let(:event) do
418
+ event = LogStash::Event.new
419
+ event.set '[host][hostname]', 'orangutan'
420
+ event
421
+ end
422
+
423
+ context 'enabled and no event data' do
424
+
425
+ let(:options) { super().merge('data_stream_sync_fields' => 'true') }
426
+
427
+ it 'fills in DS fields' do
428
+ tuple = subject.map_events([ event ]).first
429
+ expect( tuple.size ).to eql 3
430
+ expect( tuple[2]['data_stream'] ).to eql({"type" => "logs", "dataset" => "generic", "namespace" => "default"})
431
+ end
432
+
433
+ end
434
+
435
+ context 'enabled and some event data' do
436
+
437
+ let(:options) { super().merge('data_stream_dataset' => 'ds1', 'data_stream_sync_fields' => 'true') }
438
+
439
+ let(:event) do
440
+ super().tap do |event|
441
+ event.set '[data_stream][namespace]', 'custom'
442
+ end
443
+ end
444
+
445
+ it 'fills in missing fields' do
446
+ tuple = subject.map_events([ event ]).first
447
+ expect( tuple.size ).to eql 3
448
+ expect( tuple[2]['data_stream'] ).to eql({"type" => "logs", "dataset" => "ds1", "namespace" => "custom"})
449
+ end
450
+
451
+ it 'does not mutate data_stream hash' do
452
+ data_stream = event.get('data_stream')
453
+ data_stream_dup = data_stream.dup
454
+ subject.map_events([ event ])
455
+ expect( data_stream ).to eql data_stream_dup
456
+ end
457
+
458
+ end
459
+
460
+ context 'enabled with invalid data' do
461
+
462
+ let(:options) { super().merge('data_stream_sync_fields' => 'true') }
463
+
464
+ let(:event) do
465
+ super().tap do |event|
466
+ event.set '[data_stream]', false
467
+ end
468
+ end
469
+
470
+ it 'overwrites invalid data_stream field' do
471
+ tuple = subject.map_events([ event ]).first
472
+ expect( tuple.size ).to eql 3
473
+ expect( tuple[2]['data_stream'] ).to eql({"type" => "logs", "dataset" => "generic", "namespace" => "default"})
474
+ end
475
+
476
+ end
477
+
478
+ context 'enabled having invalid data with routing disabled' do
479
+
480
+ let(:options) do
481
+ super().merge('data_stream_sync_fields' => 'true', 'data_stream_auto_routing' => 'false', 'data_stream_namespace' => 'ns1')
482
+ end
483
+
484
+ let(:event) do
485
+ super().tap do |event|
486
+ event.set '[data_stream][type]', 'foo'
487
+ event.set '[data_stream][dataset]', false
488
+ event.set '[data_stream][extra]', 0
489
+ end
490
+ end
491
+
492
+ it 'overwrites invalid data_stream sub-fields' do
493
+ tuple = subject.map_events([ event ]).first
494
+ expect( tuple.size ).to eql 3
495
+ expect( tuple[2]['data_stream'] ).to eql({"type" => "logs", "dataset" => "generic", "namespace" => "ns1", "extra" => 0})
496
+ end
497
+
498
+ end
499
+
500
+ context 'disabled and no event data' do
501
+
502
+ let(:options) { super().merge('data_stream_dataset' => 'ds1', 'data_stream_sync_fields' => 'false') }
503
+
504
+ it 'does not fill DS fields' do
505
+ tuple = subject.map_events([ event ]).first
506
+ expect( tuple.size ).to eql 3
507
+ expect( tuple[2].keys ).to_not include 'data_stream'
508
+ end
509
+
510
+ end
511
+
512
+ context 'disabled and some event data' do
513
+
514
+ let(:options) { super().merge('data_stream_sync_fields' => 'false') }
515
+
516
+ let(:event) do
517
+ super().tap do |event|
518
+ event.set '[data_stream][type]', 'logs'
519
+ end
520
+ end
521
+
522
+ it 'does not fill DS fields' do
523
+ tuple = subject.map_events([ event ]).first
524
+ expect( tuple.size ).to eql 3
525
+ expect( tuple[2]['data_stream'] ).to eql({ 'type' => 'logs'})
526
+ end
527
+
528
+ end
529
+
530
+ end
531
+
532
+ describe "validation" do
533
+
534
+ context 'with too long dataset name' do
535
+
536
+ let(:options) { super().merge('data_stream' => 'true', 'data_stream_dataset' => 'x' * 120) }
537
+
538
+ it 'fails' do
539
+ expect { LogStash::Outputs::ElasticSearch.new(options) }.to raise_error LogStash::ConfigurationError
540
+ end
541
+
542
+ end
543
+
544
+ context 'with empty dataset name' do
545
+
546
+ let(:options) { super().merge('data_stream' => 'true', 'data_stream_dataset' => '') }
547
+
548
+ it 'fails' do
549
+ expect { LogStash::Outputs::ElasticSearch.new(options) }.to raise_error LogStash::ConfigurationError
550
+ end
551
+
552
+ end
553
+
554
+ context 'with invalid dataset char' do
555
+
556
+ let(:options) { super().merge('data_stream' => 'true', 'data_stream_dataset' => 'foo/bar') }
557
+
558
+ it 'fails' do
559
+ expect { LogStash::Outputs::ElasticSearch.new(options) }.to raise_error LogStash::ConfigurationError
560
+ end
561
+
562
+ end
563
+
564
+ context 'with invalid namespace char' do
565
+
566
+ let(:options) { super().merge('data_stream' => 'true', 'data_stream_namespace' => 'foo*') }
567
+
568
+ it 'fails' do
569
+ expect { LogStash::Outputs::ElasticSearch.new(options) }.to raise_error LogStash::ConfigurationError
570
+ end
571
+
572
+ end
573
+
574
+ context 'with invalid "empty" namespace' do
575
+
576
+ let(:options) { super().merge('data_stream' => 'true', 'data_stream_namespace' => ' ') }
577
+
578
+ it 'fails' do
579
+ expect { LogStash::Outputs::ElasticSearch.new(options) }.to raise_error LogStash::ConfigurationError
580
+ end
581
+
582
+ end
583
+
584
+ context 'with invalid type' do
585
+
586
+ let(:options) { super().merge('data_stream' => 'true', 'data_stream_type' => 'custom') }
587
+
588
+ it 'fails' do
589
+ expect { LogStash::Outputs::ElasticSearch.new(options) }.to raise_error LogStash::ConfigurationError
590
+ end
591
+
592
+ end
593
+
594
+ end
595
+
596
+ private
597
+
598
+ def change_constant(name, new_value, target: Object)
599
+ old_value = target.const_get name
600
+ begin
601
+ target.send :remove_const, name
602
+ target.const_set name, new_value
603
+ yield if block_given?
604
+ ensure
605
+ if block_given?
606
+ target.send :remove_const, name rescue nil
607
+ target.const_set name, old_value
608
+ end
609
+ end
610
+ end
611
+
612
+ end