logstash-output-elasticsearch-test 11.16.0-x86_64-linux
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +649 -0
- data/CONTRIBUTORS +34 -0
- data/Gemfile +16 -0
- data/LICENSE +202 -0
- data/NOTICE.TXT +5 -0
- data/README.md +106 -0
- data/docs/index.asciidoc +1369 -0
- data/lib/logstash/outputs/elasticsearch/data_stream_support.rb +282 -0
- data/lib/logstash/outputs/elasticsearch/default-ilm-policy.json +14 -0
- data/lib/logstash/outputs/elasticsearch/http_client/manticore_adapter.rb +155 -0
- data/lib/logstash/outputs/elasticsearch/http_client/pool.rb +534 -0
- data/lib/logstash/outputs/elasticsearch/http_client.rb +497 -0
- data/lib/logstash/outputs/elasticsearch/http_client_builder.rb +201 -0
- data/lib/logstash/outputs/elasticsearch/ilm.rb +92 -0
- data/lib/logstash/outputs/elasticsearch/license_checker.rb +52 -0
- data/lib/logstash/outputs/elasticsearch/template_manager.rb +131 -0
- data/lib/logstash/outputs/elasticsearch/templates/ecs-disabled/elasticsearch-6x.json +45 -0
- data/lib/logstash/outputs/elasticsearch/templates/ecs-disabled/elasticsearch-7x.json +44 -0
- data/lib/logstash/outputs/elasticsearch/templates/ecs-disabled/elasticsearch-8x.json +50 -0
- data/lib/logstash/outputs/elasticsearch.rb +699 -0
- data/lib/logstash/plugin_mixins/elasticsearch/api_configs.rb +237 -0
- data/lib/logstash/plugin_mixins/elasticsearch/common.rb +409 -0
- data/lib/logstash/plugin_mixins/elasticsearch/noop_license_checker.rb +9 -0
- data/logstash-output-elasticsearch.gemspec +40 -0
- data/spec/es_spec_helper.rb +225 -0
- data/spec/fixtures/_nodes/6x.json +81 -0
- data/spec/fixtures/_nodes/7x.json +92 -0
- data/spec/fixtures/htpasswd +2 -0
- data/spec/fixtures/license_check/active.json +16 -0
- data/spec/fixtures/license_check/inactive.json +5 -0
- data/spec/fixtures/nginx_reverse_proxy.conf +22 -0
- data/spec/fixtures/scripts/painless/scripted_update.painless +2 -0
- data/spec/fixtures/scripts/painless/scripted_update_nested.painless +1 -0
- data/spec/fixtures/scripts/painless/scripted_upsert.painless +1 -0
- data/spec/fixtures/template-with-policy-es6x.json +48 -0
- data/spec/fixtures/template-with-policy-es7x.json +45 -0
- data/spec/fixtures/template-with-policy-es8x.json +50 -0
- data/spec/fixtures/test_certs/ca.crt +29 -0
- data/spec/fixtures/test_certs/ca.der.sha256 +1 -0
- data/spec/fixtures/test_certs/ca.key +51 -0
- data/spec/fixtures/test_certs/renew.sh +13 -0
- data/spec/fixtures/test_certs/test.crt +30 -0
- data/spec/fixtures/test_certs/test.der.sha256 +1 -0
- data/spec/fixtures/test_certs/test.key +51 -0
- data/spec/fixtures/test_certs/test.p12 +0 -0
- data/spec/fixtures/test_certs/test_invalid.crt +36 -0
- data/spec/fixtures/test_certs/test_invalid.key +51 -0
- data/spec/fixtures/test_certs/test_invalid.p12 +0 -0
- data/spec/fixtures/test_certs/test_self_signed.crt +32 -0
- data/spec/fixtures/test_certs/test_self_signed.key +54 -0
- data/spec/fixtures/test_certs/test_self_signed.p12 +0 -0
- data/spec/integration/outputs/compressed_indexing_spec.rb +70 -0
- data/spec/integration/outputs/create_spec.rb +67 -0
- data/spec/integration/outputs/data_stream_spec.rb +68 -0
- data/spec/integration/outputs/delete_spec.rb +63 -0
- data/spec/integration/outputs/ilm_spec.rb +534 -0
- data/spec/integration/outputs/index_spec.rb +421 -0
- data/spec/integration/outputs/index_version_spec.rb +98 -0
- data/spec/integration/outputs/ingest_pipeline_spec.rb +75 -0
- data/spec/integration/outputs/metrics_spec.rb +66 -0
- data/spec/integration/outputs/no_es_on_startup_spec.rb +78 -0
- data/spec/integration/outputs/painless_update_spec.rb +99 -0
- data/spec/integration/outputs/parent_spec.rb +94 -0
- data/spec/integration/outputs/retry_spec.rb +182 -0
- data/spec/integration/outputs/routing_spec.rb +61 -0
- data/spec/integration/outputs/sniffer_spec.rb +94 -0
- data/spec/integration/outputs/templates_spec.rb +133 -0
- data/spec/integration/outputs/unsupported_actions_spec.rb +75 -0
- data/spec/integration/outputs/update_spec.rb +114 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/support/elasticsearch/api/actions/delete_ilm_policy.rb +19 -0
- data/spec/support/elasticsearch/api/actions/get_alias.rb +18 -0
- data/spec/support/elasticsearch/api/actions/get_ilm_policy.rb +18 -0
- data/spec/support/elasticsearch/api/actions/put_alias.rb +24 -0
- data/spec/support/elasticsearch/api/actions/put_ilm_policy.rb +25 -0
- data/spec/unit/http_client_builder_spec.rb +185 -0
- data/spec/unit/outputs/elasticsearch/data_stream_support_spec.rb +612 -0
- data/spec/unit/outputs/elasticsearch/http_client/manticore_adapter_spec.rb +151 -0
- data/spec/unit/outputs/elasticsearch/http_client/pool_spec.rb +501 -0
- data/spec/unit/outputs/elasticsearch/http_client_spec.rb +339 -0
- data/spec/unit/outputs/elasticsearch/template_manager_spec.rb +189 -0
- data/spec/unit/outputs/elasticsearch_proxy_spec.rb +103 -0
- data/spec/unit/outputs/elasticsearch_spec.rb +1573 -0
- data/spec/unit/outputs/elasticsearch_ssl_spec.rb +197 -0
- data/spec/unit/outputs/error_whitelist_spec.rb +56 -0
- data/spec/unit/outputs/license_check_spec.rb +57 -0
- 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
|