logstash-input-elasticsearch 4.3.3 → 4.6.2

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: 72f28226e8297df8d4eda501ef9a99a67c11bab0574711f553797c678cd5e9a8
4
- data.tar.gz: d141edd1c0664b1f77f4ddc757cda564781aeaa2ada1ebee828ac2f76268c1de
3
+ metadata.gz: 92c58eb709a67922d73d44a13cca7fc933968747feebb0c7afa81c04ea3543d2
4
+ data.tar.gz: 4354af2982b8af23492a8c1f4c063c21ce6e2d1bfc1e082a9de243ab1c575248
5
5
  SHA512:
6
- metadata.gz: 468f91f896d037895c7479e7ae377cee60c4b0c22b05918695f35b6e56bdfa405524fd04d03440133ac40a71fa4ed00251ad27e38792f7c30a8b736ffaa186c9
7
- data.tar.gz: 5ba240ae691f622ab6bf410b7603ebbb959ee5c50cddc90748dd26a1a349fcc36057e9147a15d0501ea1e4f0bbc2861f3042c0addc070568ec805cdd6668d999
6
+ metadata.gz: ba09a7c97593fb2b32cbd4c1f5c4448af2d6ed10c32908ea98b5d4bd54ec0bf11321ae30c48afa745be27bc6280c8fbac6c3f7e62dfa8d5887142dce04e3d0b3
7
+ data.tar.gz: 86e4b75f7937c4e66a23b5724902d35db23303d297d7d46cfb55092efc14d0141e708b73b2a72ee1f459f27bc4a9ee0f46d337de2b31b9f38675e25286b58778
@@ -1,3 +1,18 @@
1
+ ## 4.6.2
2
+ - Added scroll clearing and better handling of scroll expiration [#128](https://github.com/logstash-plugins/logstash-input-elasticsearch/pull/128)
3
+
4
+ ## 4.6.1
5
+ - [DOC] Removed outdated compatibility notice [#124](https://github.com/logstash-plugins/logstash-input-elasticsearch/pull/124)
6
+
7
+ ## 4.6.0
8
+ - Feat: added option to specify proxy for ES [#114](https://github.com/logstash-plugins/logstash-input-elasticsearch/pull/114)
9
+
10
+ ## 4.5.0
11
+ - Feat: Added support for cloud_id / cloud_auth configuration [#112](https://github.com/logstash-plugins/logstash-input-elasticsearch/pull/112)
12
+
13
+ ## 4.4.0
14
+ - Changed Elasticsearch Client transport to use Manticore [#111](https://github.com/logstash-plugins/logstash-input-elasticsearch/pull/111)
15
+
1
16
  ## 4.3.3
2
17
  - Loosen restrictions on Elasticsearch gem [#110](https://github.com/logstash-plugins/logstash-input-elasticsearch/pull/110)
3
18
 
data/LICENSE CHANGED
@@ -1,13 +1,202 @@
1
- Copyright (c) 2012-2018 Elasticsearch <http://www.elastic.co>
2
1
 
3
- Licensed under the Apache License, Version 2.0 (the "License");
4
- you may not use this file except in compliance with the License.
5
- You may obtain a copy of the License at
2
+ Apache License
3
+ Version 2.0, January 2004
4
+ http://www.apache.org/licenses/
6
5
 
7
- http://www.apache.org/licenses/LICENSE-2.0
6
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
8
7
 
9
- Unless required by applicable law or agreed to in writing, software
10
- distributed under the License is distributed on an "AS IS" BASIS,
11
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- See the License for the specific language governing permissions and
13
- limitations under the License.
8
+ 1. Definitions.
9
+
10
+ "License" shall mean the terms and conditions for use, reproduction,
11
+ and distribution as defined by Sections 1 through 9 of this document.
12
+
13
+ "Licensor" shall mean the copyright owner or entity authorized by
14
+ the copyright owner that is granting the License.
15
+
16
+ "Legal Entity" shall mean the union of the acting entity and all
17
+ other entities that control, are controlled by, or are under common
18
+ control with that entity. For the purposes of this definition,
19
+ "control" means (i) the power, direct or indirect, to cause the
20
+ direction or management of such entity, whether by contract or
21
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
22
+ outstanding shares, or (iii) beneficial ownership of such entity.
23
+
24
+ "You" (or "Your") shall mean an individual or Legal Entity
25
+ exercising permissions granted by this License.
26
+
27
+ "Source" form shall mean the preferred form for making modifications,
28
+ including but not limited to software source code, documentation
29
+ source, and configuration files.
30
+
31
+ "Object" form shall mean any form resulting from mechanical
32
+ transformation or translation of a Source form, including but
33
+ not limited to compiled object code, generated documentation,
34
+ and conversions to other media types.
35
+
36
+ "Work" shall mean the work of authorship, whether in Source or
37
+ Object form, made available under the License, as indicated by a
38
+ copyright notice that is included in or attached to the work
39
+ (an example is provided in the Appendix below).
40
+
41
+ "Derivative Works" shall mean any work, whether in Source or Object
42
+ form, that is based on (or derived from) the Work and for which the
43
+ editorial revisions, annotations, elaborations, or other modifications
44
+ represent, as a whole, an original work of authorship. For the purposes
45
+ of this License, Derivative Works shall not include works that remain
46
+ separable from, or merely link (or bind by name) to the interfaces of,
47
+ the Work and Derivative Works thereof.
48
+
49
+ "Contribution" shall mean any work of authorship, including
50
+ the original version of the Work and any modifications or additions
51
+ to that Work or Derivative Works thereof, that is intentionally
52
+ submitted to Licensor for inclusion in the Work by the copyright owner
53
+ or by an individual or Legal Entity authorized to submit on behalf of
54
+ the copyright owner. For the purposes of this definition, "submitted"
55
+ means any form of electronic, verbal, or written communication sent
56
+ to the Licensor or its representatives, including but not limited to
57
+ communication on electronic mailing lists, source code control systems,
58
+ and issue tracking systems that are managed by, or on behalf of, the
59
+ Licensor for the purpose of discussing and improving the Work, but
60
+ excluding communication that is conspicuously marked or otherwise
61
+ designated in writing by the copyright owner as "Not a Contribution."
62
+
63
+ "Contributor" shall mean Licensor and any individual or Legal Entity
64
+ on behalf of whom a Contribution has been received by Licensor and
65
+ subsequently incorporated within the Work.
66
+
67
+ 2. Grant of Copyright License. Subject to the terms and conditions of
68
+ this License, each Contributor hereby grants to You a perpetual,
69
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70
+ copyright license to reproduce, prepare Derivative Works of,
71
+ publicly display, publicly perform, sublicense, and distribute the
72
+ Work and such Derivative Works in Source or Object form.
73
+
74
+ 3. Grant of Patent License. Subject to the terms and conditions of
75
+ this License, each Contributor hereby grants to You a perpetual,
76
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77
+ (except as stated in this section) patent license to make, have made,
78
+ use, offer to sell, sell, import, and otherwise transfer the Work,
79
+ where such license applies only to those patent claims licensable
80
+ by such Contributor that are necessarily infringed by their
81
+ Contribution(s) alone or by combination of their Contribution(s)
82
+ with the Work to which such Contribution(s) was submitted. If You
83
+ institute patent litigation against any entity (including a
84
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
85
+ or a Contribution incorporated within the Work constitutes direct
86
+ or contributory patent infringement, then any patent licenses
87
+ granted to You under this License for that Work shall terminate
88
+ as of the date such litigation is filed.
89
+
90
+ 4. Redistribution. You may reproduce and distribute copies of the
91
+ Work or Derivative Works thereof in any medium, with or without
92
+ modifications, and in Source or Object form, provided that You
93
+ meet the following conditions:
94
+
95
+ (a) You must give any other recipients of the Work or
96
+ Derivative Works a copy of this License; and
97
+
98
+ (b) You must cause any modified files to carry prominent notices
99
+ stating that You changed the files; and
100
+
101
+ (c) You must retain, in the Source form of any Derivative Works
102
+ that You distribute, all copyright, patent, trademark, and
103
+ attribution notices from the Source form of the Work,
104
+ excluding those notices that do not pertain to any part of
105
+ the Derivative Works; and
106
+
107
+ (d) If the Work includes a "NOTICE" text file as part of its
108
+ distribution, then any Derivative Works that You distribute must
109
+ include a readable copy of the attribution notices contained
110
+ within such NOTICE file, excluding those notices that do not
111
+ pertain to any part of the Derivative Works, in at least one
112
+ of the following places: within a NOTICE text file distributed
113
+ as part of the Derivative Works; within the Source form or
114
+ documentation, if provided along with the Derivative Works; or,
115
+ within a display generated by the Derivative Works, if and
116
+ wherever such third-party notices normally appear. The contents
117
+ of the NOTICE file are for informational purposes only and
118
+ do not modify the License. You may add Your own attribution
119
+ notices within Derivative Works that You distribute, alongside
120
+ or as an addendum to the NOTICE text from the Work, provided
121
+ that such additional attribution notices cannot be construed
122
+ as modifying the License.
123
+
124
+ You may add Your own copyright statement to Your modifications and
125
+ may provide additional or different license terms and conditions
126
+ for use, reproduction, or distribution of Your modifications, or
127
+ for any such Derivative Works as a whole, provided Your use,
128
+ reproduction, and distribution of the Work otherwise complies with
129
+ the conditions stated in this License.
130
+
131
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
132
+ any Contribution intentionally submitted for inclusion in the Work
133
+ by You to the Licensor shall be under the terms and conditions of
134
+ this License, without any additional terms or conditions.
135
+ Notwithstanding the above, nothing herein shall supersede or modify
136
+ the terms of any separate license agreement you may have executed
137
+ with Licensor regarding such Contributions.
138
+
139
+ 6. Trademarks. This License does not grant permission to use the trade
140
+ names, trademarks, service marks, or product names of the Licensor,
141
+ except as required for reasonable and customary use in describing the
142
+ origin of the Work and reproducing the content of the NOTICE file.
143
+
144
+ 7. Disclaimer of Warranty. Unless required by applicable law or
145
+ agreed to in writing, Licensor provides the Work (and each
146
+ Contributor provides its Contributions) on an "AS IS" BASIS,
147
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148
+ implied, including, without limitation, any warranties or conditions
149
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150
+ PARTICULAR PURPOSE. You are solely responsible for determining the
151
+ appropriateness of using or redistributing the Work and assume any
152
+ risks associated with Your exercise of permissions under this License.
153
+
154
+ 8. Limitation of Liability. In no event and under no legal theory,
155
+ whether in tort (including negligence), contract, or otherwise,
156
+ unless required by applicable law (such as deliberate and grossly
157
+ negligent acts) or agreed to in writing, shall any Contributor be
158
+ liable to You for damages, including any direct, indirect, special,
159
+ incidental, or consequential damages of any character arising as a
160
+ result of this License or out of the use or inability to use the
161
+ Work (including but not limited to damages for loss of goodwill,
162
+ work stoppage, computer failure or malfunction, or any and all
163
+ other commercial damages or losses), even if such Contributor
164
+ has been advised of the possibility of such damages.
165
+
166
+ 9. Accepting Warranty or Additional Liability. While redistributing
167
+ the Work or Derivative Works thereof, You may choose to offer,
168
+ and charge a fee for, acceptance of support, warranty, indemnity,
169
+ or other liability obligations and/or rights consistent with this
170
+ License. However, in accepting such obligations, You may act only
171
+ on Your own behalf and on Your sole responsibility, not on behalf
172
+ of any other Contributor, and only if You agree to indemnify,
173
+ defend, and hold each Contributor harmless for any liability
174
+ incurred by, or claims asserted against, such Contributor by reason
175
+ of your accepting any such warranty or additional liability.
176
+
177
+ END OF TERMS AND CONDITIONS
178
+
179
+ APPENDIX: How to apply the Apache License to your work.
180
+
181
+ To apply the Apache License to your work, attach the following
182
+ boilerplate notice, with the fields enclosed by brackets "[]"
183
+ replaced with your own identifying information. (Don't include
184
+ the brackets!) The text should be enclosed in the appropriate
185
+ comment syntax for the file format. We also recommend that a
186
+ file or class name and description of purpose be included on the
187
+ same "printed page" as the copyright notice for easier
188
+ identification within third-party archives.
189
+
190
+ Copyright 2020 Elastic and contributors
191
+
192
+ Licensed under the Apache License, Version 2.0 (the "License");
193
+ you may not use this file except in compliance with the License.
194
+ You may obtain a copy of the License at
195
+
196
+ http://www.apache.org/licenses/LICENSE-2.0
197
+
198
+ Unless required by applicable law or agreed to in writing, software
199
+ distributed under the License is distributed on an "AS IS" BASIS,
200
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201
+ See the License for the specific language governing permissions and
202
+ limitations under the License.
@@ -21,16 +21,6 @@ include::{include_path}/plugin_header.asciidoc[]
21
21
 
22
22
  ==== Description
23
23
 
24
- .Compatibility Note
25
- [NOTE]
26
- ================================================================================
27
- Starting with Elasticsearch 5.3, there's an {ref}/modules-http.html[HTTP setting]
28
- called `http.content_type.required`. If this option is set to `true`, and you
29
- are using Logstash 2.4 through 5.2, you need to update the Elasticsearch input
30
- plugin to version 4.0.2 or higher.
31
-
32
- ================================================================================
33
-
34
24
  Read from an Elasticsearch cluster, based on search query results.
35
25
  This is useful for replaying test logs, reindexing, etc.
36
26
  You can periodically schedule ingestion using a cron syntax
@@ -87,12 +77,15 @@ This plugin supports the following configuration options plus the <
87
77
  |=======================================================================
88
78
  |Setting |Input type|Required
89
79
  | <<plugins-{type}s-{plugin}-ca_file>> |a valid filesystem path|No
80
+ | <<plugins-{type}s-{plugin}-cloud_auth>> |<<password,password>>|No
81
+ | <<plugins-{type}s-{plugin}-cloud_id>> |<<string,string>>|No
90
82
  | <<plugins-{type}s-{plugin}-docinfo>> |<<boolean,boolean>>|No
91
83
  | <<plugins-{type}s-{plugin}-docinfo_fields>> |<<array,array>>|No
92
84
  | <<plugins-{type}s-{plugin}-docinfo_target>> |<<string,string>>|No
93
85
  | <<plugins-{type}s-{plugin}-hosts>> |<<array,array>>|No
94
86
  | <<plugins-{type}s-{plugin}-index>> |<<string,string>>|No
95
87
  | <<plugins-{type}s-{plugin}-password>> |<<password,password>>|No
88
+ | <<plugins-{type}s-{plugin}-proxy>> |<<uri,uri>>|No
96
89
  | <<plugins-{type}s-{plugin}-query>> |<<string,string>>|No
97
90
  | <<plugins-{type}s-{plugin}-schedule>> |<<string,string>>|No
98
91
  | <<plugins-{type}s-{plugin}-scroll>> |<<string,string>>|No
@@ -113,8 +106,27 @@ input plugins.
113
106
  * Value type is <<path,path>>
114
107
  * There is no default value for this setting.
115
108
 
116
- SSL Certificate Authority file in PEM encoded format, must also
117
- include any chain certificates as necessary.
109
+ SSL Certificate Authority file in PEM encoded format, must also include any chain certificates as necessary.
110
+
111
+ [id="plugins-{type}s-{plugin}-cloud_auth"]
112
+ ===== `cloud_auth`
113
+
114
+ * Value type is <<password,password>>
115
+ * There is no default value for this setting.
116
+
117
+ Cloud authentication string ("<username>:<password>" format) is an alternative for the `user`/`password` pair.
118
+
119
+ For more info, check out the https://www.elastic.co/guide/en/logstash/current/connecting-to-cloud.html#_cloud_auth[Logstash-to-Cloud documentation]
120
+
121
+ [id="plugins-{type}s-{plugin}-cloud_id"]
122
+ ===== `cloud_id`
123
+
124
+ * Value type is <<string,string>>
125
+ * There is no default value for this setting.
126
+
127
+ Cloud ID, from the Elastic Cloud web console. If set `hosts` should not be used.
128
+
129
+ For more info, check out the https://www.elastic.co/guide/en/logstash/current/connecting-to-cloud.html#_cloud_id[Logstash-to-Cloud documentation]
118
130
 
119
131
  [id="plugins-{type}s-{plugin}-docinfo"]
120
132
  ===== `docinfo`
@@ -152,11 +164,6 @@ Example
152
164
  }
153
165
 
154
166
 
155
- NOTE: Starting with Logstash 6.0, the `document_type` option is
156
- deprecated due to the
157
- https://www.elastic.co/guide/en/elasticsearch/reference/6.0/removal-of-types.html[removal of types in Logstash 6.0].
158
- It will be removed in the next major version of Logstash.
159
-
160
167
  [id="plugins-{type}s-{plugin}-docinfo_fields"]
161
168
  ===== `docinfo_fields`
162
169
 
@@ -210,6 +217,16 @@ The password to use together with the username in the `user` option
210
217
  when authenticating to the Elasticsearch server. If set to an empty
211
218
  string authentication will be disabled.
212
219
 
220
+ [id="plugins-{type}s-{plugin}-proxy"]
221
+ ===== `proxy`
222
+
223
+ * Value type is <<uri,uri>>
224
+ * There is no default value for this setting.
225
+
226
+ Set the address of a forward HTTP proxy.
227
+ An empty string is treated as if proxy was not set, this is useful when using
228
+ environment variables e.g. `proxy => '${LS_PROXY:}'`.
229
+
213
230
  [id="plugins-{type}s-{plugin}-query"]
214
231
  ===== `query`
215
232
 
@@ -2,8 +2,10 @@
2
2
  require "logstash/inputs/base"
3
3
  require "logstash/namespace"
4
4
  require "logstash/json"
5
+ require "logstash/util/safe_uri"
5
6
  require "base64"
6
7
 
8
+
7
9
  # .Compatibility Note
8
10
  # [NOTE]
9
11
  # ================================================================================
@@ -68,6 +70,11 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
68
70
  # Port defaults to 9200
69
71
  config :hosts, :validate => :array
70
72
 
73
+ # Cloud ID, from the Elastic Cloud web console. If set `hosts` should not be used.
74
+ #
75
+ # For more info, check out the https://www.elastic.co/guide/en/logstash/current/connecting-to-cloud.html#_cloud_id[Logstash-to-Cloud documentation]
76
+ config :cloud_id, :validate => :string
77
+
71
78
  # The index or alias to search.
72
79
  config :index, :validate => :string, :default => "logstash-*"
73
80
 
@@ -133,6 +140,14 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
133
140
  # Basic Auth - password
134
141
  config :password, :validate => :password
135
142
 
143
+ # Cloud authentication string ("<username>:<password>" format) is an alternative for the `user`/`password` configuration.
144
+ #
145
+ # For more info, check out the https://www.elastic.co/guide/en/logstash/current/connecting-to-cloud.html#_cloud_auth[Logstash-to-Cloud documentation]
146
+ config :cloud_auth, :validate => :password
147
+
148
+ # Set the address of a forward HTTP proxy.
149
+ config :proxy, :validate => :uri_or_empty
150
+
136
151
  # SSL
137
152
  config :ssl, :validate => :boolean, :default => false
138
153
 
@@ -149,6 +164,7 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
149
164
  def register
150
165
  require "elasticsearch"
151
166
  require "rufus/scheduler"
167
+ require "elasticsearch/transport/transport/http/manticore"
152
168
 
153
169
  @options = {
154
170
  :index => @index,
@@ -163,12 +179,17 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
163
179
 
164
180
  transport_options = {}
165
181
 
182
+ fill_user_password_from_cloud_auth
183
+
166
184
  if @user && @password
167
185
  token = Base64.strict_encode64("#{@user}:#{@password.value}")
168
186
  transport_options[:headers] = { :Authorization => "Basic #{token}" }
169
187
  end
170
188
 
171
- hosts = if @ssl then
189
+ fill_hosts_from_cloud_id
190
+ @hosts = Array(@hosts).map { |host| host.to_s } # potential SafeURI#to_s
191
+
192
+ hosts = if @ssl
172
193
  @hosts.map do |h|
173
194
  host, port = h.split(":")
174
195
  { :host => host, :scheme => 'https', :port => port }
@@ -176,14 +197,37 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
176
197
  else
177
198
  @hosts
178
199
  end
200
+ ssl_options = { :ssl => true, :ca_file => @ca_file } if @ssl && @ca_file
201
+ ssl_options ||= {}
179
202
 
180
- if @ssl && @ca_file
181
- transport_options[:ssl] = { :ca_file => @ca_file }
182
- end
203
+ @logger.warn "Supplied proxy setting (proxy => '') has no effect" if @proxy.eql?('')
183
204
 
184
- @client = Elasticsearch::Client.new(:hosts => hosts, :transport_options => transport_options)
205
+ transport_options[:proxy] = @proxy.to_s if @proxy && !@proxy.eql?('')
206
+
207
+ @client = Elasticsearch::Client.new(
208
+ :hosts => hosts,
209
+ :transport_options => transport_options,
210
+ :transport_class => ::Elasticsearch::Transport::Transport::HTTP::Manticore,
211
+ :ssl => ssl_options
212
+ )
185
213
  end
186
214
 
215
+ ##
216
+ # @override to handle proxy => '' as if none was set
217
+ # @param value [Array<Object>]
218
+ # @param validator [nil,Array,Symbol]
219
+ # @return [Array(true,Object)]: if validation is a success, a tuple containing `true` and the coerced value
220
+ # @return [Array(false,String)]: if validation is a failure, a tuple containing `false` and the failure reason.
221
+ def self.validate_value(value, validator)
222
+ return super unless validator == :uri_or_empty
223
+
224
+ value = deep_replace(value)
225
+ value = hash_or_array(value)
226
+
227
+ return true, value.first if value.size == 1 && value.first.empty?
228
+
229
+ return super(value, :uri)
230
+ end
187
231
 
188
232
  def run(output_queue)
189
233
  if @schedule
@@ -225,25 +269,41 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
225
269
  slice_options = @options.merge(:body => LogStash::Json.dump(slice_query) )
226
270
 
227
271
  logger.info("Slice starting", slice_id: slice_id, slices: @slices) unless slice_id.nil?
228
- r = search_request(slice_options)
229
272
 
230
- r['hits']['hits'].each { |hit| push_hit(hit, output_queue) }
231
- logger.debug("Slice progress", slice_id: slice_id, slices: @slices) unless slice_id.nil?
232
-
233
- has_hits = r['hits']['hits'].any?
273
+ scroll_id = nil
274
+ begin
275
+ r = search_request(slice_options)
234
276
 
235
- while has_hits && r['_scroll_id'] && !stop?
236
- r = process_next_scroll(output_queue, r['_scroll_id'])
277
+ r['hits']['hits'].each { |hit| push_hit(hit, output_queue) }
237
278
  logger.debug("Slice progress", slice_id: slice_id, slices: @slices) unless slice_id.nil?
238
- has_hits = r['has_hits']
279
+
280
+ has_hits = r['hits']['hits'].any?
281
+ scroll_id = r['_scroll_id']
282
+
283
+ while has_hits && scroll_id && !stop?
284
+ has_hits, scroll_id = process_next_scroll(output_queue, scroll_id)
285
+ logger.debug("Slice progress", slice_id: slice_id, slices: @slices) if logger.debug? && slice_id
286
+ end
287
+ logger.info("Slice complete", slice_id: slice_id, slices: @slices) unless slice_id.nil?
288
+ ensure
289
+ clear_scroll(scroll_id)
239
290
  end
240
- logger.info("Slice complete", slice_id: slice_id, slices: @slices) unless slice_id.nil?
241
291
  end
242
292
 
293
+ ##
294
+ # @param output_queue [#<<]
295
+ # @param scroll_id [String]: a scroll id to resume
296
+ # @return [Array(Boolean,String)]: a tuple representing whether the response
297
+ #
243
298
  def process_next_scroll(output_queue, scroll_id)
244
299
  r = scroll_request(scroll_id)
245
300
  r['hits']['hits'].each { |hit| push_hit(hit, output_queue) }
246
- {'has_hits' => r['hits']['hits'].any?, '_scroll_id' => r['_scroll_id']}
301
+ [r['hits']['hits'].any?, r['_scroll_id']]
302
+ rescue => e
303
+ # this will typically be triggered by a scroll timeout
304
+ logger.error("Scroll request error, aborting scroll", error: e.inspect)
305
+ # return no hits and original scroll_id so we can try to clear it
306
+ [false, scroll_id]
247
307
  end
248
308
 
249
309
  def push_hit(hit, output_queue)
@@ -272,6 +332,13 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
272
332
  output_queue << event
273
333
  end
274
334
 
335
+ def clear_scroll(scroll_id)
336
+ @client.clear_scroll(scroll_id: scroll_id) if scroll_id
337
+ rescue => e
338
+ # ignore & log any clear_scroll errors
339
+ logger.warn("Ignoring clear_scroll exception", message: e.message)
340
+ end
341
+
275
342
  def scroll_request scroll_id
276
343
  @client.scroll(:body => { :scroll_id => scroll_id }, :scroll => @scroll)
277
344
  end
@@ -279,4 +346,62 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
279
346
  def search_request(options)
280
347
  @client.search(options)
281
348
  end
349
+
350
+ def hosts_default?(hosts)
351
+ hosts.nil? || ( hosts.is_a?(Array) && hosts.empty? )
352
+ end
353
+
354
+ def fill_hosts_from_cloud_id
355
+ return unless @cloud_id
356
+
357
+ if @hosts && !hosts_default?(@hosts)
358
+ raise LogStash::ConfigurationError, 'Both cloud_id and hosts specified, please only use one of those.'
359
+ end
360
+ @hosts = parse_host_uri_from_cloud_id(@cloud_id)
361
+ end
362
+
363
+ def fill_user_password_from_cloud_auth
364
+ return unless @cloud_auth
365
+
366
+ if @user || @password
367
+ raise LogStash::ConfigurationError, 'Both cloud_auth and user/password specified, please only use one.'
368
+ end
369
+ @user, @password = parse_user_password_from_cloud_auth(@cloud_auth)
370
+ params['user'], params['password'] = @user, @password
371
+ end
372
+
373
+ def parse_host_uri_from_cloud_id(cloud_id)
374
+ begin # might not be available on older LS
375
+ require 'logstash/util/cloud_setting_id'
376
+ rescue LoadError
377
+ raise LogStash::ConfigurationError, 'The cloud_id setting is not supported by your version of Logstash, ' +
378
+ 'please upgrade your installation (or set hosts instead).'
379
+ end
380
+
381
+ begin
382
+ cloud_id = LogStash::Util::CloudSettingId.new(cloud_id) # already does append ':{port}' to host
383
+ rescue ArgumentError => e
384
+ raise LogStash::ConfigurationError, e.message.to_s.sub(/Cloud Id/i, 'cloud_id')
385
+ end
386
+ cloud_uri = "#{cloud_id.elasticsearch_scheme}://#{cloud_id.elasticsearch_host}"
387
+ LogStash::Util::SafeURI.new(cloud_uri)
388
+ end
389
+
390
+ def parse_user_password_from_cloud_auth(cloud_auth)
391
+ begin # might not be available on older LS
392
+ require 'logstash/util/cloud_setting_auth'
393
+ rescue LoadError
394
+ raise LogStash::ConfigurationError, 'The cloud_auth setting is not supported by your version of Logstash, ' +
395
+ 'please upgrade your installation (or set user/password instead).'
396
+ end
397
+
398
+ cloud_auth = cloud_auth.value if cloud_auth.is_a?(LogStash::Util::Password)
399
+ begin
400
+ cloud_auth = LogStash::Util::CloudSettingAuth.new(cloud_auth)
401
+ rescue ArgumentError => e
402
+ raise LogStash::ConfigurationError, e.message.to_s.sub(/Cloud Auth/i, 'cloud_auth')
403
+ end
404
+ [ cloud_auth.username, cloud_auth.password ]
405
+ end
406
+
282
407
  end
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
 
3
3
  s.name = 'logstash-input-elasticsearch'
4
- s.version = '4.3.3'
4
+ s.version = '4.6.2'
5
5
  s.licenses = ['Apache License (2.0)']
6
6
  s.summary = "Reads query results from an Elasticsearch cluster"
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"
@@ -30,6 +30,8 @@ Gem::Specification.new do |s|
30
30
  s.add_runtime_dependency 'tzinfo'
31
31
  s.add_runtime_dependency 'tzinfo-data'
32
32
  s.add_runtime_dependency 'rufus-scheduler'
33
+ s.add_runtime_dependency 'manticore', "~> 0.6"
34
+ s.add_runtime_dependency 'faraday', "~> 0.15.4"
33
35
 
34
36
  s.add_development_dependency 'logstash-devutils'
35
37
  s.add_development_dependency 'timecop'
@@ -1,11 +1,30 @@
1
1
  module ESHelper
2
2
  def self.get_host_port
3
- return "http://elasticsearch:9200" if ENV["INTEGRATION"] == "true"
3
+ return "elasticsearch:9200" if ENV["INTEGRATION"] == "true" || ENV["SECURE_INTEGRATION"] == "true"
4
4
  raise "This setting is only used for integration tests"
5
5
  end
6
6
 
7
- def self.get_client
8
- Elasticsearch::Client.new(:hosts => [get_host_port])
7
+ def self.get_client(options = {})
8
+ ssl_options = {}
9
+ hosts = [get_host_port]
10
+
11
+ if options[:ca_file]
12
+ ssl_options = { :ssl => true, :ca_file => options[:ca_file] }
13
+ hosts.map! do |h|
14
+ host, port = h.split(":")
15
+ { :host => host, :scheme => 'https', :port => port }
16
+ end
17
+ end
18
+
19
+ transport_options = {}
20
+
21
+ if options[:user] && options[:password]
22
+ token = Base64.strict_encode64("#{options[:user]}:#{options[:password]}")
23
+ transport_options[:headers] = { :Authorization => "Basic #{token}" }
24
+ end
25
+
26
+ @client = Elasticsearch::Client.new(:hosts => hosts, :transport_options => transport_options, :ssl => ssl_options,
27
+ :transport_class => ::Elasticsearch::Transport::Transport::HTTP::Manticore)
9
28
  end
10
29
 
11
30
  def self.doc_type
@@ -0,0 +1,32 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ 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
31
+ nIg9fQPvVw+fIHACZQ==
32
+ -----END CERTIFICATE-----
@@ -0,0 +1,51 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ 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
51
+ -----END RSA PRIVATE KEY-----
@@ -0,0 +1,36 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ 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
35
+ FKbYFqzgpWksa+zZ2RYYplUAxq0wYw==
36
+ -----END CERTIFICATE-----
@@ -0,0 +1,51 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ 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
51
+ -----END RSA PRIVATE KEY-----
@@ -1,5 +1,6 @@
1
1
  # encoding: utf-8
2
2
  require "logstash/devutils/rspec/spec_helper"
3
+ require "logstash/devutils/rspec/shared_examples"
3
4
  require "logstash/inputs/elasticsearch"
4
5
  require "elasticsearch"
5
6
  require "timecop"
@@ -7,9 +8,13 @@ require "stud/temporary"
7
8
  require "time"
8
9
  require "date"
9
10
 
10
- describe LogStash::Inputs::Elasticsearch do
11
+ class LogStash::Inputs::TestableElasticsearch < LogStash::Inputs::Elasticsearch
12
+ attr_reader :client
13
+ end
14
+
15
+ describe LogStash::Inputs::TestableElasticsearch do
11
16
 
12
- let(:plugin) { LogStash::Inputs::Elasticsearch.new(config) }
17
+ let(:plugin) { LogStash::Inputs::TestableElasticsearch.new(config) }
13
18
  let(:queue) { Queue.new }
14
19
 
15
20
  it_behaves_like "an interruptible input plugin" do
@@ -31,6 +36,7 @@ describe LogStash::Inputs::Elasticsearch do
31
36
  }
32
37
  allow(esclient).to receive(:search) { { "hits" => { "hits" => [hit] } } }
33
38
  allow(esclient).to receive(:scroll) { { "hits" => { "hits" => [hit] } } }
39
+ allow(esclient).to receive(:clear_scroll).and_return(nil)
34
40
  end
35
41
  end
36
42
 
@@ -75,13 +81,14 @@ describe LogStash::Inputs::Elasticsearch do
75
81
  expect(Elasticsearch::Client).to receive(:new).with(any_args).and_return(client)
76
82
  expect(client).to receive(:search).with(any_args).and_return(response)
77
83
  expect(client).to receive(:scroll).with({ :body => { :scroll_id => "cXVlcnlUaGVuRmV0Y2g" }, :scroll=> "1m" }).and_return(scroll_reponse)
84
+ expect(client).to receive(:clear_scroll).and_return(nil)
78
85
 
79
86
  event = input(config) do |pipeline, queue|
80
87
  queue.pop
81
88
  end
82
89
 
83
- insist { event }.is_a?(LogStash::Event)
84
- insist { event.get("message") } == [ "ohayo" ]
90
+ expect(event).to be_a(LogStash::Event)
91
+ expect(event.get("message")).to eql [ "ohayo" ]
85
92
  end
86
93
 
87
94
 
@@ -256,6 +263,8 @@ describe LogStash::Inputs::Elasticsearch do
256
263
  expect(Elasticsearch::Client).to receive(:new).with(any_args).and_return(client)
257
264
  plugin.register
258
265
 
266
+ expect(client).to receive(:clear_scroll).and_return(nil)
267
+
259
268
  # SLICE0 is a three-page scroll in which the last page is empty
260
269
  slice0_query = LogStash::Json.dump(query.merge('slice' => { 'id' => 0, 'max' => 2}))
261
270
  expect(client).to receive(:search).with(hash_including(:body => slice0_query)).and_return(slice0_response0)
@@ -359,6 +368,7 @@ describe LogStash::Inputs::Elasticsearch do
359
368
  expect(Elasticsearch::Client).to receive(:new).with(any_args).and_return(client)
360
369
  expect(client).to receive(:search).with(any_args).and_return(response)
361
370
  allow(client).to receive(:scroll).with({ :body => {:scroll_id => "cXVlcnlUaGVuRmV0Y2g"}, :scroll => "1m" }).and_return(scroll_reponse)
371
+ allow(client).to receive(:clear_scroll).and_return(nil)
362
372
  end
363
373
 
364
374
  context 'when defining docinfo' do
@@ -404,6 +414,7 @@ describe LogStash::Inputs::Elasticsearch do
404
414
  "docinfo_target" => 'metadata_with_string'
405
415
  } }
406
416
  it 'thows an exception if the `docinfo_target` exist but is not of type hash' do
417
+ expect(client).not_to receive(:clear_scroll)
407
418
  plugin.register
408
419
  expect { plugin.run([]) }.to raise_error(Exception, /incompatible event/)
409
420
  end
@@ -504,6 +515,103 @@ describe LogStash::Inputs::Elasticsearch do
504
515
  end
505
516
  end
506
517
 
518
+ describe "client" do
519
+ let(:config) do
520
+ {
521
+
522
+ }
523
+ end
524
+ let(:plugin) { described_class.new(config) }
525
+ let(:event) { LogStash::Event.new({}) }
526
+
527
+ describe "cloud.id" do
528
+ let(:valid_cloud_id) do
529
+ 'sample:dXMtY2VudHJhbDEuZ2NwLmNsb3VkLmVzLmlvJGFjMzFlYmI5MDI0MTc3MzE1NzA0M2MzNGZkMjZmZDQ2OjkyNDMkYTRjMDYyMzBlNDhjOGZjZTdiZTg4YTA3NGEzYmIzZTA6OTI0NA=='
530
+ end
531
+
532
+ let(:config) { super.merge({ 'cloud_id' => valid_cloud_id }) }
533
+
534
+ it "should set host(s)" do
535
+ plugin.register
536
+ client = plugin.send(:client)
537
+ expect( client.transport.hosts ).to eql [{
538
+ :scheme => "https",
539
+ :host => "ac31ebb90241773157043c34fd26fd46.us-central1.gcp.cloud.es.io",
540
+ :port => 9243,
541
+ :path => "",
542
+ :protocol => "https"
543
+ }]
544
+ end
545
+
546
+ context 'invalid' do
547
+ let(:config) { super.merge({ 'cloud_id' => 'invalid:dXMtY2VudHJhbDEuZ2NwLmNsb3VkLmVzLmlv' }) }
548
+
549
+ it "should fail" do
550
+ expect { plugin.register }.to raise_error LogStash::ConfigurationError, /cloud_id.*? is invalid/
551
+ end
552
+ end
553
+
554
+ context 'hosts also set' do
555
+ let(:config) { super.merge({ 'cloud_id' => valid_cloud_id, 'hosts' => [ 'localhost:9200' ] }) }
556
+
557
+ it "should fail" do
558
+ expect { plugin.register }.to raise_error LogStash::ConfigurationError, /cloud_id and hosts/
559
+ end
560
+ end
561
+ end if LOGSTASH_VERSION > '6.0'
562
+
563
+ describe "cloud.auth" do
564
+ let(:config) { super.merge({ 'cloud_auth' => LogStash::Util::Password.new('elastic:my-passwd-00') }) }
565
+
566
+ it "should set authorization" do
567
+ plugin.register
568
+ client = plugin.send(:client)
569
+ auth_header = client.transport.options[:transport_options][:headers][:Authorization]
570
+
571
+ expect( auth_header ).to eql "Basic #{Base64.encode64('elastic:my-passwd-00').rstrip}"
572
+ end
573
+
574
+ context 'invalid' do
575
+ let(:config) { super.merge({ 'cloud_auth' => 'invalid-format' }) }
576
+
577
+ it "should fail" do
578
+ expect { plugin.register }.to raise_error LogStash::ConfigurationError, /cloud_auth.*? format/
579
+ end
580
+ end
581
+
582
+ context 'user also set' do
583
+ let(:config) { super.merge({ 'cloud_auth' => 'elastic:my-passwd-00', 'user' => 'another' }) }
584
+
585
+ it "should fail" do
586
+ expect { plugin.register }.to raise_error LogStash::ConfigurationError, /cloud_auth and user/
587
+ end
588
+ end
589
+ end if LOGSTASH_VERSION > '6.0'
590
+
591
+ describe "proxy" do
592
+ let(:config) { super.merge({ 'proxy' => 'http://localhost:1234' }) }
593
+
594
+ it "should set proxy" do
595
+ plugin.register
596
+ client = plugin.send(:client)
597
+ proxy = client.transport.options[:transport_options][:proxy]
598
+
599
+ expect( proxy ).to eql "http://localhost:1234"
600
+ end
601
+
602
+ context 'invalid' do
603
+ let(:config) { super.merge({ 'proxy' => '${A_MISSING_ENV_VAR:}' }) }
604
+
605
+ it "should not set proxy" do
606
+ plugin.register
607
+ client = plugin.send(:client)
608
+
609
+ expect( client.transport.options[:transport_options] ).to_not include(:proxy)
610
+ end
611
+ end
612
+ end
613
+ end
614
+
507
615
  context "when scheduling" do
508
616
  let(:config) do
509
617
  {
@@ -513,39 +621,11 @@ describe LogStash::Inputs::Elasticsearch do
513
621
  }
514
622
  end
515
623
 
516
- response = {
517
- "_scroll_id" => "cXVlcnlUaGVuRmV0Y2g",
518
- "took" => 27,
519
- "timed_out" => false,
520
- "_shards" => {
521
- "total" => 169,
522
- "successful" => 169,
523
- "failed" => 0
524
- },
525
- "hits" => {
526
- "total" => 1,
527
- "max_score" => 1.0,
528
- "hits" => [ {
529
- "_index" => "logstash-2014.10.12",
530
- "_type" => "logs",
531
- "_id" => "C5b2xLQwTZa76jBmHIbwHQ",
532
- "_score" => 1.0,
533
- "_source" => { "message" => ["ohayo"] }
534
- } ]
535
- }
536
- }
537
-
538
- scroll_reponse = {
539
- "_scroll_id" => "r453Wc1jh0caLJhSDg",
540
- "hits" => { "hits" => [] }
541
- }
542
-
543
624
  before do
544
625
  plugin.register
545
626
  end
546
627
 
547
628
  it "should properly schedule" do
548
-
549
629
  Timecop.travel(Time.new(2000))
550
630
  Timecop.scale(60)
551
631
  runner = Thread.new do
@@ -564,5 +644,4 @@ describe LogStash::Inputs::Elasticsearch do
564
644
  end
565
645
 
566
646
  end
567
-
568
647
  end
@@ -4,16 +4,17 @@ require "logstash/plugin"
4
4
  require "logstash/inputs/elasticsearch"
5
5
  require_relative "../../../spec/es_helper"
6
6
 
7
- describe LogStash::Inputs::Elasticsearch, :integration => true do
7
+ describe LogStash::Inputs::Elasticsearch do
8
8
 
9
9
  let(:config) { { 'hosts' => [ESHelper.get_host_port],
10
10
  'index' => 'logs',
11
11
  'query' => '{ "query": { "match": { "message": "Not found"} }}' } }
12
12
  let(:plugin) { described_class.new(config) }
13
13
  let(:event) { LogStash::Event.new({}) }
14
+ let(:client_options) {{}}
14
15
 
15
16
  before(:each) do
16
- @es = ESHelper.get_client
17
+ @es = ESHelper.get_client(client_options)
17
18
  # Delete all templates first.
18
19
  # Clean ES of data before we start.
19
20
  @es.indices.delete_template(:name => "*")
@@ -31,8 +32,8 @@ describe LogStash::Inputs::Elasticsearch, :integration => true do
31
32
  @es.indices.delete(:index => "*") rescue nil
32
33
  end
33
34
 
34
- describe 'smoke test' do
35
- it "should retrieve json event from elasticseach" do
35
+ shared_examples 'an elasticsearch index plugin' do
36
+ it 'should retrieve json event from elasticsearch' do
36
37
  queue = []
37
38
  plugin.run(queue)
38
39
  event = queue.pop
@@ -40,4 +41,23 @@ describe LogStash::Inputs::Elasticsearch, :integration => true do
40
41
  expect(event.get("response")).to eql(404)
41
42
  end
42
43
  end
44
+
45
+ describe 'against an unsecured elasticsearch', :integration => true do
46
+ it_behaves_like 'an elasticsearch index plugin'
47
+ end
48
+
49
+ describe 'against a secured elasticsearch', :secure_integration => true do
50
+ let(:user) { 'simpleuser' }
51
+ let(:password) { 'abc123' }
52
+ let(:ca_file) { "spec/fixtures/test_certs/test.crt" }
53
+ let(:client_options) {{:ca_file => ca_file, :user => user, :password => password}}
54
+ let(:config) { super.merge({
55
+ 'user' => user,
56
+ 'password' => password,
57
+ 'ssl' => true,
58
+ 'ca_file' => ca_file })
59
+ }
60
+ it_behaves_like 'an elasticsearch index plugin'
61
+ end
43
62
  end
63
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-input-elasticsearch
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.3.3
4
+ version: 4.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-11-12 00:00:00.000000000 Z
11
+ date: 2020-06-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -128,6 +128,34 @@ dependencies:
128
128
  - - ">="
129
129
  - !ruby/object:Gem::Version
130
130
  version: '0'
131
+ - !ruby/object:Gem::Dependency
132
+ requirement: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - "~>"
135
+ - !ruby/object:Gem::Version
136
+ version: '0.6'
137
+ name: manticore
138
+ prerelease: false
139
+ type: :runtime
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - "~>"
143
+ - !ruby/object:Gem::Version
144
+ version: '0.6'
145
+ - !ruby/object:Gem::Dependency
146
+ requirement: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - "~>"
149
+ - !ruby/object:Gem::Version
150
+ version: 0.15.4
151
+ name: faraday
152
+ prerelease: false
153
+ type: :runtime
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - "~>"
157
+ - !ruby/object:Gem::Version
158
+ version: 0.15.4
131
159
  - !ruby/object:Gem::Dependency
132
160
  requirement: !ruby/object:Gem::Requirement
133
161
  requirements:
@@ -174,6 +202,10 @@ files:
174
202
  - lib/logstash/inputs/elasticsearch.rb
175
203
  - logstash-input-elasticsearch.gemspec
176
204
  - spec/es_helper.rb
205
+ - spec/fixtures/test_certs/ca/ca.crt
206
+ - spec/fixtures/test_certs/ca/ca.key
207
+ - spec/fixtures/test_certs/test.crt
208
+ - spec/fixtures/test_certs/test.key
177
209
  - spec/inputs/elasticsearch_spec.rb
178
210
  - spec/inputs/integration/elasticsearch_spec.rb
179
211
  homepage: http://www.elastic.co/guide/en/logstash/current/index.html
@@ -204,5 +236,9 @@ specification_version: 4
204
236
  summary: Reads query results from an Elasticsearch cluster
205
237
  test_files:
206
238
  - spec/es_helper.rb
239
+ - spec/fixtures/test_certs/ca/ca.crt
240
+ - spec/fixtures/test_certs/ca/ca.key
241
+ - spec/fixtures/test_certs/test.crt
242
+ - spec/fixtures/test_certs/test.key
207
243
  - spec/inputs/elasticsearch_spec.rb
208
244
  - spec/inputs/integration/elasticsearch_spec.rb