logstash-output-elasticsearch-test 10.3.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.
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