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.
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,197 @@
1
+ require_relative "../../../spec/spec_helper"
2
+ require 'stud/temporary'
3
+
4
+ describe "SSL options" do
5
+ let(:manticore_double) { double("manticoreSSL #{self.inspect}") }
6
+
7
+ let(:settings) { { "ssl_enabled" => true, "hosts" => "localhost", "pool_max" => 1, "pool_max_per_route" => 1 } }
8
+
9
+ subject do
10
+ require "logstash/outputs/elasticsearch"
11
+ LogStash::Outputs::ElasticSearch.new(settings)
12
+ end
13
+
14
+ before do
15
+ allow(manticore_double).to receive(:close)
16
+
17
+ response_double = double("manticore response").as_null_object
18
+ # Allow healtchecks
19
+ allow(manticore_double).to receive(:head).with(any_args).and_return(response_double)
20
+ allow(manticore_double).to receive(:get).with(any_args).and_return(response_double)
21
+ allow(::Manticore::Client).to receive(:new).and_return(manticore_double)
22
+ end
23
+
24
+ after do
25
+ subject.close
26
+ end
27
+
28
+ context "when ssl_verification_mode" do
29
+ context "is set to none" do
30
+ let(:settings) { super().merge(
31
+ "ssl_verification_mode" => 'none',
32
+ ) }
33
+
34
+ it "should print a warning" do
35
+ expect(subject.logger).to receive(:warn).with(/You have enabled encryption but DISABLED certificate verification/).at_least(:once)
36
+ allow(subject.logger).to receive(:warn).with(any_args)
37
+
38
+ subject.register
39
+ allow(LogStash::Outputs::ElasticSearch::HttpClient::Pool).to receive(:start)
40
+ end
41
+
42
+ it "should pass the flag to the ES client" do
43
+ expect(::Manticore::Client).to receive(:new) do |args|
44
+ expect(args[:ssl]).to match hash_including(:enabled => true, :verify => :disable)
45
+ end.and_return(manticore_double)
46
+
47
+ subject.register
48
+ end
49
+ end
50
+
51
+ context "is set to full" do
52
+ let(:settings) { super().merge(
53
+ "ssl_verification_mode" => 'full',
54
+ ) }
55
+
56
+ it "should pass the flag to the ES client" do
57
+ expect(::Manticore::Client).to receive(:new) do |args|
58
+ expect(args[:ssl]).to match hash_including(:enabled => true, :verify => :default)
59
+ end.and_return(manticore_double)
60
+
61
+ subject.register
62
+ end
63
+ end
64
+ end
65
+
66
+ context "with the conflicting configs" do
67
+ context "ssl_certificate_authorities and ssl_truststore_path set" do
68
+ let(:ssl_truststore_path) { Stud::Temporary.file.path }
69
+ let(:ssl_certificate_authorities_path) { Stud::Temporary.file.path }
70
+ let(:settings) { super().merge(
71
+ "ssl_truststore_path" => ssl_truststore_path,
72
+ "ssl_certificate_authorities" => ssl_certificate_authorities_path
73
+ ) }
74
+
75
+ after :each do
76
+ File.delete(ssl_truststore_path)
77
+ File.delete(ssl_certificate_authorities_path)
78
+ end
79
+
80
+ it "should raise a configuration error" do
81
+ expect { subject.register }.to raise_error(LogStash::ConfigurationError, /Use either "ssl_certificate_authorities\/cacert" or "ssl_truststore_path\/truststore"/)
82
+ end
83
+ end
84
+
85
+ context "ssl_certificate and ssl_keystore_path set" do
86
+ let(:ssl_keystore_path) { Stud::Temporary.file.path }
87
+ let(:ssl_certificate_path) { Stud::Temporary.file.path }
88
+ let(:settings) { super().merge(
89
+ "ssl_certificate" => ssl_certificate_path,
90
+ "ssl_keystore_path" => ssl_keystore_path
91
+ ) }
92
+
93
+ after :each do
94
+ File.delete(ssl_keystore_path)
95
+ File.delete(ssl_certificate_path)
96
+ end
97
+
98
+ it "should raise a configuration error" do
99
+ expect { subject.register }.to raise_error(LogStash::ConfigurationError, /Use either "ssl_certificate" or "ssl_keystore_path\/keystore"/)
100
+ end
101
+ end
102
+ end
103
+
104
+ context "when configured with Java store files" do
105
+ let(:ssl_truststore_path) { Stud::Temporary.file.path }
106
+ let(:ssl_keystore_path) { Stud::Temporary.file.path }
107
+
108
+ after :each do
109
+ File.delete(ssl_truststore_path)
110
+ File.delete(ssl_keystore_path)
111
+ end
112
+
113
+ let(:settings) { super().merge(
114
+ "ssl_truststore_path" => ssl_truststore_path,
115
+ "ssl_truststore_type" => "jks",
116
+ "ssl_truststore_password" => "foo",
117
+ "ssl_keystore_path" => ssl_keystore_path,
118
+ "ssl_keystore_type" => "jks",
119
+ "ssl_keystore_password" => "bar",
120
+ "ssl_verification_mode" => "full",
121
+ "ssl_cipher_suites" => ["TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"],
122
+ "ssl_supported_protocols" => ["TLSv1.3"]
123
+ ) }
124
+
125
+ it "should pass the parameters to the ES client" do
126
+ expect(::Manticore::Client).to receive(:new) do |args|
127
+ expect(args[:ssl]).to match hash_including(
128
+ :enabled => true,
129
+ :keystore => ssl_keystore_path,
130
+ :keystore_type => "jks",
131
+ :keystore_password => "bar",
132
+ :truststore => ssl_truststore_path,
133
+ :truststore_type => "jks",
134
+ :truststore_password => "foo",
135
+ :verify => :default,
136
+ :cipher_suites => ["TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"],
137
+ :protocols => ["TLSv1.3"],
138
+ )
139
+ end.and_return(manticore_double)
140
+
141
+ subject.register
142
+ end
143
+ end
144
+
145
+ context "when configured with certificate files" do
146
+ let(:ssl_certificate_authorities_path) { Stud::Temporary.file.path }
147
+ let(:ssl_certificate_path) { Stud::Temporary.file.path }
148
+ let(:ssl_key_path) { Stud::Temporary.file.path }
149
+ let(:settings) { super().merge(
150
+ "ssl_certificate_authorities" => [ssl_certificate_authorities_path],
151
+ "ssl_certificate" => ssl_certificate_path,
152
+ "ssl_key" => ssl_key_path,
153
+ "ssl_verification_mode" => "full",
154
+ "ssl_cipher_suites" => ["TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"],
155
+ "ssl_supported_protocols" => ["TLSv1.3"]
156
+ ) }
157
+
158
+ after :each do
159
+ File.delete(ssl_certificate_authorities_path)
160
+ File.delete(ssl_certificate_path)
161
+ File.delete(ssl_key_path)
162
+ end
163
+
164
+ it "should pass the parameters to the ES client" do
165
+ expect(::Manticore::Client).to receive(:new) do |args|
166
+ expect(args[:ssl]).to match hash_including(
167
+ :enabled => true,
168
+ :ca_file => ssl_certificate_authorities_path,
169
+ :client_cert => ssl_certificate_path,
170
+ :client_key => ssl_key_path,
171
+ :verify => :default,
172
+ :cipher_suites => ["TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"],
173
+ :protocols => ["TLSv1.3"],
174
+ )
175
+ end.and_return(manticore_double)
176
+
177
+ subject.register
178
+ end
179
+
180
+ context "and only the ssl_certificate is set" do
181
+ let(:settings) { super().reject { |k| "ssl_key".eql?(k) } }
182
+
183
+ it "should raise a configuration error" do
184
+ expect { subject.register }.to raise_error(LogStash::ConfigurationError, /Using an "ssl_certificate" requires an "ssl_key"/)
185
+ end
186
+ end
187
+
188
+ context "and only the ssl_key is set" do
189
+ let(:settings) { super().reject { |k| "ssl_certificate".eql?(k) } }
190
+
191
+ it "should raise a configuration error" do
192
+ expect { subject.register }.to raise_error(LogStash::ConfigurationError, /An "ssl_certificate" is required when using an "ssl_key"/)
193
+ end
194
+ end
195
+ end
196
+ end
197
+
@@ -0,0 +1,56 @@
1
+ require "logstash/outputs/elasticsearch"
2
+ require_relative "../../../spec/es_spec_helper"
3
+
4
+ describe "whitelisting error types in expected behavior" do
5
+ let(:template) { '{"template" : "not important, will be updated by :index"}' }
6
+ let(:event1) { LogStash::Event.new("somevalue" => 100, "@timestamp" => "2014-11-17T20:37:17.223Z") }
7
+ let(:action1) { ["index", {:_id=>1, :routing=>nil, :_index=>"logstash-2014.11.17", :_type=> doc_type }, event1] }
8
+ let(:settings) { {"manage_template" => true, "index" => "logstash-2014.11.17", "template_overwrite" => true, "hosts" => get_host_port() } }
9
+
10
+ subject { LogStash::Outputs::ElasticSearch.new(settings) }
11
+
12
+ before :each do
13
+ allow(subject.logger).to receive(:warn)
14
+ allow(subject).to receive(:maximum_seen_major_version).and_return(0)
15
+ allow(subject).to receive(:alive_urls_count).and_return(1)
16
+ allow(subject).to receive(:finish_register)
17
+
18
+ subject.register
19
+
20
+ allow(subject.client).to receive(:get_xpack_info)
21
+ allow(subject.client).to receive(:bulk).and_return(
22
+ {
23
+ "errors" => true,
24
+ "items" => [{
25
+ "create" => {
26
+ "status" => 409,
27
+ "error" => {
28
+ "type" => "document_already_exists_exception",
29
+ "reason" => "[shard] document already exists"
30
+ }
31
+ }
32
+ }]
33
+ })
34
+
35
+ subject.multi_receive([event1])
36
+ end
37
+
38
+ after :each do
39
+ subject.close
40
+ end
41
+
42
+ describe "when failure logging is enabled for everything" do
43
+ it "should log a failure on the action" do
44
+ expect(subject.logger).to have_received(:warn).with("Failed action", anything)
45
+ end
46
+ end
47
+
48
+ describe "when failure logging is disabled for document exists error" do
49
+ let(:settings) { super().merge("silence_errors_in_log" => ["document_already_exists_exception"]) }
50
+
51
+ it "should log a failure on the action" do
52
+ expect(subject.logger).not_to have_received(:warn).with("Failed action", anything)
53
+ end
54
+ end
55
+
56
+ end
@@ -0,0 +1,57 @@
1
+ require "logstash/devutils/rspec/spec_helper"
2
+ require "logstash/outputs/elasticsearch/http_client"
3
+ require "logstash/outputs/elasticsearch/license_checker"
4
+
5
+ describe LogStash::Outputs::ElasticSearch::LicenseChecker do
6
+
7
+ # Note that the actual license checking logic is spec'ed in pool_spec.rb
8
+
9
+ context "LicenseChecker API required by Pool class" do
10
+ subject { described_class }
11
+
12
+ it "defines the appropriate_license? methods" do
13
+ expect(subject.instance_methods).to include(:appropriate_license?)
14
+ end
15
+ end
16
+
17
+ context "Pool class API required by the LicenseChecker" do
18
+ subject { LogStash::Outputs::ElasticSearch::HttpClient::Pool }
19
+
20
+ it "contains the get_license method" do
21
+ expect(LogStash::Outputs::ElasticSearch::HttpClient::Pool.instance_methods).to include(:get_license)
22
+ end
23
+ end
24
+
25
+ context "appropriate license" do
26
+ let(:logger) { double("logger") }
27
+ let(:url) { LogStash::Util::SafeURI.new("https://cloud.elastic.co") }
28
+ let(:pool) { double("pool") }
29
+ subject { described_class.new(logger) }
30
+
31
+ it "is true when connect to serverless" do
32
+ allow(pool).to receive(:serverless?).and_return(true)
33
+ expect(subject.appropriate_license?(pool, url)).to eq true
34
+ end
35
+
36
+ it "is true when license status is active" do
37
+ allow(pool).to receive(:serverless?).and_return(false)
38
+ allow(pool).to receive(:get_license).with(url).and_return(LogStash::Json.load File.read("spec/fixtures/license_check/active.json"))
39
+ expect(subject.appropriate_license?(pool, url)).to eq true
40
+ end
41
+
42
+ it "is true when license status is inactive" do
43
+ allow(logger).to receive(:warn).with(instance_of(String), anything)
44
+ allow(pool).to receive(:serverless?).and_return(false)
45
+ allow(pool).to receive(:get_license).with(url).and_return(LogStash::Json.load File.read("spec/fixtures/license_check/inactive.json"))
46
+ expect(subject.appropriate_license?(pool, url)).to eq true
47
+ end
48
+
49
+ it "is false when no license return" do
50
+ allow(logger).to receive(:error).with(instance_of(String), anything)
51
+ allow(pool).to receive(:serverless?).and_return(false)
52
+ allow(pool).to receive(:get_license).with(url).and_return(LogStash::Json.load('{}'))
53
+ expect(subject.appropriate_license?(pool, url)).to eq false
54
+ end
55
+ end
56
+ end
57
+