logstash-filter-elasticsearch 3.16.2 → 3.17.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: 77f05a757154f2f9e412dc4226296322180f27b0906a3a28a5b87a164531421c
4
- data.tar.gz: 3262154d23afdec46fb84a583d88f2a7fa12b6c5282d36c9af4bc16d95aca1e2
3
+ metadata.gz: a29cd8cf20b82a601cbaaae69662b4341a40dc5d7c935c0c5b13b6b36d7de236
4
+ data.tar.gz: bd1e19d8f42b8066aee89c44622d5efa193e0a800ac1951c186bcaf7ed166626
5
5
  SHA512:
6
- metadata.gz: a85fc86abdf1546f600fd6878ce9775e437561eeaa3c5ad2da5963cd991c9b15383dfbab249b5d755d709ed404f6fc88c637f6df4348425318eb08ea091fc92c
7
- data.tar.gz: 5398c04fe9c7aff2cc74e61f67aaab22da5280160c44fae8fdf7cc86cdb8fb62735eade95dca41bc53c7a7bb745af30e82fe2bfd715c8a959728e9a1d29e9e72
6
+ metadata.gz: 0c1374ae82f6a3b78b9192186b8dddae4a4826da2befdcf471d8a26abc3faa433f901ed76ad7e1ba0f3e0f1fd223813230125d7c588a454374315dc55935f5b4
7
+ data.tar.gz: 4555b95388fe23d825e7d5a34c1a5714dccf394b8657182c483858bef383fae17bd6bb2f818af3c21f0304d29606df9e42378058d675518ffa1a5c9904a3ac37
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 3.17.1
2
+ - Add elastic-transport client support used in elasticsearch-ruby 8.x [#193](https://github.com/logstash-plugins/logstash-filter-elasticsearch/pull/193)
3
+
4
+ ## 3.17.0
5
+ - Added support for custom headers [#190](https://github.com/logstash-plugins/logstash-filter-elasticsearch/pull/190)
6
+
1
7
  ## 3.16.2
2
8
  - Add `x-elastic-product-origin` header to Elasticsearch requests [#185](https://github.com/logstash-plugins/logstash-filter-elasticsearch/pull/185)
3
9
 
data/docs/index.asciidoc CHANGED
@@ -131,6 +131,7 @@ This plugin supports the following configuration options plus the <<plugins-{typ
131
131
  | <<plugins-{type}s-{plugin}-ca_trusted_fingerprint>> |<<string,string>>|No
132
132
  | <<plugins-{type}s-{plugin}-cloud_auth>> |<<password,password>>|No
133
133
  | <<plugins-{type}s-{plugin}-cloud_id>> |<<string,string>>|No
134
+ | <<plugins-{type}s-{plugin}-custom_headers>> |<<hash,hash>>|No
134
135
  | <<plugins-{type}s-{plugin}-docinfo_fields>> |<<hash,hash>>|No
135
136
  | <<plugins-{type}s-{plugin}-enable_sort>> |<<boolean,boolean>>|No
136
137
  | <<plugins-{type}s-{plugin}-fields>> |<<array,array>>|No
@@ -228,6 +229,16 @@ Cloud ID, from the Elastic Cloud web console. If set `hosts` should not be used.
228
229
  For more info, check out the
229
230
  {logstash-ref}/connecting-to-cloud.html[Logstash-to-Cloud documentation].
230
231
 
232
+
233
+ [id="plugins-{type}s-{plugin}-custom_headers"]
234
+ ===== `custom_headers`
235
+
236
+ * Value type is <<hash,hash>>
237
+ * Default value is empty
238
+
239
+ Pass a set of key value pairs as the headers sent in each request to Elasticsearch.
240
+ These custom headers will override any headers previously set by the plugin such as the User Agent or Authorization headers.
241
+
231
242
  [id="plugins-{type}s-{plugin}-docinfo_fields"]
232
243
  ===== `docinfo_fields`
233
244
 
@@ -1,7 +1,6 @@
1
1
  # encoding: utf-8
2
2
  require "elasticsearch"
3
3
  require "base64"
4
- require "elasticsearch/transport/transport/http/manticore"
5
4
 
6
5
 
7
6
  module LogStash
@@ -9,6 +8,7 @@ module LogStash
9
8
  class ElasticsearchClient
10
9
 
11
10
  attr_reader :client
11
+ attr_reader :es_transport_client_type
12
12
 
13
13
  BUILD_FLAVOR_SERVERLESS = 'serverless'.freeze
14
14
  DEFAULT_EAV_HEADER = { "Elastic-Api-Version" => "2023-10-31" }.freeze
@@ -20,6 +20,8 @@ module LogStash
20
20
  api_key = options.fetch(:api_key, nil)
21
21
  proxy = options.fetch(:proxy, nil)
22
22
  user_agent = options[:user_agent]
23
+ custom_headers = options[:custom_headers]
24
+
23
25
 
24
26
  transport_options = { }
25
27
  transport_options[:headers] = options.fetch(:serverless, false) ? DEFAULT_EAV_HEADER.dup : {}
@@ -27,6 +29,7 @@ module LogStash
27
29
  transport_options[:headers].merge!(setup_api_key(api_key))
28
30
  transport_options[:headers].merge!({ 'user-agent' => "#{user_agent}" })
29
31
  transport_options[:headers].merge!(INTERNAL_ORIGIN_HEADER)
32
+ transport_options[:headers].merge!(custom_headers) unless custom_headers.empty?
30
33
 
31
34
  transport_options[:pool_max] = 1000
32
35
  transport_options[:pool_max_per_route] = 100
@@ -41,7 +44,7 @@ module LogStash
41
44
 
42
45
  client_options = {
43
46
  hosts: hosts,
44
- transport_class: ::Elasticsearch::Transport::Transport::HTTP::Manticore,
47
+ transport_class: get_transport_client_class,
45
48
  transport_options: transport_options,
46
49
  ssl: ssl_options,
47
50
  retry_on_failure: options[:retry_on_failure],
@@ -95,6 +98,20 @@ module LogStash
95
98
  token = ::Base64.strict_encode64(api_key.value)
96
99
  { 'Authorization' => "ApiKey #{token}" }
97
100
  end
101
+
102
+ def get_transport_client_class
103
+ # LS-core includes `elasticsearch` gem. The gem is composed of two separate gems: `elasticsearch-api` and `elasticsearch-transport`
104
+ # And now `elasticsearch-transport` is old, instead we have `elastic-transport`.
105
+ # LS-core updated `elasticsearch` > 8: https://github.com/elastic/logstash/pull/17161
106
+ # Following source bits are for the compatibility to support both `elasticsearch-transport` and `elastic-transport` gems
107
+ require "elasticsearch/transport/transport/http/manticore"
108
+ es_transport_client_type = "elasticsearch_transport"
109
+ ::Elasticsearch::Transport::Transport::HTTP::Manticore
110
+ rescue ::LoadError
111
+ require "elastic/transport/transport/http/manticore"
112
+ es_transport_client_type = "elastic_transport"
113
+ ::Elastic::Transport::Transport::HTTP::Manticore
114
+ end
98
115
  end
99
116
  end
100
117
  end
@@ -7,7 +7,6 @@ require "logstash/plugin_mixins/normalize_config_support"
7
7
  require "monitor"
8
8
 
9
9
  require_relative "elasticsearch/client"
10
- require_relative "elasticsearch/patches/_elasticsearch_transport_http_manticore"
11
10
 
12
11
  class LogStash::Filters::Elasticsearch < LogStash::Filters::Base
13
12
  config_name "elasticsearch"
@@ -33,6 +32,9 @@ class LogStash::Filters::Elasticsearch < LogStash::Filters::Base
33
32
  # Array of fields to copy from old event (found via elasticsearch) into new event
34
33
  config :fields, :validate => :array, :default => {}
35
34
 
35
+ # Custom headers for Elasticsearch requests
36
+ config :custom_headers, :validate => :hash, :default => {}
37
+
36
38
  # Hash of docinfo fields to copy from old event (found via elasticsearch) into new event
37
39
  config :docinfo_fields, :validate => :hash, :default => {}
38
40
 
@@ -180,6 +182,9 @@ class LogStash::Filters::Elasticsearch < LogStash::Filters::Base
180
182
 
181
183
  test_connection!
182
184
  setup_serverless
185
+ if get_client.es_transport_client_type == "elasticsearch_transport"
186
+ require_relative "elasticsearch/patches/_elasticsearch_transport_http_manticore"
187
+ end
183
188
  end # def register
184
189
 
185
190
  def filter(event)
@@ -269,7 +274,8 @@ class LogStash::Filters::Elasticsearch < LogStash::Filters::Base
269
274
  :ssl => client_ssl_options,
270
275
  :retry_on_failure => @retry_on_failure,
271
276
  :retry_on_status => @retry_on_status,
272
- :user_agent => prepare_user_agent
277
+ :user_agent => prepare_user_agent,
278
+ :custom_headers => @custom_headers
273
279
  }
274
280
  end
275
281
 
@@ -1,13 +1,13 @@
1
1
  Gem::Specification.new do |s|
2
2
 
3
3
  s.name = 'logstash-filter-elasticsearch'
4
- s.version = '3.16.2'
4
+ s.version = '3.17.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"
8
8
  s.authors = ["Elastic"]
9
9
  s.email = 'info@elastic.co'
10
- s.homepage = "http://www.elastic.co/guide/en/logstash/current/index.html"
10
+ s.homepage = "https://elastic.co/logstash"
11
11
  s.require_paths = ["lib"]
12
12
 
13
13
  # Files
@@ -21,7 +21,7 @@ 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', ">= 7.14.9" # LS >= 6.7 and < 7.14 all used version 5.0.5
24
+ s.add_runtime_dependency 'elasticsearch', ">= 7.14.9", '< 9'
25
25
  s.add_runtime_dependency 'manticore', ">= 0.7.1"
26
26
  s.add_runtime_dependency 'logstash-mixin-ca_trusted_fingerprint_support', '~> 1.0'
27
27
  s.add_runtime_dependency 'logstash-mixin-normalize_config_support', '~>1.0'
@@ -60,9 +60,18 @@ describe LogStash::Filters::Elasticsearch do
60
60
  allow(plugin).to receive(:get_client).and_return(filter_client)
61
61
  allow(filter_client).to receive(:serverless?).and_return(true)
62
62
  allow(filter_client).to receive(:client).and_return(es_client)
63
- allow(es_client).to receive(:info).with(a_hash_including(:headers => LogStash::Filters::ElasticsearchClient::DEFAULT_EAV_HEADER)).and_raise(
64
- Elasticsearch::Transport::Transport::Errors::BadRequest.new
65
- )
63
+
64
+ if elastic_ruby_v8_client_available?
65
+ allow(es_client).to receive(:info)
66
+ .with(a_hash_including(
67
+ :headers => LogStash::Filters::ElasticsearchClient::DEFAULT_EAV_HEADER))
68
+ .and_raise(Elastic::Transport::Transport::Errors::BadRequest.new)
69
+ else
70
+ allow(es_client).to receive(:info)
71
+ .with(a_hash_including(
72
+ :headers => LogStash::Filters::ElasticsearchClient::DEFAULT_EAV_HEADER))
73
+ .and_raise(Elasticsearch::Transport::Transport::Errors::BadRequest.new)
74
+ end
66
75
  end
67
76
 
68
77
  it "raises an exception when Elastic Api Version is not supported" do
@@ -103,6 +112,11 @@ describe LogStash::Filters::Elasticsearch do
103
112
 
104
113
  before(:each) do
105
114
  allow(LogStash::Filters::ElasticsearchClient).to receive(:new).and_return(client)
115
+ if elastic_ruby_v8_client_available?
116
+ allow(client).to receive(:es_transport_client_type).and_return('elastic_transport')
117
+ else
118
+ allow(client).to receive(:es_transport_client_type).and_return('elasticsearch_transport')
119
+ end
106
120
  allow(client).to receive(:search).and_return(response)
107
121
  allow(plugin).to receive(:test_connection!)
108
122
  allow(plugin).to receive(:setup_serverless)
@@ -333,6 +347,35 @@ describe LogStash::Filters::Elasticsearch do
333
347
  end
334
348
  end
335
349
 
350
+ context "with custom headers" do
351
+ let(:config) do
352
+ {
353
+ "query" => "*",
354
+ "custom_headers" => { "Custom-Header-1" => "Custom Value 1", "Custom-Header-2" => "Custom Value 2" }
355
+ }
356
+ end
357
+
358
+ let(:plugin) { LogStash::Filters::Elasticsearch.new(config) }
359
+ let(:client_double) { double("client") }
360
+ let(:transport_double) { double("transport", options: { transport_options: { headers: config["custom_headers"] } }) }
361
+
362
+ before do
363
+ allow(plugin).to receive(:get_client).and_return(client_double)
364
+ if elastic_ruby_v8_client_available?
365
+ allow(client_double).to receive(:es_transport_client_type).and_return('elastic_transport')
366
+ else
367
+ allow(client_double).to receive(:es_transport_client_type).and_return('elasticsearch_transport')
368
+ end
369
+ allow(client_double).to receive(:client).and_return(transport_double)
370
+ end
371
+
372
+ it "sets custom headers" do
373
+ plugin.register
374
+ client = plugin.send(:get_client).client
375
+ expect(client.options[:transport_options][:headers]).to match(hash_including(config["custom_headers"]))
376
+ end
377
+ end
378
+
336
379
  context "if query is on nested field" do
337
380
  let(:config) do
338
381
  {
@@ -482,7 +525,12 @@ describe LogStash::Filters::Elasticsearch do
482
525
  # this spec is a safeguard to trigger an assessment of thread-safety should
483
526
  # we choose a different transport adapter in the future.
484
527
  transport_class = extract_transport(client).options.fetch(:transport_class)
485
- expect(transport_class).to equal ::Elasticsearch::Transport::Transport::HTTP::Manticore
528
+ if elastic_ruby_v8_client_available?
529
+ allow(client).to receive(:es_transport_client_type).and_return("elastic_transport")
530
+ expect(transport_class).to equal ::Elastic::Transport::Transport::HTTP::Manticore
531
+ else
532
+ expect(transport_class).to equal ::Elasticsearch::Transport::Transport::HTTP::Manticore
533
+ end
486
534
  end
487
535
 
488
536
  it 'uses a client with sufficient connection pool size' do
@@ -797,6 +845,11 @@ describe LogStash::Filters::Elasticsearch do
797
845
 
798
846
  before(:each) do
799
847
  allow(LogStash::Filters::ElasticsearchClient).to receive(:new).and_return(client)
848
+ if elastic_ruby_v8_client_available?
849
+ allow(client).to receive(:es_transport_client_type).and_return('elastic_transport')
850
+ else
851
+ allow(client).to receive(:es_transport_client_type).and_return('elasticsearch_transport')
852
+ end
800
853
  allow(plugin).to receive(:test_connection!)
801
854
  allow(plugin).to receive(:setup_serverless)
802
855
  plugin.register
@@ -811,11 +864,19 @@ describe LogStash::Filters::Elasticsearch do
811
864
  end
812
865
  end
813
866
 
814
- # @note can be removed once gem depends on elasticsearch >= 6.x
815
- def extract_transport(client) # on 7.x client.transport is a ES::Transport::Client
867
+ def extract_transport(client)
868
+ # on 7x: client.transport.transport
869
+ # on >=8.x: client.transport
816
870
  client.transport.respond_to?(:transport) ? client.transport.transport : client.transport
817
871
  end
818
872
 
873
+ def elastic_ruby_v8_client_available?
874
+ Elasticsearch::Transport
875
+ false
876
+ rescue NameError # NameError: uninitialized constant Elasticsearch::Transport if Elastic Ruby client is not available
877
+ true
878
+ end
879
+
819
880
  class MockResponse
820
881
  attr_reader :code, :headers
821
882
 
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.16.2
4
+ version: 3.17.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-12-09 00:00:00.000000000 Z
11
+ date: 2025-03-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -36,6 +36,9 @@ dependencies:
36
36
  - - ">="
37
37
  - !ruby/object:Gem::Version
38
38
  version: 7.14.9
39
+ - - "<"
40
+ - !ruby/object:Gem::Version
41
+ version: '9'
39
42
  name: elasticsearch
40
43
  type: :runtime
41
44
  prerelease: false
@@ -44,6 +47,9 @@ dependencies:
44
47
  - - ">="
45
48
  - !ruby/object:Gem::Version
46
49
  version: 7.14.9
50
+ - - "<"
51
+ - !ruby/object:Gem::Version
52
+ version: '9'
47
53
  - !ruby/object:Gem::Dependency
48
54
  requirement: !ruby/object:Gem::Requirement
49
55
  requirements:
@@ -174,7 +180,7 @@ files:
174
180
  - spec/filters/fixtures/test_certs/ls.der.sha256
175
181
  - spec/filters/fixtures/test_certs/ls.key
176
182
  - spec/filters/integration/elasticsearch_spec.rb
177
- homepage: http://www.elastic.co/guide/en/logstash/current/index.html
183
+ homepage: https://elastic.co/logstash
178
184
  licenses:
179
185
  - Apache License (2.0)
180
186
  metadata: