logstash-output-elasticsearch 10.4.2-java → 10.5.0-java

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7f27a5838e3f5abb53fb561802f1fa6f88e25b43f252951f6a2e8a1a8402d11a
4
- data.tar.gz: d77d44f5f208793751f7e026a47806523158f490fd0872f739aea9102acae7a5
3
+ metadata.gz: 71b5bb8d2a918b37ee594c9bcbe11ec872dbfb2ee30094a6b2ede8ea4550fb46
4
+ data.tar.gz: fc4c5cba1d3cc99cfbdf17f3658723d97889e7d0c824dc430986f5f64ea652e0
5
5
  SHA512:
6
- metadata.gz: a64c0b9981fb551cba3a566a6c519d99579b5827128c3320ea77cd9c47932a54f0bcfcba9f94ca57c8570e428f8efde54f1e94d5351ec21ce91a95bf70999bce
7
- data.tar.gz: dd082458727f7b7bfaa8273606e12b131efe6fbd035f25f881d118e59e15fa0d556db1f4675baede6955827b89a1f127d05e16a86d11bf2f97b39861a68df945
6
+ metadata.gz: 036130a59c31c2634db172b37a918fdcb29ca93d608f1cfb80a54a5f0e3620b0766acec221f0c2ef0c65e7f764085ac67f16d5263fea9b72d5b5256f8ac7be98
7
+ data.tar.gz: 0b27c6975420f0390d945bc7bdabd9fd5afabe12d8a5a20a4ccb6cc2d2ea5da2946942c76b8fc67de5bee97063b5771770a74e89a7f40f846df1979c798e9499
data/CHANGELOG.md CHANGED
@@ -1,5 +1,5 @@
1
- ## 10.4.2
2
- - Changed cloud id, credential and host setup to happen in `build_client` [#939](https://github.com/logstash-plugins/logstash-output-elasticsearch/pull/939)
1
+ ## 10.5.0
2
+ - Added api_key support [#934](https://github.com/logstash-plugins/logstash-output-elasticsearch/pull/934)
3
3
 
4
4
  ## 10.4.1
5
5
  - [DOC] Added note about `_type` setting change from `doc` to `_doc` [#884](https://github.com/logstash-plugins/logstash-output-elasticsearch/pull/884)
data/docs/index.asciidoc CHANGED
@@ -232,6 +232,9 @@ Elasticsearch] to take advantage of response compression when using this plugin
232
232
  For requests compression, regardless of the Elasticsearch version, users have to enable `http_compression`
233
233
  setting in their Logstash config file.
234
234
 
235
+ ==== Authentication
236
+
237
+ Authentication to a secure Elasticsearch cluster is possible using one of the `user`/`password`, `cloud_auth` or `api_key` options.
235
238
 
236
239
  [id="plugins-{type}s-{plugin}-options"]
237
240
  ==== Elasticsearch Output Configuration Options
@@ -242,6 +245,7 @@ This plugin supports the following configuration options plus the <<plugins-{typ
242
245
  |=======================================================================
243
246
  |Setting |Input type|Required
244
247
  | <<plugins-{type}s-{plugin}-action>> |<<string,string>>|No
248
+ | <<plugins-{type}s-{plugin}-api_key>> |<<password,password>>|No
245
249
  | <<plugins-{type}s-{plugin}-bulk_path>> |<<string,string>>|No
246
250
  | <<plugins-{type}s-{plugin}-cacert>> |a valid filesystem path|No
247
251
  | <<plugins-{type}s-{plugin}-cloud_auth>> |<<password,password>>|No
@@ -324,6 +328,16 @@ The Elasticsearch action to perform. Valid actions are:
324
328
 
325
329
  For more details on actions, check out the http://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html[Elasticsearch bulk API documentation]
326
330
 
331
+ [id="plugins-{type}s-{plugin}-api_key"]
332
+ ===== `api_key`
333
+
334
+ * Value type is <<password,password>>
335
+ * There is no default value for this setting.
336
+
337
+ Authenticate using Elasticsearch API key. Note that this option also requires enabling the `ssl` option.
338
+
339
+ Format is `id:api_key` where `id` and `api_key` are as returned by the Elasticsearch https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-create-api-key.html[Create API key API].
340
+
327
341
  [id="plugins-{type}s-{plugin}-bulk_path"]
328
342
  ===== `bulk_path`
329
343
 
@@ -122,6 +122,10 @@ class LogStash::Outputs::ElasticSearch < LogStash::Outputs::Base
122
122
  # Password to authenticate to a secure Elasticsearch cluster
123
123
  config :password, :validate => :password
124
124
 
125
+ # Authenticate using Elasticsearch API key.
126
+ # format is id:api_key (as returned by https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-create-api-key.html[Create API key])
127
+ config :api_key, :validate => :password
128
+
125
129
  # Cloud authentication string ("<username>:<password>" format) is an alternative for the `user`/`password` configuration.
126
130
  #
127
131
  # For more details, check out the https://www.elastic.co/guide/en/logstash/current/connecting-to-cloud.html#_cloud_auth[cloud documentation]
@@ -255,7 +259,11 @@ class LogStash::Outputs::ElasticSearch < LogStash::Outputs::Base
255
259
  end
256
260
 
257
261
  def build_client
258
- fill_user_password_from_cloud_auth
262
+ # the following 3 options validation & setup methods are called inside build_client
263
+ # because they must be executed prior to building the client and logstash
264
+ # monitoring and management rely on directly calling build_client
265
+ # see https://github.com/logstash-plugins/logstash-output-elasticsearch/pull/934#pullrequestreview-396203307
266
+ validate_authentication
259
267
  fill_hosts_from_cloud_id
260
268
  setup_hosts
261
269
 
@@ -20,7 +20,6 @@ module LogStash; module Outputs; class ElasticSearch;
20
20
  @stopping = Concurrent::AtomicBoolean.new(false)
21
21
  # To support BWC, we check if DLQ exists in core (< 5.4). If it doesn't, we use nil to resort to previous behavior.
22
22
  @dlq_writer = dlq_enabled? ? execution_context.dlq_writer : nil
23
-
24
23
  build_client
25
24
  setup_after_successful_connection
26
25
  check_action_validity
@@ -109,6 +108,28 @@ module LogStash; module Outputs; class ElasticSearch;
109
108
  [action, params, event]
110
109
  end
111
110
 
111
+ def validate_authentication
112
+ authn_options = 0
113
+ authn_options += 1 if @cloud_auth
114
+ authn_options += 1 if (@api_key && @api_key.value)
115
+ authn_options += 1 if (@user || (@password && @password.value))
116
+
117
+ if authn_options > 1
118
+ raise LogStash::ConfigurationError, 'Multiple authentication options are specified, please only use one of user/password, cloud_auth or api_key'
119
+ end
120
+
121
+ if @api_key && @api_key.value && @ssl != true
122
+ raise(LogStash::ConfigurationError, "Using api_key authentication requires SSL/TLS secured communication using the `ssl => true` option")
123
+ end
124
+
125
+ if @cloud_auth
126
+ @user, @password = parse_user_password_from_cloud_auth(@cloud_auth)
127
+ # params is the plugin global params hash which will be passed to HttpClientBuilder.build
128
+ params['user'], params['password'] = @user, @password
129
+ end
130
+ end
131
+ private :validate_authentication
132
+
112
133
  def setup_hosts
113
134
  @hosts = Array(@hosts)
114
135
  if @hosts.empty?
@@ -132,16 +153,6 @@ module LogStash; module Outputs; class ElasticSearch;
132
153
  @hosts = parse_host_uri_from_cloud_id(@cloud_id)
133
154
  end
134
155
 
135
- def fill_user_password_from_cloud_auth
136
- return unless @cloud_auth
137
-
138
- if @user || @password
139
- raise LogStash::ConfigurationError, 'Both cloud_auth and user/password specified, please only use one.'
140
- end
141
- @user, @password = parse_user_password_from_cloud_auth(@cloud_auth)
142
- params['user'], params['password'] = @user, @password
143
- end
144
-
145
156
  def parse_host_uri_from_cloud_id(cloud_id)
146
157
  begin # might not be available on older LS
147
158
  require 'logstash/util/cloud_setting_id'
@@ -1,4 +1,5 @@
1
1
  require 'cgi'
2
+ require "base64"
2
3
 
3
4
  module LogStash; module Outputs; class ElasticSearch;
4
5
  module HttpClientBuilder
@@ -8,7 +9,7 @@ module LogStash; module Outputs; class ElasticSearch;
8
9
  :pool_max_per_route => params["pool_max_per_route"],
9
10
  :check_connection_timeout => params["validate_after_inactivity"],
10
11
  :http_compression => params["http_compression"],
11
- :headers => params["custom_headers"]
12
+ :headers => params["custom_headers"] || {}
12
13
  }
13
14
 
14
15
  client_settings[:proxy] = params["proxy"] if params["proxy"]
@@ -56,6 +57,7 @@ module LogStash; module Outputs; class ElasticSearch;
56
57
 
57
58
  client_settings.merge! setup_ssl(logger, params)
58
59
  common_options.merge! setup_basic_auth(logger, params)
60
+ client_settings[:headers].merge! setup_api_key(logger, params)
59
61
 
60
62
  external_version_types = ["external", "external_gt", "external_gte"]
61
63
  # External Version validation
@@ -151,6 +153,14 @@ module LogStash; module Outputs; class ElasticSearch;
151
153
  }
152
154
  end
153
155
 
156
+ def self.setup_api_key(logger, params)
157
+ api_key = params["api_key"]
158
+
159
+ return {} unless (api_key && api_key.value)
160
+
161
+ { "Authorization" => "ApiKey " + Base64.strict_encode64(api_key.value) }
162
+ end
163
+
154
164
  private
155
165
  def self.dedup_slashes(url)
156
166
  url.gsub(/\/+/, "/")
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'logstash-output-elasticsearch'
3
- s.version = '10.4.2'
3
+ s.version = '10.5.0'
4
4
 
5
5
  s.licenses = ['apache-2.0']
6
6
  s.summary = "Stores logs in Elasticsearch"
@@ -1,4 +1,5 @@
1
1
  require_relative "../../../spec/es_spec_helper"
2
+ require "base64"
2
3
  require "flores/random"
3
4
  require "logstash/outputs/elasticsearch"
4
5
 
@@ -142,6 +143,25 @@ describe LogStash::Outputs::ElasticSearch do
142
143
 
143
144
  include_examples("an authenticated config")
144
145
  end
146
+
147
+ context 'claud_auth also set' do
148
+ let(:do_register) { false } # this is what we want to test, so we disable the before(:each) call
149
+ let(:options) { { "user" => user, "password" => password, "cloud_auth" => "elastic:my-passwd-00" } }
150
+
151
+ it "should fail" do
152
+ expect { subject.register }.to raise_error LogStash::ConfigurationError, /Multiple authentication options are specified/
153
+ end
154
+ end
155
+
156
+ context 'api_key also set' do
157
+ let(:do_register) { false } # this is what we want to test, so we disable the before(:each) call
158
+ let(:options) { { "user" => user, "password" => password, "api_key" => "some_key" } }
159
+
160
+ it "should fail" do
161
+ expect { subject.register }.to raise_error LogStash::ConfigurationError, /Multiple authentication options are specified/
162
+ end
163
+ end
164
+
145
165
  end
146
166
 
147
167
  describe "with path" do
@@ -577,7 +597,15 @@ describe LogStash::Outputs::ElasticSearch do
577
597
  let(:options) { { 'cloud_auth' => 'elastic:my-passwd-00', 'user' => 'another' } }
578
598
 
579
599
  it "should fail" do
580
- expect { subject.register }.to raise_error LogStash::ConfigurationError, /cloud_auth and user/
600
+ expect { subject.register }.to raise_error LogStash::ConfigurationError, /Multiple authentication options are specified/
601
+ end
602
+ end
603
+
604
+ context 'api_key also set' do
605
+ let(:options) { { 'cloud_auth' => 'elastic:my-passwd-00', 'api_key' => 'some_key' } }
606
+
607
+ it "should fail" do
608
+ expect { subject.register }.to raise_error LogStash::ConfigurationError, /Multiple authentication options are specified/
581
609
  end
582
610
  end
583
611
  end if LOGSTASH_VERSION > '6.0'
@@ -659,6 +687,62 @@ describe LogStash::Outputs::ElasticSearch do
659
687
  end
660
688
  end
661
689
 
690
+ describe "API key" do
691
+ let(:manticore_options) { subject.client.pool.adapter.manticore.instance_variable_get(:@options) }
692
+ let(:api_key) { "some_id:some_api_key" }
693
+ let(:base64_api_key) { "ApiKey c29tZV9pZDpzb21lX2FwaV9rZXk=" }
694
+
695
+ context "when set without ssl" do
696
+ let(:do_register) { false } # this is what we want to test, so we disable the before(:each) call
697
+ let(:options) { { "api_key" => api_key } }
698
+
699
+ it "should raise a configuration error" do
700
+ expect { subject.register }.to raise_error LogStash::ConfigurationError, /requires SSL\/TLS/
701
+ end
702
+ end
703
+
704
+ context "when set without ssl but with a https host" do
705
+ let(:do_register) { false } # this is what we want to test, so we disable the before(:each) call
706
+ let(:options) { { "hosts" => ["https://some.host.com"], "api_key" => api_key } }
707
+
708
+ it "should raise a configuration error" do
709
+ expect { subject.register }.to raise_error LogStash::ConfigurationError, /requires SSL\/TLS/
710
+ end
711
+ end
712
+
713
+ context "when set" do
714
+ let(:options) { { "ssl" => true, "api_key" => ::LogStash::Util::Password.new(api_key) } }
715
+
716
+ it "should use the custom headers in the adapter options" do
717
+ expect(manticore_options[:headers]).to eq({ "Authorization" => base64_api_key })
718
+ end
719
+ end
720
+
721
+ context "when not set" do
722
+ it "should have no headers" do
723
+ expect(manticore_options[:headers]).to be_empty
724
+ end
725
+ end
726
+
727
+ context 'user also set' do
728
+ let(:do_register) { false } # this is what we want to test, so we disable the before(:each) call
729
+ let(:options) { { "ssl" => true, "api_key" => api_key, 'user' => 'another' } }
730
+
731
+ it "should fail" do
732
+ expect { subject.register }.to raise_error LogStash::ConfigurationError, /Multiple authentication options are specified/
733
+ end
734
+ end
735
+
736
+ context 'cloud_auth also set' do
737
+ let(:do_register) { false } # this is what we want to test, so we disable the before(:each) call
738
+ let(:options) { { "ssl" => true, "api_key" => api_key, 'cloud_auth' => 'foobar' } }
739
+
740
+ it "should fail" do
741
+ expect { subject.register }.to raise_error LogStash::ConfigurationError, /Multiple authentication options are specified/
742
+ end
743
+ end
744
+ end
745
+
662
746
  @private
663
747
 
664
748
  def stub_manticore_client!(manticore_double = nil)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-output-elasticsearch
3
3
  version: !ruby/object:Gem::Version
4
- version: 10.4.2
4
+ version: 10.5.0
5
5
  platform: java
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-04-23 00:00:00.000000000 Z
11
+ date: 2020-04-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement