logstash-output-elasticsearch 2.4.2-java → 2.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
  SHA1:
3
- metadata.gz: 22b9b67e7eada407308a8da6bb3ab1c9dabe4e11
4
- data.tar.gz: e434712af48381f69dbd6eb75a3556614ea40e93
3
+ metadata.gz: 94080174a41d46422a7f94b0e9354554d3e0d66a
4
+ data.tar.gz: bddb86d2a5bbbae75734c41610588c3cf5c04f71
5
5
  SHA512:
6
- metadata.gz: b4046883d73f45496ad777cf3e3708a619e4172a07d7c8c682e459a859eac562ce130346f0164de8b8477ce14080d3bfc1bf4b5584111ac861ee0eff961d4b89
7
- data.tar.gz: 1ece9c0def2d670ebd7ffd49308c6838aa1b0c4f1c12a3aef226cda00ebf0f3e348673b68720cc396ad4ddd45f9fa7200d6017afc3867cd6bc5342c17a9c488a
6
+ metadata.gz: 4d59bc4d44c2b1918519e286efb995805abd63dd8d411ae87b82551750182b743ee56ed453d557e12769c21a3535496aa02d79ff77580ba9508499914edc61e2
7
+ data.tar.gz: fdba23ed47b9414ca87d2d7bd75a3c07c440fce5d86c49adcdb4be1a95884266e908f0b73ef55a1c895947714cd2fc19ec6bf0c8887274b9dc9ffab5c51190cc
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 2.5.0
2
+ - Host settings now are more robust to bad input
3
+ - Host settings can now take full URLs
4
+
1
5
  ## 2.4.2
2
6
  - Make flush_size actually cap the batch size in LS 2.2+
3
7
 
@@ -16,7 +16,7 @@ require "uri" # for escaping user input
16
16
  # We strongly encourage the use of HTTP over the node protocol for a number of reasons. HTTP is only marginally slower,
17
17
  # yet far easier to administer and work with. When using the HTTP protocol one may upgrade Elasticsearch versions without having
18
18
  # to upgrade Logstash in lock-step. For those still wishing to use the node or transport protocols please see
19
- # the https://www.elastic.co/guide/en/logstash/2.0/plugins-outputs-elasticsearch_java.html[logstash-output-elasticsearch_java] plugin.
19
+ # the <<plugins-outputs-elasticsearch_java,elasticsearch_java output plugin>>.
20
20
  #
21
21
  # You can learn more about Elasticsearch at <https://www.elastic.co/products/elasticsearch>
22
22
  #
@@ -81,8 +81,10 @@ class LogStash::Outputs::ElasticSearch < LogStash::Outputs::Base
81
81
  # the root path for the Elasticsearch HTTP API lives.
82
82
  config :path, :validate => :string, :default => "/"
83
83
 
84
- # Enable SSL/TLS secured communication to Elasticsearch cluster
85
- config :ssl, :validate => :boolean, :default => false
84
+ # Enable SSL/TLS secured communication to Elasticsearch cluster. Leaving this unspecified will use whatever scheme
85
+ # is specified in the URLs listed in 'hosts'. If no explicit protocol is specified plain HTTP will be used.
86
+ # If SSL is explicitly disabled here the plugin will refuse to start if an HTTPS URL is given in 'hosts'
87
+ config :ssl, :validate => :boolean
86
88
 
87
89
  # Option to validate the server's certificate. Disabling this severely compromises security.
88
90
  # For more information on disabling certificate verification please read
@@ -74,6 +74,9 @@ module LogStash; module Outputs; class ElasticSearch
74
74
  # Remember the `http` protocol uses the http://www.elastic.co/guide/en/elasticsearch/reference/current/modules-http.html#modules-http[http] address (eg. 9200, not 9300).
75
75
  # `"127.0.0.1"`
76
76
  # `["127.0.0.1:9200","127.0.0.2:9200"]`
77
+ # `["http://127.0.0.1"]`
78
+ # `["https://127.0.0.1:9200"]`
79
+ # `["https://127.0.0.1:9200/mypath"]` (If using a proxy on a subpath)
77
80
  # It is important to exclude http://www.elastic.co/guide/en/elasticsearch/reference/current/modules-node.html[dedicated master nodes] from the `hosts` list
78
81
  # to prevent LS from sending bulk requests to the master nodes. So this parameter should only reference either data or client nodes in Elasticsearch.
79
82
  mod.config :hosts, :validate => :array, :default => ["127.0.0.1"]
@@ -105,18 +105,10 @@ module LogStash; module Outputs; class ElasticSearch;
105
105
  client_settings = options[:client_settings] || {}
106
106
  timeout = options[:timeout] || 0
107
107
 
108
- uris = hosts.map do |host|
109
- proto = client_settings[:ssl] ? "https" : "http"
110
- if host =~ /:\d+\z/
111
- "#{proto}://#{host}#{client_settings[:path]}"
112
- else
113
- # Use default port of 9200 if none provided with host.
114
- "#{proto}://#{host}:9200#{client_settings[:path]}"
115
- end
116
- end
108
+ urls = hosts.map {|host| host_to_url(host, client_settings[:ssl], client_settings[:path])}
117
109
 
118
110
  @client_options = {
119
- :hosts => uris,
111
+ :hosts => urls,
120
112
  :ssl => client_settings[:ssl],
121
113
  :transport_options => {
122
114
  :socket_timeout => timeout,
@@ -136,6 +128,61 @@ module LogStash; module Outputs; class ElasticSearch;
136
128
  Elasticsearch::Client.new(client_options)
137
129
  end
138
130
 
131
+ HOSTNAME_PORT_REGEX=/\A(?<hostname>([A-Za-z0-9\.\-]+)|\[[0-9A-Fa-f\:]+\])(:(?<port>\d+))?\Z/
132
+ URL_REGEX=/\A#{URI::regexp(['http', 'https'])}\z/
133
+ # Parse a configuration host to a normalized URL
134
+ def host_to_url(host, ssl=nil, path=nil)
135
+ explicit_scheme = case ssl
136
+ when true
137
+ "https"
138
+ when false
139
+ "http"
140
+ else
141
+ nil
142
+ end
143
+
144
+ # Ensure path starts with a /
145
+ if path && path[0] != '/'
146
+ path = "/#{path}"
147
+ end
148
+
149
+ url = nil
150
+ if host =~ URL_REGEX
151
+ url = URI.parse(host)
152
+
153
+ # Please note that the ssl == nil case is different! If you didn't make an explicit
154
+ # choice we don't complain!
155
+ if url.scheme == "http" && ssl == true
156
+ raise LogStash::ConfigurationError, "You specified a plain 'http' URL '#{host}' but set 'ssl' to true! Aborting!"
157
+ elsif url.scheme == "https" && ssl == false
158
+ raise LogStash::ConfigurationError, "You have explicitly disabled SSL but passed in an https URL '#{host}'! Aborting!"
159
+ end
160
+
161
+ url.scheme = explicit_scheme if explicit_scheme
162
+ elsif (match_results = HOSTNAME_PORT_REGEX.match(host))
163
+ hostname = match_results["hostname"]
164
+ port = match_results["port"] || 9200
165
+ url = URI.parse("#{explicit_scheme || 'http'}://#{hostname}:#{port}")
166
+ else
167
+ raise LogStash::ConfigurationError, "Host '#{host}' was specified, but is not valid! Use either a full URL or a hostname:port string!"
168
+ end
169
+
170
+ if path && url.path && url.path != "/" && url.path != ''
171
+ raise LogStash::ConfigurationError, "A path '#{url.path}' has been explicitly specified in the url '#{url}', but you also specified a path of '#{path}'. This is probably a mistake, please remove one setting."
172
+ end
173
+
174
+ if path
175
+ url.path = path # The URI library cannot stringify if it holds a nil
176
+ end
177
+
178
+ if url.password || url.user
179
+ raise LogStash::ConfigurationError, "We do not support setting the user password in the URL directly as " +
180
+ "this may be logged to disk thus leaking credentials. Use the 'user' and 'password' options respectively"
181
+ end
182
+
183
+ url.to_s
184
+ end
185
+
139
186
  def template_exists?(name)
140
187
  @client.indices.get_template(:name => name)
141
188
  return true
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
 
3
3
  s.name = 'logstash-output-elasticsearch'
4
- s.version = '2.4.2'
4
+ s.version = '2.5.0'
5
5
  s.licenses = ['apache-2.0']
6
6
  s.summary = "Logstash Output to Elasticsearch"
7
7
  s.description = "Output events to elasticsearch"
@@ -0,0 +1,129 @@
1
+ require "logstash/devutils/rspec/spec_helper"
2
+ require "logstash/outputs/elasticsearch/http_client"
3
+ require "java"
4
+
5
+ describe LogStash::Outputs::ElasticSearch::HttpClient do
6
+ let(:base_options) { {:hosts => ["127.0.0.1"], :logger => Cabin::Channel.get }}
7
+
8
+ describe "Host/URL Parsing" do
9
+ subject { described_class.new(base_options) }
10
+
11
+ let(:true_hostname) { "my-dash.hostname" }
12
+ let(:ipv6_hostname) { "[::1]" }
13
+ let(:ipv4_hostname) { "127.0.0.1" }
14
+ let(:port) { 9202 }
15
+ let(:hostname_port) { "#{hostname}:#{port}"}
16
+ let(:http_hostname_port) { "http://#{hostname_port}"}
17
+ let(:https_hostname_port) { "https://#{hostname_port}"}
18
+ let(:http_hostname_port_path) { "http://#{hostname_port}/path"}
19
+
20
+ shared_examples("proper host handling") do
21
+ it "should properly transform a host:port string to a URL" do
22
+ expect(subject.send(:host_to_url, hostname_port)).to eql(http_hostname_port)
23
+ end
24
+
25
+ it "should raise an error when a partial URL is an invalid format" do
26
+ expect {
27
+ subject.send(:host_to_url, "#{hostname_port}/")
28
+ }.to raise_error(LogStash::ConfigurationError)
29
+ end
30
+
31
+ it "should not raise an error with a / for a path" do
32
+ expect(subject.send(:host_to_url, "#{http_hostname_port}/")).to eql("#{http_hostname_port}/")
33
+ end
34
+
35
+ it "should parse full URLs correctly" do
36
+ expect(subject.send(:host_to_url, http_hostname_port)).to eql(http_hostname_port)
37
+ end
38
+
39
+ it "should reject full URLs with usernames and passwords" do
40
+ expect {
41
+ subject.send(:host_to_url, "http://user:password@host.domain")
42
+ }.to raise_error(LogStash::ConfigurationError)
43
+ end
44
+
45
+ describe "ssl" do
46
+ it "should refuse to handle an http url when ssl is true" do
47
+ expect {
48
+ subject.send(:host_to_url, http_hostname_port, true)
49
+ }.to raise_error(LogStash::ConfigurationError)
50
+ end
51
+
52
+ it "should refuse to handle an https url when ssl is false" do
53
+ expect {
54
+ subject.send(:host_to_url, https_hostname_port, false)
55
+ }.to raise_error(LogStash::ConfigurationError)
56
+ end
57
+
58
+ it "should handle an ssl url correctly when SSL is nil" do
59
+ expect(subject.send(:host_to_url, https_hostname_port, nil)).to eql(https_hostname_port)
60
+ end
61
+ end
62
+
63
+ describe "path" do
64
+ it "should allow paths in a url" do
65
+ expect(subject.send(:host_to_url, http_hostname_port_path, nil)).to eql(http_hostname_port_path)
66
+ end
67
+
68
+ it "should not allow paths in two places" do
69
+ expect {
70
+ subject.send(:host_to_url, http_hostname_port_path, false, "/otherpath")
71
+ }.to raise_error(LogStash::ConfigurationError)
72
+ end
73
+
74
+ it "should automatically insert a / in front of path overlays if needed" do
75
+ expect(subject.send(:host_to_url, http_hostname_port, false, "otherpath")).to eql(http_hostname_port + "/otherpath")
76
+ end
77
+ end
78
+ end
79
+
80
+ describe "an regular hostname" do
81
+ let(:hostname) { true_hostname }
82
+ include_examples("proper host handling")
83
+ end
84
+
85
+ describe "an ipv4 host" do
86
+ let(:hostname) { ipv4_hostname }
87
+ include_examples("proper host handling")
88
+ end
89
+
90
+ describe "an ipv6 host" do
91
+ let(:hostname) { ipv6_hostname }
92
+ include_examples("proper host handling")
93
+ end
94
+ end
95
+
96
+ describe "sniffing" do
97
+ let(:client) { LogStash::Outputs::ElasticSearch::HttpClient.new(base_options.merge(client_opts)) }
98
+ let(:transport) { client.client.transport }
99
+
100
+ before do
101
+ allow(transport).to receive(:reload_connections!)
102
+ end
103
+
104
+ context "with sniffing enabled" do
105
+ let(:client_opts) { {:sniffing => true, :sniffing_delay => 1 } }
106
+
107
+ after do
108
+ client.stop_sniffing!
109
+ end
110
+
111
+ it "should start the sniffer" do
112
+ expect(client.sniffer_thread).to be_a(Thread)
113
+ end
114
+
115
+ it "should periodically sniff the client" do
116
+ sleep 2
117
+ expect(transport).to have_received(:reload_connections!).at_least(:once)
118
+ end
119
+ end
120
+
121
+ context "with sniffing disabled" do
122
+ let(:client_opts) { {:sniffing => false} }
123
+
124
+ it "should not start the sniffer" do
125
+ expect(client.sniffer_thread).to be_nil
126
+ end
127
+ end
128
+ end
129
+ end
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: 2.4.2
4
+ version: 2.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: 2016-02-02 00:00:00.000000000 Z
11
+ date: 2016-02-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -223,7 +223,7 @@ files:
223
223
  - spec/integration/outputs/update_spec.rb
224
224
  - spec/unit/buffer_spec.rb
225
225
  - spec/unit/http_client_builder_spec.rb
226
- - spec/unit/outputs/elasticsearch/protocol_spec.rb
226
+ - spec/unit/outputs/elasticsearch/http_client_spec.rb
227
227
  - spec/unit/outputs/elasticsearch_proxy_spec.rb
228
228
  - spec/unit/outputs/elasticsearch_spec.rb
229
229
  - spec/unit/outputs/elasticsearch_ssl_spec.rb
@@ -268,7 +268,7 @@ test_files:
268
268
  - spec/integration/outputs/update_spec.rb
269
269
  - spec/unit/buffer_spec.rb
270
270
  - spec/unit/http_client_builder_spec.rb
271
- - spec/unit/outputs/elasticsearch/protocol_spec.rb
271
+ - spec/unit/outputs/elasticsearch/http_client_spec.rb
272
272
  - spec/unit/outputs/elasticsearch_proxy_spec.rb
273
273
  - spec/unit/outputs/elasticsearch_spec.rb
274
274
  - spec/unit/outputs/elasticsearch_ssl_spec.rb
@@ -1,41 +0,0 @@
1
- require "logstash/devutils/rspec/spec_helper"
2
- require "logstash/outputs/elasticsearch/http_client"
3
- require "java"
4
-
5
- describe LogStash::Outputs::ElasticSearch::HttpClient do
6
- describe "sniffing" do
7
- let(:base_options) { {:hosts => ["127.0.0.1"], :logger => Cabin::Channel.get }}
8
- let(:client) { LogStash::Outputs::ElasticSearch::HttpClient.new(base_options.merge(client_opts)) }
9
- let(:transport) { client.client.transport }
10
-
11
- before do
12
- allow(transport).to receive(:reload_connections!)
13
- end
14
-
15
- context "with sniffing enabled" do
16
- let(:client_opts) { {:sniffing => true, :sniffing_delay => 1 } }
17
-
18
- after do
19
- client.stop_sniffing!
20
- end
21
-
22
- it "should start the sniffer" do
23
- expect(client.sniffer_thread).to be_a(Thread)
24
- end
25
-
26
- it "should periodically sniff the client" do
27
- sleep 2
28
- expect(transport).to have_received(:reload_connections!).at_least(:once)
29
- end
30
- end
31
-
32
- context "with sniffing disabled" do
33
- let(:client_opts) { {:sniffing => false} }
34
-
35
- it "should not start the sniffer" do
36
- expect(client.sniffer_thread).to be_nil
37
- end
38
- end
39
-
40
- end
41
- end