From 957b22bd23fe837a274f1d81efed1ddf0bc78786 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lex=20C=C3=A1mara?= Date: Wed, 17 Sep 2025 12:58:29 +0200 Subject: [PATCH 1/4] Support both, encoded and non encoded api-key formats on plugin configuration --- lib/logstash/filters/elasticsearch/client.rb | 12 ++++++++-- spec/filters/elasticsearch_spec.rb | 24 +++++++++++++++----- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/lib/logstash/filters/elasticsearch/client.rb b/lib/logstash/filters/elasticsearch/client.rb index 3174550..bfbe179 100644 --- a/lib/logstash/filters/elasticsearch/client.rb +++ b/lib/logstash/filters/elasticsearch/client.rb @@ -101,12 +101,20 @@ def setup_basic_auth(user, password) end def setup_api_key(api_key) - return {} unless (api_key && api_key.value) + return {} unless (api_key&.value) - token = ::Base64.strict_encode64(api_key.value) + token = is_base64?(api_key.value) ? api_key.value : Base64.strict_encode64(api_key.value) { 'Authorization' => "ApiKey #{token}" } end + def is_base64?(string) + begin + string == Base64.strict_encode64(Base64.strict_decode64(string)) + rescue ArgumentError + false + end + end + def get_transport_client_class # LS-core includes `elasticsearch` gem. The gem is composed of two separate gems: `elasticsearch-api` and `elasticsearch-transport` # And now `elasticsearch-transport` is old, instead we have `elastic-transport`. diff --git a/spec/filters/elasticsearch_spec.rb b/spec/filters/elasticsearch_spec.rb index 4c1deb4..a97e613 100644 --- a/spec/filters/elasticsearch_spec.rb +++ b/spec/filters/elasticsearch_spec.rb @@ -324,14 +324,26 @@ def wait_receive_request end context "with ssl" do - let(:config) { super().merge({ 'api_key' => LogStash::Util::Password.new('foo:bar'), "ssl_enabled" => true }) } + let(:config) { super().merge("ssl_enabled" => true) } + encoded_api_key = Base64.strict_encode64('foo:bar') - it "should set authorization" do - plugin.register - client = plugin.send(:get_client).client - auth_header = extract_transport(client).options[:transport_options][:headers]['Authorization'] + scenarios = { + 'with non-encoded api-key' => LogStash::Util::Password.new('foo:bar'), + 'with encoded api-key' => LogStash::Util::Password.new(encoded_api_key) + } + + scenarios.each do |description, api_key_value| + context description do + let(:config) { super().merge('api_key' => api_key_value) } - expect( auth_header ).to eql "ApiKey #{Base64.strict_encode64('foo:bar')}" + it "should set authorization" do + plugin.register + client= plugin.send(:get_client).client + auth_header = extract_transport(client).options[:transport_options][:headers]['Authorization'] + + expect(auth_header).to eql "ApiKey #{encoded_api_key}" + end + end end context 'user also set' do From 10bbcc13ac5d6dce86614d21888ff6062076a014 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lex=20C=C3=A1mara?= Date: Wed, 17 Sep 2025 16:29:48 +0200 Subject: [PATCH 2/4] Added missing manticore dependency at 'elasticsearch_spec.rb' tests --- spec/filters/elasticsearch_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/filters/elasticsearch_spec.rb b/spec/filters/elasticsearch_spec.rb index a97e613..8e31c7c 100644 --- a/spec/filters/elasticsearch_spec.rb +++ b/spec/filters/elasticsearch_spec.rb @@ -4,6 +4,7 @@ require "logstash/filters/elasticsearch" require "logstash/json" require "cabin" +require "manticore" require "webrick" require "uri" From 85a853b18f384ef4806bd23f6e2135c3fb595a73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lex=20C=C3=A1mara?= Date: Mon, 22 Sep 2025 16:59:44 +0200 Subject: [PATCH 3/4] Solved code style issues --- CHANGELOG.md | 2 +- lib/logstash/filters/elasticsearch/client.rb | 12 +++---- spec/filters/elasticsearch_spec.rb | 35 ++++++++++---------- 3 files changed, 24 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8bec1f..4d2eeb3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ ## 4.3.1 - - Support both, encoded and non encoded api-key formats on plugin configuration [#203](https://github.com/logstash-plugins/logstash-filter-elasticsearch/pull/203) + - Added support for encoded and non encoded api-key formats on plugin configuration [#203](https://github.com/logstash-plugins/logstash-filter-elasticsearch/pull/203) ## 4.3.0 - ES|QL support [#194](https://github.com/logstash-plugins/logstash-filter-elasticsearch/pull/194) diff --git a/lib/logstash/filters/elasticsearch/client.rb b/lib/logstash/filters/elasticsearch/client.rb index bfbe179..9ac1a6f 100644 --- a/lib/logstash/filters/elasticsearch/client.rb +++ b/lib/logstash/filters/elasticsearch/client.rb @@ -103,16 +103,14 @@ def setup_basic_auth(user, password) def setup_api_key(api_key) return {} unless (api_key&.value) - token = is_base64?(api_key.value) ? api_key.value : Base64.strict_encode64(api_key.value) + token = base64?(api_key.value) ? api_key.value : Base64.strict_encode64(api_key.value) { 'Authorization' => "ApiKey #{token}" } end - def is_base64?(string) - begin - string == Base64.strict_encode64(Base64.strict_decode64(string)) - rescue ArgumentError - false - end + def base64?(string) + string == Base64.strict_encode64(Base64.strict_decode64(string)) + rescue ArgumentError + false end def get_transport_client_class diff --git a/spec/filters/elasticsearch_spec.rb b/spec/filters/elasticsearch_spec.rb index 8e31c7c..eb219a0 100644 --- a/spec/filters/elasticsearch_spec.rb +++ b/spec/filters/elasticsearch_spec.rb @@ -4,7 +4,6 @@ require "logstash/filters/elasticsearch" require "logstash/json" require "cabin" -require "manticore" require "webrick" require "uri" @@ -325,26 +324,28 @@ def wait_receive_request end context "with ssl" do - let(:config) { super().merge("ssl_enabled" => true) } - encoded_api_key = Base64.strict_encode64('foo:bar') + let(:api_key_value) { nil } + let(:config) { super().merge("ssl_enabled" => true, 'api_key' => LogStash::Util::Password.new(api_key_value)) } + let(:encoded_api_key) { Base64.strict_encode64('foo:bar') } - scenarios = { - 'with non-encoded api-key' => LogStash::Util::Password.new('foo:bar'), - 'with encoded api-key' => LogStash::Util::Password.new(encoded_api_key) - } + shared_examples "a plugin that sets the ApiKey authorization header" do + it "correctly sets the Authorization header" do + plugin.register + client= plugin.send(:get_client).client + auth_header = extract_transport(client).options[:transport_options][:headers]['Authorization'] - scenarios.each do |description, api_key_value| - context description do - let(:config) { super().merge('api_key' => api_key_value) } + expect(auth_header).to eql("ApiKey #{encoded_api_key}") + end + end - it "should set authorization" do - plugin.register - client= plugin.send(:get_client).client - auth_header = extract_transport(client).options[:transport_options][:headers]['Authorization'] + context "with a non-encoded API key" do + let(:api_key_value) { "foo:bar" } + it_behaves_like "a plugin that sets the ApiKey authorization header" + end - expect(auth_header).to eql "ApiKey #{encoded_api_key}" - end - end + context "with an encoded API key" do + let(:api_key_value) { encoded_api_key } + it_behaves_like "a plugin that sets the ApiKey authorization header" end context 'user also set' do From 8bc47a5244839dbe9b10d7f7a8ce01ef4df18e5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lex=20C=C3=A1mara?= Date: Tue, 23 Sep 2025 13:43:14 +0200 Subject: [PATCH 4/4] Updated gemspec file --- logstash-filter-elasticsearch.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logstash-filter-elasticsearch.gemspec b/logstash-filter-elasticsearch.gemspec index 214b130..55c24b8 100644 --- a/logstash-filter-elasticsearch.gemspec +++ b/logstash-filter-elasticsearch.gemspec @@ -1,7 +1,7 @@ Gem::Specification.new do |s| s.name = 'logstash-filter-elasticsearch' - s.version = '4.3.0' + s.version = '4.3.1' s.licenses = ['Apache License (2.0)'] s.summary = "Copies fields from previous log events in Elasticsearch to current events " 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"