logstash-filter-elasticsearch 3.9.4 → 3.11.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3264c43657eea13f942de4c005f0996dfc30e845cf7643fe374ec6918d400d83
4
- data.tar.gz: bfdb2268299b87ed893d778411c450c1758977cd2e2e3c051e0679aa9467fd37
3
+ metadata.gz: 7d5a56362567a5c8949cb77f1615659c709449c5999fe46e5b558212045d3197
4
+ data.tar.gz: ba77cec6eda6ea51f037541223d257532a5161081cf64609c2ea6590c6d37ed4
5
5
  SHA512:
6
- metadata.gz: 759cb7f87175ac2894adc715e108399fd6d27af1cae91fdf91bd05aa5312678e9963fde3c36a25519b6eac3b53a326ed203583a1f22a94fdd66239014ddf2433
7
- data.tar.gz: 5dda79137366f9d40d1fddf21b6eb92da6377187eb470d3e725b1cfb338bd1e2f2296263e67fec7f10bf7b9a4d611bcca243d393235727ffef200264da5ef4c9
6
+ metadata.gz: 8b3415eb21cb9e6bbe25b692514037cdae4c5a64827e99412433b4bf184308fca1a6e307e1b724f0ba7b6c311e2b463346189d6176e78c56941e4dc0af0d8b9b
7
+ data.tar.gz: 24dad4a1105f97e5c55f94c281d62091db76020c27242253e3307946db755e1093a41c751d175fd23ed07fcb01890e8753fd54691d854b0f456792adbd667b18
data/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## 3.11.1
2
+ - Fix: hosts => "es_host:port" regression [#156](https://github.com/logstash-plugins/logstash-filter-elasticsearch/pull/156)
3
+
4
+ ## 3.11.0
5
+ - Feat: update Elasticsearch client to 7.14.0 [#150](https://github.com/logstash-plugins/logstash-filter-elasticsearch/pull/150)
6
+
7
+ ## 3.10.0
8
+ - Feat: add user-agent header passed to the Elasticsearch HTTP connection [#152](https://github.com/logstash-plugins/logstash-filter-elasticsearch/pull/152)
9
+
10
+ ## 3.9.5
11
+ - Fixed SSL handshake hang indefinitely with proxy setup [#151](https://github.com/logstash-plugins/logstash-filter-elasticsearch/pull/151)
12
+
1
13
  ## 3.9.4
2
14
  - Fix: a regression (in LS 7.14.0) where due the elasticsearch client update (from 5.0.5 to 7.5.0) the `Authorization`
3
15
  header isn't passed, this leads to the plugin not being able to leverage `user`/`password` credentials set by the user.
data/Gemfile CHANGED
@@ -9,3 +9,6 @@ if Dir.exist?(logstash_path) && use_logstash_source
9
9
  gem 'logstash-core', :path => "#{logstash_path}/logstash-core"
10
10
  gem 'logstash-core-plugin-api', :path => "#{logstash_path}/logstash-core-plugin-api"
11
11
  end
12
+
13
+ gem 'manticore', ENV['MANTICORE_VERSION'] if ENV['MANTICORE_VERSION']
14
+ gem 'elasticsearch', ENV['ELASTICSEARCH_VERSION'] if ENV['ELASTICSEARCH_VERSION']
@@ -16,15 +16,17 @@ module LogStash
16
16
  password = options.fetch(:password, nil)
17
17
  api_key = options.fetch(:api_key, nil)
18
18
  proxy = options.fetch(:proxy, nil)
19
+ user_agent = options[:user_agent]
19
20
 
20
21
  transport_options = {:headers => {}}
21
22
  transport_options[:headers].merge!(setup_basic_auth(user, password))
22
23
  transport_options[:headers].merge!(setup_api_key(api_key))
24
+ transport_options[:headers].merge!({ 'user-agent' => "#{user_agent}" })
23
25
 
24
26
  logger.warn "Supplied proxy setting (proxy => '') has no effect" if @proxy.eql?('')
25
27
  transport_options[:proxy] = proxy.to_s if proxy && !proxy.eql?('')
26
28
 
27
- hosts = hosts.map { |host| { host: host, scheme: 'https' } } if ssl
29
+ hosts = setup_hosts(hosts, ssl)
28
30
  # set ca_file even if ssl isn't on, since the host can be an https url
29
31
  ssl_options = { ssl: true, ca_file: options[:ca_file] } if options[:ca_file]
30
32
  ssl_options ||= {}
@@ -39,6 +41,17 @@ module LogStash
39
41
 
40
42
  private
41
43
 
44
+ def setup_hosts(hosts, ssl)
45
+ hosts.map do |h|
46
+ if h.start_with?('http:/', 'https:/')
47
+ h
48
+ else
49
+ host, port = h.split(':')
50
+ { host: host, port: port, scheme: (ssl ? 'https' : 'http') }
51
+ end
52
+ end
53
+ end
54
+
42
55
  def setup_basic_auth(user, password)
43
56
  return {} unless user && password && password.value
44
57
 
@@ -20,7 +20,18 @@ if es_client_version >= Gem::Version.new('7.2') && es_client_version < Gem::Vers
20
20
  def apply_headers(request_options, options)
21
21
  headers = (options && options[:headers]) || {}
22
22
  headers[CONTENT_TYPE_STR] = find_value(headers, CONTENT_TYPE_REGEX) || DEFAULT_CONTENT_TYPE
23
- headers[USER_AGENT_STR] = find_value(headers, USER_AGENT_REGEX) || user_agent_header
23
+
24
+ # this code is necessary to grab the correct user-agent header
25
+ # when this method is invoked with apply_headers(@request_options, options)
26
+ # from https://github.com/elastic/elasticsearch-ruby/blob/v7.14.0/elasticsearch-transport/lib/elasticsearch/transport/transport/http/manticore.rb#L113-L114
27
+ transport_user_agent = nil
28
+ if (options && options[:transport_options] && options[:transport_options][:headers])
29
+ transport_headers = {}
30
+ transport_headers = options[:transport_options][:headers]
31
+ transport_user_agent = find_value(transport_headers, USER_AGENT_REGEX)
32
+ end
33
+
34
+ headers[USER_AGENT_STR] = transport_user_agent || find_value(headers, USER_AGENT_REGEX) || user_agent_header
24
35
  headers[ACCEPT_ENCODING] = GZIP if use_compression?
25
36
  (request_options[:headers] ||= {}).merge!(headers) # this line was changed
26
37
  end
@@ -176,6 +176,19 @@ class LogStash::Filters::Elasticsearch < LogStash::Filters::Base
176
176
  end
177
177
  end # def filter
178
178
 
179
+ # public only to be reuse in testing
180
+ def prepare_user_agent
181
+ os_name = java.lang.System.getProperty('os.name')
182
+ os_version = java.lang.System.getProperty('os.version')
183
+ os_arch = java.lang.System.getProperty('os.arch')
184
+ jvm_vendor = java.lang.System.getProperty('java.vendor')
185
+ jvm_version = java.lang.System.getProperty('java.version')
186
+
187
+ plugin_version = Gem.loaded_specs['logstash-filter-elasticsearch'].version
188
+ # example: logstash/7.14.1 (OS=Linux-5.4.0-84-generic-amd64; JVM=AdoptOpenJDK-11.0.11) logstash-output-elasticsearch/11.0.1
189
+ "logstash/#{LOGSTASH_VERSION} (OS=#{os_name}-#{os_version}-#{os_arch}; JVM=#{jvm_vendor}-#{jvm_version}) logstash-#{@plugin_type}-#{config_name}/#{plugin_version}"
190
+ end
191
+
179
192
  private
180
193
 
181
194
  def client_options
@@ -192,7 +205,11 @@ class LogStash::Filters::Elasticsearch < LogStash::Filters::Base
192
205
  def new_client
193
206
  # NOTE: could pass cloud-id/cloud-auth to client but than we would need to be stricter on ES version requirement
194
207
  # and also LS parsing might differ from ES client's parsing so for consistency we do not pass cloud options ...
195
- LogStash::Filters::ElasticsearchClient.new(@logger, @hosts, client_options)
208
+ opts = client_options
209
+
210
+ opts[:user_agent] = prepare_user_agent
211
+
212
+ LogStash::Filters::ElasticsearchClient.new(@logger, @hosts, opts)
196
213
  end
197
214
 
198
215
  def get_client
@@ -303,6 +320,10 @@ class LogStash::Filters::Elasticsearch < LogStash::Filters::Base
303
320
  end
304
321
 
305
322
  def test_connection!
306
- get_client.client.ping
323
+ begin
324
+ get_client.client.ping
325
+ rescue Elasticsearch::UnsupportedProductError
326
+ raise LogStash::ConfigurationError, "Could not connect to a compatible version of Elasticsearch"
327
+ end
307
328
  end
308
329
  end #class LogStash::Filters::Elasticsearch
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
 
3
3
  s.name = 'logstash-filter-elasticsearch'
4
- s.version = '3.9.4'
4
+ s.version = '3.11.1'
5
5
  s.licenses = ['Apache License (2.0)']
6
6
  s.summary = "Copies fields from previous log events in Elasticsearch to current events "
7
7
  s.description = "This gem is a Logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This gem is not a stand-alone program"
@@ -21,8 +21,10 @@ Gem::Specification.new do |s|
21
21
 
22
22
  # Gem dependencies
23
23
  s.add_runtime_dependency "logstash-core-plugin-api", ">= 1.60", "<= 2.99"
24
- s.add_runtime_dependency 'elasticsearch', ">= 5.0.5" # LS >= 6.7 and < 7.14 all used version 5.0.5
25
- s.add_runtime_dependency 'manticore', "~> 0.6"
24
+ s.add_runtime_dependency 'elasticsearch', ">= 7.14.0" # LS >= 6.7 and < 7.14 all used version 5.0.5
25
+ s.add_runtime_dependency 'manticore', ">= 0.7.1"
26
+ s.add_development_dependency 'cabin', ['~> 0.6']
27
+ s.add_development_dependency 'webrick'
26
28
 
27
29
  s.add_development_dependency 'logstash-devutils'
28
30
  end
data/spec/es_helper.rb CHANGED
@@ -7,12 +7,26 @@ module ESHelper
7
7
  end
8
8
  end
9
9
 
10
- def self.get_client(credentials)
11
- require 'elasticsearch/transport/transport/http/faraday' # supports user/password options
12
- host, port = get_host_port.split(':')
13
- host_opts = credentials.inject({}) { |h, (k, v)| h[k.to_sym] = v; h } # user: _, password: _
14
- host_opts.merge! host: host, port: port, scheme: 'http'
15
- Elasticsearch::Client.new(hosts: [host_opts], transport_class: Elasticsearch::Transport::Transport::HTTP::Faraday)
10
+ def self.curl_and_get_json_response(url, method: :get, args: nil); require 'open3'
11
+ cmd = "curl -s -v --show-error #{args} -X #{method.to_s.upcase} -k #{url}"
12
+ begin
13
+ out, err, status = Open3.capture3(cmd)
14
+ rescue Errno::ENOENT
15
+ fail "curl not available, make sure curl binary is installed and available on $PATH"
16
+ end
17
+
18
+ if status.success?
19
+ http_status = err.match(/< HTTP\/1.1 (.*?)/)[1] || '0' # < HTTP/1.1 200 OK\r\n
20
+ if http_status.strip[0].to_i > 2
21
+ warn out
22
+ fail "#{cmd.inspect} unexpected response: #{http_status}\n\n#{err}"
23
+ end
24
+
25
+ LogStash::Json.load(out)
26
+ else
27
+ warn out
28
+ fail "#{cmd.inspect} process failed: #{status}\n\n#{err}"
29
+ end
16
30
  end
17
31
 
18
32
  def self.doc_type
@@ -25,12 +39,6 @@ module ESHelper
25
39
  end
26
40
  end
27
41
 
28
- def self.index_doc(es, params)
29
- type = doc_type
30
- params[:type] = doc_type unless type.nil?
31
- es.index(params)
32
- end
33
-
34
42
  def self.es_version
35
43
  ENV['ES_VERSION'] || ENV['ELASTIC_STACK_VERSION']
36
44
  end
@@ -3,18 +3,47 @@ require "logstash/devutils/rspec/spec_helper"
3
3
  require "logstash/plugin"
4
4
  require "logstash/filters/elasticsearch"
5
5
  require "logstash/json"
6
+ require "cabin"
7
+ require "webrick"
8
+ require "uri"
6
9
 
7
10
  describe LogStash::Filters::Elasticsearch do
8
11
 
12
+ subject(:plugin) { described_class.new(config) }
13
+
14
+ let(:event) { LogStash::Event.new({}) }
15
+
9
16
  context "registration" do
10
17
 
11
18
  let(:plugin) { LogStash::Plugin.lookup("filter", "elasticsearch").new({}) }
12
- before do
13
- allow(plugin).to receive(:test_connection!)
19
+
20
+ context "against authentic Elasticsearch" do
21
+ before do
22
+ allow(plugin).to receive(:test_connection!)
23
+ end
24
+
25
+ it "should not raise an exception" do
26
+ expect {plugin.register}.to_not raise_error
27
+ end
14
28
  end
15
29
 
16
- it "should not raise an exception" do
17
- expect {plugin.register}.to_not raise_error
30
+ context "against not authentic Elasticsearch" do
31
+ let(:failing_client) do
32
+ client = double("client")
33
+ allow(client).to receive(:ping).and_raise Elasticsearch::UnsupportedProductError
34
+
35
+ client_wrapper = double("filter_client")
36
+ allow(client_wrapper).to receive(:client).and_return client
37
+ client_wrapper
38
+ end
39
+
40
+ before do
41
+ allow(plugin).to receive(:get_client).and_return(failing_client)
42
+ end
43
+
44
+ it "should raise ConfigurationError" do
45
+ expect {plugin.register}.to raise_error(LogStash::ConfigurationError)
46
+ end
18
47
  end
19
48
  end
20
49
 
@@ -28,8 +57,6 @@ describe LogStash::Filters::Elasticsearch do
28
57
  "aggregation_fields" => { "bytes_avg" => "bytes_avg_ls_field" }
29
58
  }
30
59
  end
31
- let(:plugin) { described_class.new(config) }
32
- let(:event) { LogStash::Event.new({}) }
33
60
 
34
61
  let(:response) do
35
62
  LogStash::Json.load(File.read(File.join(File.dirname(__FILE__), "fixtures", "request_x_1.json")))
@@ -291,6 +318,112 @@ describe LogStash::Filters::Elasticsearch do
291
318
  end
292
319
  end
293
320
 
321
+ class StoppableServer
322
+
323
+ attr_reader :port
324
+
325
+ def initialize()
326
+ queue = Queue.new
327
+ @first_req_waiter = java.util.concurrent.CountDownLatch.new(1)
328
+ @first_request = nil
329
+
330
+ @t = java.lang.Thread.new(
331
+ proc do
332
+ begin
333
+ @server = WEBrick::HTTPServer.new :Port => 0, :DocumentRoot => ".",
334
+ :Logger => Cabin::Channel.get, # silence WEBrick logging
335
+ :StartCallback => Proc.new {
336
+ queue.push("started")
337
+ }
338
+ @port = @server.config[:Port]
339
+ @server.mount_proc '/' do |req, res|
340
+ res.body = '''
341
+ {
342
+ "name": "ce7ccfb438e8",
343
+ "cluster_name": "docker-cluster",
344
+ "cluster_uuid": "DyR1hN03QvuCWXRy3jtb0g",
345
+ "version": {
346
+ "number": "7.13.1",
347
+ "build_flavor": "default",
348
+ "build_type": "docker",
349
+ "build_hash": "9a7758028e4ea59bcab41c12004603c5a7dd84a9",
350
+ "build_date": "2021-05-28T17:40:59.346932922Z",
351
+ "build_snapshot": false,
352
+ "lucene_version": "8.8.2",
353
+ "minimum_wire_compatibility_version": "6.8.0",
354
+ "minimum_index_compatibility_version": "6.0.0-beta1"
355
+ },
356
+ "tagline": "You Know, for Search"
357
+ }
358
+ '''
359
+ res.status = 200
360
+ res['Content-Type'] = 'application/json'
361
+ @first_request = req
362
+ @first_req_waiter.countDown()
363
+ end
364
+
365
+ @server.start
366
+ rescue => e
367
+ puts "Error in webserver thread #{e}"
368
+ # ignore
369
+ end
370
+ end
371
+ )
372
+ @t.daemon = true
373
+ @t.start
374
+ queue.pop # blocks until the server is up
375
+ end
376
+
377
+ def stop
378
+ @server.shutdown
379
+ end
380
+
381
+ def wait_receive_request
382
+ @first_req_waiter.await(2, java.util.concurrent.TimeUnit::SECONDS)
383
+ @first_request
384
+ end
385
+ end
386
+
387
+ describe "user-agent header" do
388
+ let!(:webserver) { StoppableServer.new } # webserver must be started before the call, so no lazy "let"
389
+
390
+ after :each do
391
+ webserver.stop
392
+ end
393
+
394
+ it "server should be started" do
395
+ require 'net/http'
396
+ response = nil
397
+ Net::HTTP.start('localhost', webserver.port) {|http|
398
+ response = http.request_get('/')
399
+ }
400
+ expect(response.code.to_i).to eq(200)
401
+ end
402
+
403
+ context "used by plugin" do
404
+ let(:config) do
405
+ {
406
+ "hosts" => ["localhost:#{webserver.port}"],
407
+ "query" => "response: 404",
408
+ "fields" => { "response" => "code" },
409
+ "docinfo_fields" => { "_index" => "es_index" },
410
+ "aggregation_fields" => { "bytes_avg" => "bytes_avg_ls_field" }
411
+ }
412
+ end
413
+ let(:plugin) { described_class.new(config) }
414
+ let(:event) { LogStash::Event.new({}) }
415
+
416
+ it "client should sent the expect user-agent" do
417
+ plugin.register
418
+
419
+ request = webserver.wait_receive_request
420
+
421
+ expect(request.header['user-agent'].size).to eq(1)
422
+ expect(request.header['user-agent'][0]).to match(/logstash\/\d*\.\d*\.\d* \(OS=.*; JVM=.*\) logstash-filter-elasticsearch\/\d*\.\d*\.\d*/)
423
+ end
424
+ end
425
+ end
426
+
294
427
  describe "client" do
295
428
  let(:config) do
296
429
  {
@@ -438,7 +571,9 @@ describe LogStash::Filters::Elasticsearch do
438
571
  it "should set localhost:9200 as hosts" do
439
572
  plugin.register
440
573
  client = plugin.send(:get_client).client
441
- expect( extract_transport(client).hosts ).to eql [{ :host => "localhost", :port => 9200, :protocol => "http"}]
574
+ hosts = extract_transport(client).hosts
575
+ expect( hosts.size ).to be 1
576
+ expect( hosts[0] ).to include(:host => "localhost", :port => 9200, :scheme => "http")
442
577
  end
443
578
  end
444
579
 
@@ -0,0 +1,20 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDSTCCAjGgAwIBAgIUUcAg9c8B8jiliCkOEJyqoAHrmccwDQYJKoZIhvcNAQEL
3
+ BQAwNDEyMDAGA1UEAxMpRWxhc3RpYyBDZXJ0aWZpY2F0ZSBUb29sIEF1dG9nZW5l
4
+ cmF0ZWQgQ0EwHhcNMjEwODEyMDUxNDU1WhcNMjQwODExMDUxNDU1WjA0MTIwMAYD
5
+ VQQDEylFbGFzdGljIENlcnRpZmljYXRlIFRvb2wgQXV0b2dlbmVyYXRlZCBDQTCC
6
+ ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK1HuusRuGNsztd4EQvqwcMr
7
+ 8XvnNNaalerpMOorCGySEFrNf0HxDIVMGMCrOv1F8SvlcGq3XANs2MJ4F2xhhLZr
8
+ PpqVHx+QnSZ66lu5R89QVSuMh/dCMxhNBlOA/dDlvy+EJBl9H791UGy/ChhSgaBd
9
+ OKVyGkhjErRTeMIq7rR7UG6GL/fV+JGy41UiLrm1KQP7/XVD9UzZfGq/hylFkTPe
10
+ oox5BUxdxUdDZ2creOID+agtIYuJVIkelKPQ+ljBY3kWBRexqJQsvyNUs1gZpjpz
11
+ YUCzuVcXDRuJXYQXGqWXhsBPfJv+ZcSyMIBUfWT/G13cWU1iwufPy0NjajowPZsC
12
+ AwEAAaNTMFEwHQYDVR0OBBYEFMgkye5+2l+TE0I6RsXRHjGBwpBGMB8GA1UdIwQY
13
+ MBaAFMgkye5+2l+TE0I6RsXRHjGBwpBGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
14
+ hvcNAQELBQADggEBAIgtJW8sy5lBpzPRHkmWSS/SCZIPsABW+cHqQ3e0udrI3CLB
15
+ G9n7yqAPWOBTbdqC2GM8dvAS/Twx4Bub/lWr84dFCu+t0mQq4l5kpJMVRS0KKXPL
16
+ DwJbUN3oPNYy4uPn5Xi+XY3BYFce5vwJUsqIxeAbIOxVTNx++k5DFnB0ESAM23QL
17
+ sgUZl7xl3/DkdO4oHj30gmTRW9bjCJ6umnHIiO3JoJatrprurUIt80vHC4Ndft36
18
+ NBQ9mZpequ4RYjpSZNLcVsxyFAYwEY4g8MvH0MoMo2RRLfehmMCzXnI/Wh2qEyYz
19
+ emHprBii/5y1HieKXlX9CZRb5qEPHckDVXW3znw=
20
+ -----END CERTIFICATE-----
@@ -0,0 +1,27 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIIEowIBAAKCAQEArUe66xG4Y2zO13gRC+rBwyvxe+c01pqV6ukw6isIbJIQWs1/
3
+ QfEMhUwYwKs6/UXxK+VwardcA2zYwngXbGGEtms+mpUfH5CdJnrqW7lHz1BVK4yH
4
+ 90IzGE0GU4D90OW/L4QkGX0fv3VQbL8KGFKBoF04pXIaSGMStFN4wirutHtQboYv
5
+ 99X4kbLjVSIuubUpA/v9dUP1TNl8ar+HKUWRM96ijHkFTF3FR0NnZyt44gP5qC0h
6
+ i4lUiR6Uo9D6WMFjeRYFF7GolCy/I1SzWBmmOnNhQLO5VxcNG4ldhBcapZeGwE98
7
+ m/5lxLIwgFR9ZP8bXdxZTWLC58/LQ2NqOjA9mwIDAQABAoIBABmBC0P6Ebegljkk
8
+ lO26GdbOKvbfqulDS3mN5QMyXkUMopea03YzMnKUJriE+2O33a1mUcuDPWnLpYPK
9
+ BTiQieYHlulNtY0Bzf+R69igRq9+1WpZftGnzrlu7NVxkOokRqWJv3546ilV7QZ0
10
+ f9ngmu+tiN7hEnlBC8m613VMuGGb3czwbCizEVZxlZX0Dk2GExbH7Yf3NNs/aOP/
11
+ 8x6CqgL+rhrtOQ80xwRrOlEF8oSSjXCzypa3nFv21YO3J2lVo4BoIwnHgOzyz46A
12
+ b37gekqXXajIYQ0HAB+NDgVoCRFFJ7Xe16mgB3DpyUpUJzwiMedJkeQ0TprIownQ
13
+ +1mPe9ECgYEA/K4jc0trr3sk8KtcZjOYdpvwrhEqSSGEPeGfFujZaKOb8PZ8PX6j
14
+ MbCTV12nEgm8FEhZQ3azxLnO17gbJ2A+Ksm/IIwnTWlqvvMZD5qTQ7L3qZuCtbWQ
15
+ +EGC/H1SDjhiwvjHcXP61/tYL/peApBSoj0L4kC+U/VaNyvicudKk08CgYEAr46J
16
+ 4VJBJfZ4ZaUBRy53+fy+mknOfaj2wo8MnD3u+/x4YWTapqvDOPN2nJVtKlIsxbS4
17
+ qCO+fzUV17YHlsQmGULNbtFuXWJkP/RcLVbe8VYg/6tmk0dJwNAe90flagX2KJov
18
+ 8eDX129nNpuUqrNNWsfeLmPmH6vUzpKlga+1zfUCgYBrbUHHJ96dmbZn2AMNtIvy
19
+ iXP3HXcj5msJwB3aKJ8eHMkU1kaWAnwxiQfrkfaQ9bCP0v6YbyQY1IJ7NlvdDs7/
20
+ dAydMtkW0WW/zyztdGN92d3vrx0QUiRTV87vt/wl7ZUXnZt1wcB5CPRCWaiUYHWx
21
+ YlDmHW6N1XdIk5DQF0OegwKBgEt7S8k3Zo9+A5IgegYy8p7njsQjy8a3qTFJ9DAR
22
+ aPmrOc8WX/SdkVihRXRZwxAZOOrgoyyYAcYL+xI+T9EBESh3UoC9R2ibb2MYG7Ha
23
+ 0gyN7a4/8eCNHCbs1QOZRAhr+8TFVqv28pbMbWJLToZ+hVns6Zikl0MyzFLtNoAm
24
+ HlMpAoGBAIOkqnwwuRKhWprL59sdcJfWY26os9nvuDV4LoKFNEFLJhj2AA2/3UlV
25
+ v85gqNSxnMNlHLZC9l2HZ3mKv/mfx1aikmFvyhJAnk5u0f9KkexmCPLjQzS5q3ba
26
+ yFuxK2DXwN4x46RgQPFlLjOTCX0BG6rkEu4JdonF8ETSjoCtGEU8
27
+ -----END RSA PRIVATE KEY-----
@@ -0,0 +1,20 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDNjCCAh6gAwIBAgIUF9wE+oqGSbm4UVn1y9gEjzyaJFswDQYJKoZIhvcNAQEL
3
+ BQAwNDEyMDAGA1UEAxMpRWxhc3RpYyBDZXJ0aWZpY2F0ZSBUb29sIEF1dG9nZW5l
4
+ cmF0ZWQgQ0EwHhcNMjEwODEyMDUxNTI3WhcNMjQwODExMDUxNTI3WjANMQswCQYD
5
+ VQQDEwJlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK2S2by0lgyu
6
+ 1JfgGgZ41PNXbH2qMPMzowguVVdtZ16WM0CaEG7lnLxmMcC+2Q7NnGuFnPAVQo9T
7
+ Q3bh7j+1PkCJVHUKZfJIeWtGc9+qXBcO1MhedfwM1osSa4bfwM85G+XKWbRNtmSt
8
+ CoUuKArIyZkzdBAAQLBoQyPf3DIza1Au4j9Hb3zrswD6e7n2PN4ffIyil1GFduLJ
9
+ 2275qqFiOhkEDUhv7BKNftVBh/89O/5lSqAQGuQ1aDRr8TdHwhO71u4ZIU/Pn6yX
10
+ LGBWrQG53+qpdCsxGvJTfbtIEYUDTN83CirIxDKJgc1QXOEldylztHf4xnQ7ZarJ
11
+ tqF6pUzHbRsCAwEAAaNnMGUwHQYDVR0OBBYEFFQUK+6Cg2kExRj1xSDzEi4kkgKX
12
+ MB8GA1UdIwQYMBaAFMgkye5+2l+TE0I6RsXRHjGBwpBGMBgGA1UdEQQRMA+CDWVs
13
+ YXN0aWNzZWFyY2gwCQYDVR0TBAIwADANBgkqhkiG9w0BAQsFAAOCAQEAinaknZIc
14
+ 7xtQNwUwa+kdET+I4lMz+TJw9vTjGKPJqe082n81ycKU5b+a/OndG90z+dTwhShW
15
+ f0oZdIe/1rDCdiRU4ceCZA4ybKrFDIbW8gOKZOx9rsgEx9XNELj4ocZTBqxjQmNE
16
+ Ho91fli5aEm0EL2vJgejh4hcfDeElQ6go9gtvAHQ57XEADQSenvt69jOICOupnS+
17
+ LSjDVhv/VLi3CAip0B+lD5fX/DVQdrJ62eRGuQYxoouE3saCO58qUUrKB39yD9KA
18
+ qRA/sVxyLogxaU+5dLfc0NJdOqSzStxQ2vdMvAWo9tZZ2UBGFrk5SdwCQe7Yv5mX
19
+ qi02i4q6meHGcw==
20
+ -----END CERTIFICATE-----
@@ -0,0 +1,27 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIIEowIBAAKCAQEArZLZvLSWDK7Ul+AaBnjU81dsfaow8zOjCC5VV21nXpYzQJoQ
3
+ buWcvGYxwL7ZDs2ca4Wc8BVCj1NDduHuP7U+QIlUdQpl8kh5a0Zz36pcFw7UyF51
4
+ /AzWixJrht/Azzkb5cpZtE22ZK0KhS4oCsjJmTN0EABAsGhDI9/cMjNrUC7iP0dv
5
+ fOuzAPp7ufY83h98jKKXUYV24snbbvmqoWI6GQQNSG/sEo1+1UGH/z07/mVKoBAa
6
+ 5DVoNGvxN0fCE7vW7hkhT8+frJcsYFatAbnf6ql0KzEa8lN9u0gRhQNM3zcKKsjE
7
+ MomBzVBc4SV3KXO0d/jGdDtlqsm2oXqlTMdtGwIDAQABAoIBAQCm/VBDz41ImG7p
8
+ yu3e6iMeFi7HW5SKdlRUS5dJbHT1uBWJAm/q8TbwvnUBVdsn9cKWY06QYDPQBjAy
9
+ 0LxRSIKivjyl+aIJDZbbEUXrmk/M0zT9rHtgSc2isM8ITH6IHw5q7lmNMPLYOu6T
10
+ IMvfTDtADBOOTV/vF+/4NKf5GCUXVt1XTzLBFMK0p/ZoI7Fsw7fhH6FR12vk0xA4
11
+ BEC4pwRbGfHo7P31ii0by8epkve93tF4IZuFmN92A84bN1z7Kc4TYaSbua2rgguz
12
+ FzMyWpsTxr363HzCK1xOJb6JyJOiXbq4+j2oqtne3GIvyozJeiyKRgjLIMoe/LV7
13
+ fPPc5wlhAoGBAOD3z0JH2eyR/1RHILFsWInH2nDbKHHuCjhFIL2XloeXsJkiJZ95
14
+ BpdjExMZCqD44tPNRW/GgWKwoVwltm6zB0aq0aW/OfOzw6fhKt1W+go47L7Tpwap
15
+ VQgy6BFXSueUKfQDlZEWV4E2gakf8vOl0/VRQExae/CeKf1suEedQaErAoGBAMWE
16
+ LOmNDEU2NFqghfNBAFYyFJst3YnBmSmlL7W22+OsfSK/PhxnJbuNHxMgxpg9rieW
17
+ tVyjuZRo/i7WLVm3uG+dK1RJ9t8Y6kpYkCRKpi9G8DBOj3PSulOybBr+fdRfW9mf
18
+ 8UmqOjOkrhxXPkchc9TY4EM7/1XeKvEidlIp0gvRAoGAAurz4zYvW2QhXaR2hhaT
19
+ p2XSLXiKM8AUndo3rH3U0/lhrvrEZicZsMj2LF88xg20U27sIaD/eJo13Y4XqaPk
20
+ ykPY6D9srv574SeIeMpx/8PxPiBcoDd+BNc0L1VkgVBoouORAwq5I9HjKKBjdEmI
21
+ UDw3i0X5KYvDm6fXVAZ0HXUCgYBWc4To8KiXPqNpq2sVzrSkBaWJSmj2G7u7Q6b/
22
+ RTs3is72v3gjHG6iiaE5URY7mnu4rjlRhAP9Vnsy6uHMrCJZEBTf/sPEYHZj9iGZ
23
+ EOduOAF3U1tsmaaebbDtm8hdhSOBvITy9kQlSIZAt1r17Ulytz5pj0AySFzJUIkz
24
+ a0SZkQKBgCWixtUxiK8PAdWhyS++90WJeJn8eqjuSAz+VMtFQFRRWDUbkiHvGMRu
25
+ o/Hhk6zS46gSF2Evb1d26uUEenXnJlIp6YWzb0DLPrfy5P53kPA6YEvYq5MSAg3l
26
+ DZOJUF+ko7cWXSZkeTIBH/jrGOdP4tTALZt6DNt+Gz7xwPO5tGgV
27
+ -----END RSA PRIVATE KEY-----
@@ -7,11 +7,12 @@ require_relative "../../../spec/es_helper"
7
7
  describe LogStash::Filters::Elasticsearch, :integration => true do
8
8
 
9
9
  ELASTIC_SECURITY_ENABLED = ENV['ELASTIC_SECURITY_ENABLED'].eql? 'true'
10
+ SECURE_INTEGRATION = ENV['SECURE_INTEGRATION'].eql? 'true'
10
11
 
11
12
  let(:base_config) do
12
13
  {
13
14
  "index" => 'logs',
14
- "hosts" => [ESHelper.get_host_port],
15
+ "hosts" => ["http#{SECURE_INTEGRATION ? 's' : nil}://#{ESHelper.get_host_port}"],
15
16
  "query" => "response: 404",
16
17
  "sort" => "response",
17
18
  "fields" => [ ["response", "code"] ],
@@ -19,27 +20,40 @@ describe LogStash::Filters::Elasticsearch, :integration => true do
19
20
  end
20
21
 
21
22
  let(:credentials) do
22
- { 'user' => 'elastic', 'password' => ENV['ELASTIC_PASSWORD'] }
23
+ if SECURE_INTEGRATION
24
+ { 'user' => 'tests', 'password' => 'Tests123' } # added user
25
+ else
26
+ { 'user' => 'elastic', 'password' => ENV['ELASTIC_PASSWORD'] }
27
+ end
23
28
  end
24
29
 
25
30
  let(:config) do
26
- ELASTIC_SECURITY_ENABLED ? base_config.merge(credentials) : base_config
31
+ config = ELASTIC_SECURITY_ENABLED ? base_config.merge(credentials) : base_config
32
+ config = { 'ca_file' => ca_path }.merge(config) if SECURE_INTEGRATION
33
+ config
34
+ end
35
+
36
+ let(:ca_path) do
37
+ File.expand_path('../fixtures/test_certs/ca.crt', File.dirname(__FILE__))
27
38
  end
28
39
 
29
40
  let(:plugin) { described_class.new(config) }
30
41
  let(:event) { LogStash::Event.new({}) }
31
42
 
32
43
  before(:each) do
33
- @es = ESHelper.get_client(ELASTIC_SECURITY_ENABLED ? credentials : {})
34
- # Delete all templates first.
44
+ es_url = ESHelper.get_host_port
45
+ es_url = SECURE_INTEGRATION ? "https://#{es_url}" : "http://#{es_url}"
46
+ args = ELASTIC_SECURITY_ENABLED ? "-u #{credentials['user']}:#{credentials['password']}" : ''
35
47
  # Clean ES of data before we start.
36
- @es.indices.delete_template(:name => "*")
48
+ # Delete all templates first.
49
+ ESHelper.curl_and_get_json_response "#{es_url}/_index_template/*", method: 'DELETE', args: args
37
50
  # This can fail if there are no indexes, ignore failure.
38
- @es.indices.delete(:index => "*") rescue nil
51
+ ESHelper.curl_and_get_json_response "#{es_url}/_index/*", method: 'DELETE', args: args
52
+ doc_args = "#{args} -H 'Content-Type: application/json' -d '{\"response\": 404, \"this\":\"that\"}'"
39
53
  10.times do
40
- ESHelper.index_doc(@es, :index => 'logs', :body => { :response => 404, :this => 'that'})
54
+ ESHelper.curl_and_get_json_response "#{es_url}/logs/_doc", method: 'POST', args: doc_args
41
55
  end
42
- @es.indices.refresh
56
+ ESHelper.curl_and_get_json_response "#{es_url}/_refresh", method: 'POST', args: args
43
57
  end
44
58
 
45
59
  it "should enhance the current event with new data" do
@@ -69,10 +83,23 @@ describe LogStash::Filters::Elasticsearch, :integration => true do
69
83
  super().reject { |key, _| key == 'password' }
70
84
  end
71
85
 
72
- it "should enhance the current event with new data" do
86
+ it "fails to register plugin" do
73
87
  expect { plugin.register }.to raise_error Elasticsearch::Transport::Transport::Errors::Unauthorized
74
88
  end
75
89
 
76
90
  end if ELASTIC_SECURITY_ENABLED
77
91
 
92
+ context 'setting host:port (and ssl)' do # reproduces GH-155
93
+
94
+ let(:config) do
95
+ super().merge "hosts" => [ESHelper.get_host_port], "ssl" => SECURE_INTEGRATION
96
+ end
97
+
98
+ it "works" do
99
+ expect { plugin.register }.to_not raise_error
100
+ plugin.filter(event)
101
+ end
102
+
103
+ end
104
+
78
105
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-filter-elasticsearch
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.9.4
4
+ version: 3.11.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-08-12 00:00:00.000000000 Z
11
+ date: 2022-02-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -20,8 +20,8 @@ dependencies:
20
20
  - !ruby/object:Gem::Version
21
21
  version: '2.99'
22
22
  name: logstash-core-plugin-api
23
- type: :runtime
24
23
  prerelease: false
24
+ type: :runtime
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - ">="
@@ -35,24 +35,38 @@ dependencies:
35
35
  requirements:
36
36
  - - ">="
37
37
  - !ruby/object:Gem::Version
38
- version: 5.0.5
38
+ version: 7.14.0
39
39
  name: elasticsearch
40
+ prerelease: false
40
41
  type: :runtime
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 7.14.0
47
+ - !ruby/object:Gem::Dependency
48
+ requirement: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 0.7.1
53
+ name: manticore
41
54
  prerelease: false
55
+ type: :runtime
42
56
  version_requirements: !ruby/object:Gem::Requirement
43
57
  requirements:
44
58
  - - ">="
45
59
  - !ruby/object:Gem::Version
46
- version: 5.0.5
60
+ version: 0.7.1
47
61
  - !ruby/object:Gem::Dependency
48
62
  requirement: !ruby/object:Gem::Requirement
49
63
  requirements:
50
64
  - - "~>"
51
65
  - !ruby/object:Gem::Version
52
66
  version: '0.6'
53
- name: manticore
54
- type: :runtime
67
+ name: cabin
55
68
  prerelease: false
69
+ type: :development
56
70
  version_requirements: !ruby/object:Gem::Requirement
57
71
  requirements:
58
72
  - - "~>"
@@ -64,9 +78,23 @@ dependencies:
64
78
  - - ">="
65
79
  - !ruby/object:Gem::Version
66
80
  version: '0'
67
- name: logstash-devutils
81
+ name: webrick
82
+ prerelease: false
68
83
  type: :development
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ - !ruby/object:Gem::Dependency
90
+ requirement: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ name: logstash-devutils
69
96
  prerelease: false
97
+ type: :development
70
98
  version_requirements: !ruby/object:Gem::Requirement
71
99
  requirements:
72
100
  - - ">="
@@ -100,6 +128,10 @@ files:
100
128
  - spec/filters/fixtures/request_size0_agg.json
101
129
  - spec/filters/fixtures/request_x_1.json
102
130
  - spec/filters/fixtures/request_x_10.json
131
+ - spec/filters/fixtures/test_certs/ca.crt
132
+ - spec/filters/fixtures/test_certs/ca.key
133
+ - spec/filters/fixtures/test_certs/es.crt
134
+ - spec/filters/fixtures/test_certs/es.key
103
135
  - spec/filters/integration/elasticsearch_spec.rb
104
136
  homepage: http://www.elastic.co/guide/en/logstash/current/index.html
105
137
  licenses:
@@ -122,7 +154,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
122
154
  - !ruby/object:Gem::Version
123
155
  version: '0'
124
156
  requirements: []
125
- rubygems_version: 3.0.6
157
+ rubygems_version: 3.1.6
126
158
  signing_key:
127
159
  specification_version: 4
128
160
  summary: Copies fields from previous log events in Elasticsearch to current events
@@ -136,4 +168,8 @@ test_files:
136
168
  - spec/filters/fixtures/request_size0_agg.json
137
169
  - spec/filters/fixtures/request_x_1.json
138
170
  - spec/filters/fixtures/request_x_10.json
171
+ - spec/filters/fixtures/test_certs/ca.crt
172
+ - spec/filters/fixtures/test_certs/ca.key
173
+ - spec/filters/fixtures/test_certs/es.crt
174
+ - spec/filters/fixtures/test_certs/es.key
139
175
  - spec/filters/integration/elasticsearch_spec.rb