logstash-output-elasticsearch-test 10.3.0-x86_64-linux

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +397 -0
  3. data/CONTRIBUTORS +33 -0
  4. data/Gemfile +15 -0
  5. data/LICENSE +13 -0
  6. data/NOTICE.TXT +5 -0
  7. data/README.md +106 -0
  8. data/docs/index.asciidoc +899 -0
  9. data/lib/logstash/outputs/elasticsearch/common.rb +441 -0
  10. data/lib/logstash/outputs/elasticsearch/common_configs.rb +167 -0
  11. data/lib/logstash/outputs/elasticsearch/default-ilm-policy.json +14 -0
  12. data/lib/logstash/outputs/elasticsearch/elasticsearch-template-es2x.json +95 -0
  13. data/lib/logstash/outputs/elasticsearch/elasticsearch-template-es5x.json +46 -0
  14. data/lib/logstash/outputs/elasticsearch/elasticsearch-template-es6x.json +45 -0
  15. data/lib/logstash/outputs/elasticsearch/elasticsearch-template-es7x.json +44 -0
  16. data/lib/logstash/outputs/elasticsearch/elasticsearch-template-es8x.json +44 -0
  17. data/lib/logstash/outputs/elasticsearch/http_client/manticore_adapter.rb +131 -0
  18. data/lib/logstash/outputs/elasticsearch/http_client/pool.rb +495 -0
  19. data/lib/logstash/outputs/elasticsearch/http_client.rb +432 -0
  20. data/lib/logstash/outputs/elasticsearch/http_client_builder.rb +159 -0
  21. data/lib/logstash/outputs/elasticsearch/ilm.rb +113 -0
  22. data/lib/logstash/outputs/elasticsearch/template_manager.rb +61 -0
  23. data/lib/logstash/outputs/elasticsearch.rb +263 -0
  24. data/logstash-output-elasticsearch.gemspec +33 -0
  25. data/spec/es_spec_helper.rb +189 -0
  26. data/spec/fixtures/_nodes/2x_1x.json +27 -0
  27. data/spec/fixtures/_nodes/5x_6x.json +81 -0
  28. data/spec/fixtures/_nodes/7x.json +92 -0
  29. data/spec/fixtures/htpasswd +2 -0
  30. data/spec/fixtures/nginx_reverse_proxy.conf +22 -0
  31. data/spec/fixtures/scripts/groovy/scripted_update.groovy +2 -0
  32. data/spec/fixtures/scripts/groovy/scripted_update_nested.groovy +2 -0
  33. data/spec/fixtures/scripts/groovy/scripted_upsert.groovy +2 -0
  34. data/spec/fixtures/scripts/painless/scripted_update.painless +2 -0
  35. data/spec/fixtures/scripts/painless/scripted_update_nested.painless +1 -0
  36. data/spec/fixtures/scripts/painless/scripted_upsert.painless +1 -0
  37. data/spec/fixtures/template-with-policy-es6x.json +48 -0
  38. data/spec/fixtures/template-with-policy-es7x.json +45 -0
  39. data/spec/fixtures/test_certs/ca/ca.crt +32 -0
  40. data/spec/fixtures/test_certs/ca/ca.key +51 -0
  41. data/spec/fixtures/test_certs/test.crt +36 -0
  42. data/spec/fixtures/test_certs/test.key +51 -0
  43. data/spec/integration/outputs/compressed_indexing_spec.rb +69 -0
  44. data/spec/integration/outputs/create_spec.rb +67 -0
  45. data/spec/integration/outputs/delete_spec.rb +65 -0
  46. data/spec/integration/outputs/groovy_update_spec.rb +150 -0
  47. data/spec/integration/outputs/ilm_spec.rb +531 -0
  48. data/spec/integration/outputs/index_spec.rb +178 -0
  49. data/spec/integration/outputs/index_version_spec.rb +102 -0
  50. data/spec/integration/outputs/ingest_pipeline_spec.rb +74 -0
  51. data/spec/integration/outputs/metrics_spec.rb +70 -0
  52. data/spec/integration/outputs/no_es_on_startup_spec.rb +58 -0
  53. data/spec/integration/outputs/painless_update_spec.rb +189 -0
  54. data/spec/integration/outputs/parent_spec.rb +102 -0
  55. data/spec/integration/outputs/retry_spec.rb +169 -0
  56. data/spec/integration/outputs/routing_spec.rb +61 -0
  57. data/spec/integration/outputs/sniffer_spec.rb +133 -0
  58. data/spec/integration/outputs/templates_5x_spec.rb +98 -0
  59. data/spec/integration/outputs/templates_spec.rb +98 -0
  60. data/spec/integration/outputs/update_spec.rb +116 -0
  61. data/spec/support/elasticsearch/api/actions/delete_ilm_policy.rb +19 -0
  62. data/spec/support/elasticsearch/api/actions/get_alias.rb +18 -0
  63. data/spec/support/elasticsearch/api/actions/get_ilm_policy.rb +18 -0
  64. data/spec/support/elasticsearch/api/actions/put_alias.rb +24 -0
  65. data/spec/support/elasticsearch/api/actions/put_ilm_policy.rb +25 -0
  66. data/spec/unit/http_client_builder_spec.rb +185 -0
  67. data/spec/unit/outputs/elasticsearch/http_client/manticore_adapter_spec.rb +149 -0
  68. data/spec/unit/outputs/elasticsearch/http_client/pool_spec.rb +274 -0
  69. data/spec/unit/outputs/elasticsearch/http_client_spec.rb +250 -0
  70. data/spec/unit/outputs/elasticsearch/template_manager_spec.rb +25 -0
  71. data/spec/unit/outputs/elasticsearch_proxy_spec.rb +72 -0
  72. data/spec/unit/outputs/elasticsearch_spec.rb +675 -0
  73. data/spec/unit/outputs/elasticsearch_ssl_spec.rb +82 -0
  74. data/spec/unit/outputs/error_whitelist_spec.rb +54 -0
  75. metadata +300 -0
@@ -0,0 +1,150 @@
1
+ require_relative "../../../spec/es_spec_helper"
2
+
3
+ if ESHelper.es_version_satisfies?('>= 2', '< 6')
4
+ describe "Update actions using groovy scripts", :integration => true, :update_tests => 'groovy' do
5
+ require "logstash/outputs/elasticsearch"
6
+
7
+ def get_es_output( options={} )
8
+ settings = {
9
+ "manage_template" => true,
10
+ "index" => "logstash-update",
11
+ "template_overwrite" => true,
12
+ "hosts" => get_host_port(),
13
+ "action" => "update",
14
+ "script_lang" => "groovy"
15
+ }
16
+ LogStash::Outputs::ElasticSearch.new(settings.merge!(options))
17
+ end
18
+
19
+ before :each do
20
+ @es = get_client
21
+ # Delete all templates first.
22
+ # Clean ES of data before we start.
23
+ @es.indices.delete_template(:name => "*")
24
+ # This can fail if there are no indexes, ignore failure.
25
+ @es.indices.delete(:index => "*") rescue nil
26
+ @es.index(
27
+ :index => 'logstash-update',
28
+ :type => doc_type,
29
+ :id => "123",
30
+ :body => { :message => 'Test', :counter => 1 }
31
+ )
32
+ @es.indices.refresh
33
+ end
34
+
35
+ context "scripted updates" do
36
+ it "should increment a counter with event/doc 'count' variable" do
37
+ subject = get_es_output({ 'document_id' => "123", 'script' => 'scripted_update', 'script_type' => 'file' })
38
+ subject.register
39
+ subject.multi_receive([LogStash::Event.new("count" => 2)])
40
+ r = @es.get(:index => 'logstash-update', :type => doc_type, :id => "123", :refresh => true)
41
+ expect(r["_source"]["counter"]).to eq(3)
42
+ end
43
+
44
+ it "should increment a counter with event/doc '[data][count]' nested variable" do
45
+ subject = get_es_output({ 'document_id' => "123", 'script' => 'scripted_update_nested', 'script_type' => 'file' })
46
+ subject.register
47
+ subject.multi_receive([LogStash::Event.new("data" => { "count" => 3 })])
48
+ r = @es.get(:index => 'logstash-update', :type => doc_type, :id => "123", :refresh => true)
49
+ expect(r["_source"]["counter"]).to eq(4)
50
+ end
51
+
52
+ it "should increment a counter with event/doc 'count' variable with inline script" do
53
+ subject = get_es_output({
54
+ 'document_id' => "123",
55
+ 'script' => 'ctx._source.counter += event["counter"]',
56
+ 'script_lang' => 'groovy',
57
+ 'script_type' => 'inline'
58
+ })
59
+ subject.register
60
+ subject.multi_receive([LogStash::Event.new("counter" => 3 )])
61
+ r = @es.get(:index => 'logstash-update', :type => doc_type, :id => "123", :refresh => true)
62
+ expect(r["_source"]["counter"]).to eq(4)
63
+ end
64
+
65
+ it "should increment a counter with event/doc 'count' variable with event/doc as upsert and inline script" do
66
+ subject = get_es_output({
67
+ 'document_id' => "123",
68
+ 'doc_as_upsert' => true,
69
+ 'script' => 'if( ctx._source.containsKey("counter") ){ ctx._source.counter += event["counter"]; } else { ctx._source.counter = event["counter"]; }',
70
+ 'script_lang' => 'groovy',
71
+ 'script_type' => 'inline'
72
+ })
73
+ subject.register
74
+ subject.multi_receive([LogStash::Event.new("counter" => 3 )])
75
+ r = @es.get(:index => 'logstash-update', :type => doc_type, :id => "123", :refresh => true)
76
+ expect(r["_source"]["counter"]).to eq(4)
77
+ end
78
+
79
+ it "should, with new doc, set a counter with event/doc 'count' variable with event/doc as upsert and inline script" do
80
+ subject = get_es_output({
81
+ 'document_id' => "456",
82
+ 'doc_as_upsert' => true,
83
+ 'script' => 'if( ctx._source.containsKey("counter") ){ ctx._source.counter += event["count"]; } else { ctx._source.counter = event["count"]; }',
84
+ 'script_lang' => 'groovy',
85
+ 'script_type' => 'inline'
86
+ })
87
+ subject.register
88
+ subject.multi_receive([LogStash::Event.new("counter" => 3 )])
89
+ r = @es.get(:index => 'logstash-update', :type => doc_type, :id => "456", :refresh => true)
90
+ expect(r["_source"]["counter"]).to eq(3)
91
+ end
92
+
93
+ it "should increment a counter with event/doc 'count' variable with indexed script" do
94
+ @es.put_script lang: 'groovy', id: 'indexed_update', body: { script: 'ctx._source.counter += event["count"]' }
95
+ subject = get_es_output({
96
+ 'document_id' => "123",
97
+ 'script' => 'indexed_update',
98
+ 'script_lang' => 'groovy',
99
+ 'script_type' => 'indexed'
100
+ })
101
+ subject.register
102
+ subject.multi_receive([LogStash::Event.new("count" => 4 )])
103
+ r = @es.get(:index => 'logstash-update', :type => doc_type, :id => "123", :refresh => true)
104
+ expect(r["_source"]["counter"]).to eq(5)
105
+ end
106
+ end
107
+
108
+ context "when update with upsert" do
109
+ it "should create new documents with provided upsert" do
110
+ subject = get_es_output({ 'document_id' => "456", 'upsert' => '{"message": "upsert message"}' })
111
+ subject.register
112
+ subject.multi_receive([LogStash::Event.new("message" => "sample message here")])
113
+ r = @es.get(:index => 'logstash-update', :type => doc_type, :id => "456", :refresh => true)
114
+ expect(r["_source"]["message"]).to eq('upsert message')
115
+ end
116
+
117
+ it "should create new documents with event/doc as upsert" do
118
+ subject = get_es_output({ 'document_id' => "456", 'doc_as_upsert' => true })
119
+ subject.register
120
+ subject.multi_receive([LogStash::Event.new("message" => "sample message here")])
121
+ r = @es.get(:index => 'logstash-update', :type => doc_type, :id => "456", :refresh => true)
122
+ expect(r["_source"]["message"]).to eq('sample message here')
123
+ end
124
+
125
+ it "should fail on documents with event/doc as upsert at external version" do
126
+ subject = get_es_output({ 'document_id' => "456", 'doc_as_upsert' => true, 'version' => 999, "version_type" => "external" })
127
+ expect { subject.register }.to raise_error(LogStash::ConfigurationError)
128
+ end
129
+ end
130
+
131
+ context "updates with scripted upsert" do
132
+ it "should create new documents with upsert content" do
133
+ subject = get_es_output({ 'document_id' => "456", 'script' => 'scripted_update', 'upsert' => '{"message": "upsert message"}', 'script_type' => 'file' })
134
+ subject.register
135
+ subject.multi_receive([LogStash::Event.new("message" => "sample message here")])
136
+ r = @es.get(:index => 'logstash-update', :type => doc_type, :id => "456", :refresh => true)
137
+ expect(r["_source"]["message"]).to eq('upsert message')
138
+ end
139
+
140
+ it "should create new documents with event/doc as script params" do
141
+ subject = get_es_output({ 'document_id' => "456", 'script' => 'scripted_upsert', 'scripted_upsert' => true, 'script_type' => 'file' })
142
+ subject.register
143
+ subject.multi_receive([LogStash::Event.new("counter" => 1)])
144
+ @es.indices.refresh
145
+ r = @es.get(:index => 'logstash-update', :type => doc_type, :id => "456", :refresh => true)
146
+ expect(r["_source"]["counter"]).to eq(1)
147
+ end
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,531 @@
1
+ require_relative "../../../spec/es_spec_helper"
2
+
3
+ shared_examples_for 'an ILM enabled Logstash' do
4
+
5
+ context 'with a policy with a maximum number of documents' do
6
+ let (:policy) { small_max_doc_policy }
7
+ let (:ilm_policy_name) { "custom-policy"}
8
+ let (:settings) { super.merge("ilm_policy" => ilm_policy_name)}
9
+
10
+ it 'should rollover when the policy max docs is reached' do
11
+ put_policy(@es,ilm_policy_name, policy)
12
+ subject.register
13
+
14
+ subject.multi_receive([
15
+ LogStash::Event.new("message" => "sample message here"),
16
+ LogStash::Event.new("somemessage" => { "message" => "sample nested message here" }),
17
+ LogStash::Event.new("somevalue" => 100),
18
+ ])
19
+
20
+ sleep(6)
21
+
22
+ subject.multi_receive([
23
+ LogStash::Event.new("country" => "us"),
24
+ LogStash::Event.new("country" => "at"),
25
+ LogStash::Event.new("geoip" => { "location" => [ 0.0, 0.0 ] })
26
+ ])
27
+
28
+ sleep(6)
29
+
30
+ subject.multi_receive([
31
+ LogStash::Event.new("country" => "uk"),
32
+ LogStash::Event.new("country" => "fr"),
33
+ LogStash::Event.new("geoip" => { "location" => [ 0.1, 1.0 ] })
34
+ ])
35
+
36
+ @es.indices.refresh
37
+
38
+ # Wait or fail until everything's indexed.
39
+ Stud::try(20.times) do
40
+ r = @es.search
41
+ expect(r).to have_hits(9)
42
+ end
43
+ indexes_written = @es.search['hits']['hits'].each_with_object(Hash.new(0)) do |x, res|
44
+ index_written = x['_index']
45
+ res[index_written] += 1
46
+ end
47
+ expect(indexes_written.count).to eq(3)
48
+ expect(indexes_written["#{expected_index}-#{todays_date}-000001"]).to eq(3)
49
+ expect(indexes_written["#{expected_index}-#{todays_date}-000002"]).to eq(3)
50
+ expect(indexes_written["#{expected_index}-#{todays_date}-000003"]).to eq(3)
51
+ end
52
+ end
53
+
54
+ context 'with a policy where the maximum number of documents is not reached' do
55
+ let (:policy) { large_max_doc_policy }
56
+ let (:ilm_policy_name) { "custom-policy"}
57
+ let (:settings) { super.merge("ilm_policy" => ilm_policy_name)}
58
+
59
+ it 'should ingest into a single index when max docs is not reached' do
60
+ put_policy(@es,ilm_policy_name, policy)
61
+ subject.register
62
+
63
+ subject.multi_receive([
64
+ LogStash::Event.new("message" => "sample message here"),
65
+ LogStash::Event.new("somemessage" => { "message" => "sample nested message here" }),
66
+ LogStash::Event.new("somevalue" => 100),
67
+ ])
68
+
69
+ sleep(6)
70
+
71
+ subject.multi_receive([
72
+ LogStash::Event.new("country" => "us"),
73
+ LogStash::Event.new("country" => "at"),
74
+ LogStash::Event.new("geoip" => { "location" => [ 0.0, 0.0 ] })
75
+ ])
76
+
77
+ @es.indices.refresh
78
+
79
+ # Wait or fail until everything's indexed.
80
+ Stud::try(20.times) do
81
+ r = @es.search
82
+ expect(r).to have_hits(6)
83
+ end
84
+ indexes_written = @es.search['hits']['hits'].each_with_object(Hash.new(0)) do |x, res|
85
+ index_written = x['_index']
86
+ res[index_written] += 1
87
+ end
88
+ expect(indexes_written.count).to eq(1)
89
+ expect(indexes_written["#{expected_index}-#{todays_date}-000001"]).to eq(6)
90
+ end
91
+ end
92
+ end
93
+
94
+ shared_examples_for 'an ILM disabled Logstash' do
95
+ it 'should not create a rollover alias' do
96
+ expect(@es.get_alias).to be_empty
97
+ subject.register
98
+ sleep(1)
99
+ expect(@es.get_alias).to be_empty
100
+ end
101
+
102
+ it 'should not install the default policy' do
103
+ subject.register
104
+ sleep(1)
105
+ expect{get_policy(@es, LogStash::Outputs::ElasticSearch::DEFAULT_POLICY)}.to raise_error(Elasticsearch::Transport::Transport::Errors::NotFound)
106
+ end
107
+
108
+ it 'should not write the ILM settings into the template' do
109
+ subject.register
110
+ sleep(1)
111
+ expect(@es.indices.get_template(name: "logstash")["logstash"]).to have_index_pattern("logstash-*")
112
+ if ESHelper.es_version_satisfies?(">= 2")
113
+ expect(@es.indices.get_template(name: "logstash")["logstash"]["settings"]['index']['lifecycle']).to be_nil
114
+ end
115
+ end
116
+
117
+ context 'with an existing policy that will roll over' do
118
+ let (:policy) { small_max_doc_policy }
119
+ let (:ilm_policy_name) { "3_docs"}
120
+ let (:settings) { super.merge("ilm_policy" => ilm_policy_name)}
121
+
122
+ it 'should not roll over indices' do
123
+ subject.register
124
+ subject.multi_receive([
125
+ LogStash::Event.new("message" => "sample message here"),
126
+ LogStash::Event.new("somemessage" => { "message" => "sample nested message here" }),
127
+ LogStash::Event.new("somevalue" => 100),
128
+ ])
129
+
130
+ sleep(6)
131
+
132
+ subject.multi_receive([
133
+ LogStash::Event.new("country" => "us"),
134
+ LogStash::Event.new("country" => "at"),
135
+ LogStash::Event.new("geoip" => { "location" => [ 0.0, 0.0 ] })
136
+ ])
137
+
138
+ @es.indices.refresh
139
+
140
+ # Wait or fail until everything's indexed.
141
+ Stud::try(20.times) do
142
+ r = @es.search
143
+ expect(r).to have_hits(6)
144
+ end
145
+ indexes_written = @es.search['hits']['hits'].each_with_object(Hash.new(0)) do |x, res|
146
+ index_written = x['_index']
147
+ res[index_written] += 1
148
+ end
149
+ expect(indexes_written.count).to eq(1)
150
+ expect(indexes_written.values.first).to eq(6)
151
+ end
152
+ end
153
+
154
+ context 'with a custom template name' do
155
+ let (:template_name) { "custom_template_name" }
156
+ let (:settings) { super.merge('template_name' => template_name)}
157
+
158
+ it 'should not write the ILM settings into the template' do
159
+ subject.register
160
+ sleep(1)
161
+
162
+ expect(@es.indices.get_template(name: template_name)[template_name]).to have_index_pattern("logstash-*")
163
+ if ESHelper.es_version_satisfies?(">= 2")
164
+ expect(@es.indices.get_template(name: template_name)[template_name]["settings"]['index']['lifecycle']).to be_nil
165
+ end
166
+ end
167
+ end
168
+ end
169
+
170
+ shared_examples_for 'an Elasticsearch instance that does not support index lifecycle management' do
171
+ require "logstash/outputs/elasticsearch"
172
+
173
+ let (:ilm_enabled) { false }
174
+ let (:settings) {
175
+ {
176
+ "hosts" => "#{get_host_port()}"
177
+ }
178
+ }
179
+
180
+ before :each do
181
+ require "elasticsearch"
182
+
183
+ # Clean ES of data before we start.
184
+ @es = get_client
185
+ clean(@es)
186
+ end
187
+
188
+ after :each do
189
+ clean(@es)
190
+ end
191
+
192
+ subject { LogStash::Outputs::ElasticSearch.new(settings) }
193
+
194
+ context 'when ilm is enabled in Logstash' do
195
+ let (:settings) { super.merge!({ 'ilm_enabled' => true }) }
196
+
197
+ it 'should raise a configuration error' do
198
+ expect do
199
+ begin
200
+ subject.register
201
+ sleep(1)
202
+ ensure
203
+ subject.stop_template_installer
204
+ end
205
+ end.to raise_error(LogStash::ConfigurationError)
206
+ end
207
+ end
208
+
209
+ context 'when ilm is disabled in Logstash' do
210
+ let (:settings) { super.merge!({ 'ilm_enabled' => false }) }
211
+
212
+ it_behaves_like 'an ILM disabled Logstash'
213
+ end
214
+
215
+ context 'when ilm is set to auto in Logstash' do
216
+ let (:settings) { super.merge!({ 'ilm_enabled' => 'auto' }) }
217
+
218
+ it_behaves_like 'an ILM disabled Logstash'
219
+ end
220
+
221
+ context 'when ilm is not set in Logstash' do
222
+ it_behaves_like 'an ILM disabled Logstash'
223
+ end
224
+
225
+ end
226
+
227
+ if ESHelper.es_version_satisfies?("<= 6.5")
228
+ describe 'Pre-ILM versions of Elasticsearch', :integration => true do
229
+ it_behaves_like 'an Elasticsearch instance that does not support index lifecycle management'
230
+ end
231
+ end
232
+
233
+ if ESHelper.es_version_satisfies?(">= 6.6")
234
+ describe 'OSS Elasticsearch', :distribution => 'oss', :integration => true do
235
+ it_behaves_like 'an Elasticsearch instance that does not support index lifecycle management'
236
+ end
237
+
238
+ describe 'Elasticsearch has index lifecycle management enabled', :distribution => 'xpack', :integration => true do
239
+
240
+ DEFAULT_INTERVAL = '600s'
241
+
242
+ let (:ilm_enabled) { true }
243
+
244
+ let (:settings) {
245
+ {
246
+ "ilm_enabled" => ilm_enabled,
247
+ "hosts" => "#{get_host_port()}"
248
+ }
249
+ }
250
+ let (:small_max_doc_policy) { max_docs_policy(3) }
251
+ let (:large_max_doc_policy) { max_docs_policy(1000000) }
252
+ let (:expected_index) { LogStash::Outputs::ElasticSearch::DEFAULT_ROLLOVER_ALIAS }
253
+
254
+ subject { LogStash::Outputs::ElasticSearch.new(settings) }
255
+
256
+ before :each do
257
+ # Delete all templates first.
258
+ require "elasticsearch"
259
+
260
+ # Clean ES of data before we start.
261
+ @es = get_client
262
+ clean(@es)
263
+ # Set the poll interval for lifecycle management to be short so changes get picked up in time.
264
+ set_cluster_settings(@es, {
265
+ "persistent" => {
266
+ "indices.lifecycle.poll_interval" => "1s"
267
+ }
268
+ })
269
+ end
270
+
271
+ after :each do
272
+ # Set poll interval back to default
273
+ set_cluster_settings(@es, {
274
+ "persistent" => {
275
+ "indices.lifecycle.poll_interval" => DEFAULT_INTERVAL
276
+ }
277
+ })
278
+ clean(@es)
279
+ end
280
+
281
+ context 'with ilm enabled' do
282
+ let (:ilm_enabled) { true }
283
+
284
+ context 'when using the default policy' do
285
+ context 'with a custom pattern' do
286
+ let (:settings) { super.merge("ilm_pattern" => "000001")}
287
+ it 'should create a rollover alias' do
288
+ expect(@es.indices.exists_alias(index: "logstash")).to be_falsey
289
+ subject.register
290
+ sleep(1)
291
+ expect(@es.indices.exists_alias(index: "logstash")).to be_truthy
292
+ expect(@es.get_alias(name: "logstash")).to include("logstash-000001")
293
+ end
294
+ end
295
+
296
+ it 'should install it if it is not present' do
297
+ expect{get_policy(@es, LogStash::Outputs::ElasticSearch::DEFAULT_POLICY)}.to raise_error(Elasticsearch::Transport::Transport::Errors::NotFound)
298
+ subject.register
299
+ sleep(1)
300
+ expect{get_policy(@es, LogStash::Outputs::ElasticSearch::DEFAULT_POLICY)}.not_to raise_error
301
+ end
302
+
303
+ it 'should create the default rollover alias' do
304
+ expect(@es.indices.exists_alias(index: "logstash")).to be_falsey
305
+ subject.register
306
+ sleep(1)
307
+ expect(@es.indices.exists_alias(index: "logstash")).to be_truthy
308
+ expect(@es.get_alias(name: "logstash")).to include("logstash-#{todays_date}-000001")
309
+ end
310
+
311
+ it 'should ingest into a single index' do
312
+ subject.register
313
+ subject.multi_receive([
314
+ LogStash::Event.new("message" => "sample message here"),
315
+ LogStash::Event.new("somemessage" => { "message" => "sample nested message here" }),
316
+ LogStash::Event.new("somevalue" => 100),
317
+ ])
318
+
319
+ sleep(6)
320
+
321
+ subject.multi_receive([
322
+ LogStash::Event.new("country" => "us"),
323
+ LogStash::Event.new("country" => "at"),
324
+ LogStash::Event.new("geoip" => { "location" => [ 0.0, 0.0 ] })
325
+ ])
326
+
327
+ @es.indices.refresh
328
+
329
+ # Wait or fail until everything's indexed.
330
+ Stud::try(20.times) do
331
+ r = @es.search
332
+ expect(r).to have_hits(6)
333
+ end
334
+ indexes_written = @es.search['hits']['hits'].each_with_object(Hash.new(0)) do |x, res|
335
+ index_written = x['_index']
336
+ res[index_written] += 1
337
+ end
338
+
339
+ expect(indexes_written.count).to eq(1)
340
+ expect(indexes_written["logstash-#{todays_date}-000001"]).to eq(6)
341
+ end
342
+ end
343
+
344
+ context 'when not using the default policy' do
345
+ let (:ilm_policy_name) {"new_one"}
346
+ let (:settings) { super.merge("ilm_policy" => ilm_policy_name)}
347
+ let (:policy) { small_max_doc_policy }
348
+
349
+ before do
350
+ expect{get_policy(@es, LogStash::Outputs::ElasticSearch::DEFAULT_POLICY)}.to raise_error(Elasticsearch::Transport::Transport::Errors::NotFound)
351
+ put_policy(@es,ilm_policy_name, policy)
352
+ end
353
+
354
+ it 'should not install the default policy if it is not used' do
355
+ subject.register
356
+ sleep(1)
357
+ expect{get_policy(@es, LogStash::Outputs::ElasticSearch::DEFAULT_POLICY)}.to raise_error(Elasticsearch::Transport::Transport::Errors::NotFound)
358
+ end
359
+ end
360
+
361
+ context 'when using a time based policy' do
362
+ let (:ilm_policy_name) {"new_one"}
363
+ let (:settings) { super.merge("ilm_policy" => ilm_policy_name)}
364
+ let (:policy) { max_age_policy("1d") }
365
+
366
+ before do
367
+ expect{get_policy(@es, LogStash::Outputs::ElasticSearch::DEFAULT_POLICY)}.to raise_error(Elasticsearch::Transport::Transport::Errors::NotFound)
368
+ put_policy(@es,ilm_policy_name, policy)
369
+ end
370
+
371
+ it 'should not install the default policy if it is not used' do
372
+ subject.register
373
+ sleep(1)
374
+ expect{get_policy(@es, LogStash::Outputs::ElasticSearch::DEFAULT_POLICY)}.to raise_error(Elasticsearch::Transport::Transport::Errors::NotFound)
375
+ end
376
+ end
377
+
378
+ context 'with the default template' do
379
+ it 'should create the rollover alias' do
380
+ expect(@es.indices.exists_alias(index: expected_index)).to be_falsey
381
+ subject.register
382
+ sleep(1)
383
+ expect(@es.indices.exists_alias(index: expected_index)).to be_truthy
384
+ expect(@es.get_alias(name: expected_index)).to include("#{expected_index}-#{todays_date}-000001")
385
+ end
386
+
387
+ it 'should write the ILM settings into the template' do
388
+ subject.register
389
+ sleep(1)
390
+ expect(@es.indices.get_template(name: "logstash")["logstash"]).to have_index_pattern("logstash-*")
391
+ expect(@es.indices.get_template(name: "logstash")["logstash"]["settings"]['index']['lifecycle']['name']).to eq("logstash-policy")
392
+ expect(@es.indices.get_template(name: "logstash")["logstash"]["settings"]['index']['lifecycle']['rollover_alias']).to eq("logstash")
393
+ end
394
+
395
+ it_behaves_like 'an ILM enabled Logstash'
396
+ end
397
+
398
+ context 'with a set index and a custom index pattern' do
399
+ if ESHelper.es_version_satisfies?(">= 7.0")
400
+ let (:template) { "spec/fixtures/template-with-policy-es7x.json" }
401
+ else
402
+ let (:template) { "spec/fixtures/template-with-policy-es6x.json" }
403
+ end
404
+
405
+ let (:settings) { super.merge("template" => template,
406
+ "index" => "overwrite-4")}
407
+
408
+ it 'should not overwrite the index patterns' do
409
+ subject.register
410
+ sleep(1)
411
+ expect(@es.indices.get_template(name: "logstash")["logstash"]).to have_index_pattern("overwrite-*")
412
+ end
413
+ end
414
+
415
+
416
+ context 'with a custom template' do
417
+ let (:ilm_rollover_alias) { "the_cat_in_the_hat" }
418
+ let (:index) { ilm_rollover_alias }
419
+ let(:expected_index) { index }
420
+ let (:settings) { super.merge("ilm_policy" => ilm_policy_name,
421
+ "template" => template,
422
+ "ilm_rollover_alias" => ilm_rollover_alias)}
423
+
424
+
425
+ if ESHelper.es_version_satisfies?(">= 7.0")
426
+ let (:template) { "spec/fixtures/template-with-policy-es7x.json" }
427
+ else
428
+ let (:template) { "spec/fixtures/template-with-policy-es6x.json" }
429
+ end
430
+ let (:ilm_enabled) { true }
431
+ let (:ilm_policy_name) { "custom-policy" }
432
+ let (:policy) { small_max_doc_policy }
433
+
434
+ before :each do
435
+ put_policy(@es,ilm_policy_name, policy)
436
+ end
437
+
438
+ it_behaves_like 'an ILM enabled Logstash'
439
+
440
+ it 'should create the rollover alias' do
441
+ expect(@es.indices.exists_alias(index: ilm_rollover_alias)).to be_falsey
442
+ subject.register
443
+ sleep(1)
444
+ expect(@es.indices.exists_alias(index: ilm_rollover_alias)).to be_truthy
445
+ expect(@es.get_alias(name: ilm_rollover_alias)).to include("#{ilm_rollover_alias}-#{todays_date}-000001")
446
+ end
447
+
448
+ context 'when the custom rollover alias already exists' do
449
+ it 'should ignore the already exists error' do
450
+ expect(@es.indices.exists_alias(index: ilm_rollover_alias)).to be_falsey
451
+ put_alias(@es, "#{ilm_rollover_alias}-#{todays_date}-000001", ilm_rollover_alias)
452
+ expect(@es.indices.exists_alias(index: ilm_rollover_alias)).to be_truthy
453
+ subject.register
454
+ sleep(1)
455
+ expect(@es.get_alias(name: ilm_rollover_alias)).to include("#{ilm_rollover_alias}-#{todays_date}-000001")
456
+ end
457
+
458
+ end
459
+
460
+ it 'should write the ILM settings into the template' do
461
+ subject.register
462
+ sleep(1)
463
+ expect(@es.indices.get_template(name: ilm_rollover_alias)[ilm_rollover_alias]).to have_index_pattern("#{ilm_rollover_alias}-*")
464
+ expect(@es.indices.get_template(name: ilm_rollover_alias)[ilm_rollover_alias]["settings"]['index']['lifecycle']['name']).to eq(ilm_policy_name)
465
+ expect(@es.indices.get_template(name: ilm_rollover_alias)[ilm_rollover_alias]["settings"]['index']['lifecycle']['rollover_alias']).to eq(ilm_rollover_alias)
466
+ end
467
+
468
+ context 'with a different template_name' do
469
+ let (:template_name) { "custom_template_name" }
470
+ let (:settings) { super.merge('template_name' => template_name)}
471
+
472
+ it_behaves_like 'an ILM enabled Logstash'
473
+
474
+ it 'should write the ILM settings into the template' do
475
+ subject.register
476
+ sleep(1)
477
+ expect(@es.indices.get_template(name: template_name)[template_name]).to have_index_pattern("#{ilm_rollover_alias}-*")
478
+ expect(@es.indices.get_template(name: template_name)[template_name]["settings"]['index']['lifecycle']['name']).to eq(ilm_policy_name)
479
+ expect(@es.indices.get_template(name: template_name)[template_name]["settings"]['index']['lifecycle']['rollover_alias']).to eq(ilm_rollover_alias)
480
+ end
481
+ end
482
+
483
+ end
484
+ end
485
+
486
+ context 'when ilm_enabled is set to "auto"' do
487
+ let (:ilm_enabled) { 'auto' }
488
+
489
+ if ESHelper.es_version_satisfies?(">=7.0")
490
+ context 'when Elasticsearch is version 7 or above' do
491
+ it_behaves_like 'an ILM enabled Logstash'
492
+ end
493
+ end
494
+
495
+ if ESHelper.es_version_satisfies?('< 7.0')
496
+ context 'when Elasticsearch is version 7 or below' do
497
+ it_behaves_like 'an ILM disabled Logstash'
498
+ end
499
+ end
500
+ end
501
+
502
+ context 'when ilm_enabled is the default' do
503
+ let (:settings) { super.tap{|x|x.delete('ilm_enabled')}}
504
+
505
+ if ESHelper.es_version_satisfies?(">=7.0")
506
+ context 'when Elasticsearch is version 7 or above' do
507
+ it_behaves_like 'an ILM enabled Logstash'
508
+ end
509
+ end
510
+
511
+ if ESHelper.es_version_satisfies?('< 7.0')
512
+ context 'when Elasticsearch is version 7 or below' do
513
+ it_behaves_like 'an ILM disabled Logstash'
514
+ end
515
+ end
516
+ end
517
+
518
+ context 'with ilm disabled' do
519
+ let (:settings) { super.merge('ilm_enabled' => false )}
520
+
521
+ it_behaves_like 'an ILM disabled Logstash'
522
+ end
523
+
524
+ context 'with ilm disabled using a string' do
525
+ let (:settings) { super.merge('ilm_enabled' => 'false' )}
526
+
527
+ it_behaves_like 'an ILM disabled Logstash'
528
+ end
529
+
530
+ end
531
+ end