logstash-input-beats 4.0.2-java → 4.0.3-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: 531fc3f9d3ae313fc42ee5624caeb51679696127
4
- data.tar.gz: 3ca0d6794c140249ebdb912b0a3955f73a1740da
3
+ metadata.gz: d406faf577912c1b8e53353eb01a297b91ca4de5
4
+ data.tar.gz: ac879f92b4b6e6699ed9c56fd40db3248b6810ba
5
5
  SHA512:
6
- metadata.gz: f0d7f04262228d660c39631ca10896ea038437c2be039b2aea933c5c3310391bd583f534d5783c9906389eec13e273fe6978ee0871280e5906083f6745a7e021
7
- data.tar.gz: 67020e94ebb1a72d8f68fed727950ba980be9ebb9cd19b712632998615445adcd96c556671b8b6a046c119187ae12baf4c461ae501194ab55f544402369d2f7d
6
+ metadata.gz: 8cb70e0661a794b5be172bf87c7b5d186b0107d3e37cee6590592610ce00c06b2d05c494febbf9afb48b6a77a599199919f9c5f89063ad9dc766bc1419c4cd96
7
+ data.tar.gz: ba72af919b0d49bb3fb392e22a8d2475a0a11c92c2d321881c9f07cce7ffa5e4f25bc9ce74567d7d51c7e96dae196bd71d2430beb1219bb0ba309f029db05fcc
data/CHANGELOG.md CHANGED
@@ -1,14 +1,29 @@
1
+ ## 4.0.3
2
+ - Include remote ip_address in metadata. #180
3
+ - Require Java 8 #221
4
+ - Fix ability to set SSL protocols #228
5
+
1
6
  ## 4.0.2
2
- - Relax version of concurrent-ruby to `~> 1.0`
7
+ - Relax version of concurrent-ruby to `~> 1.0` #216
3
8
 
4
9
  ## 4.0.1
5
- - Breaking change: Logstash will no longer start when multiline codec is used with the Beats input plugin
10
+ - Breaking change: Logstash will no longer start when multiline codec is used with the Beats input plugin #201
6
11
 
7
12
  ## 4.0.0
8
- - Verion yanked from RubyGems for packaging issues
13
+ - Version yanked from RubyGems for packaging issues
14
+
15
+ ## 3.1.19
16
+ - Fix ability to set SSL protocols #228
17
+
18
+ ## 3.1.18
19
+ - Relax version of concurrent-ruby to ~> 1.0 #216
20
+
21
+ ## 3.1.17
22
+ - Docs: Add note indicating that the multiline codec should not be used with the Beats input plugin
23
+ - Deprecate warning for multiline codec with the Beats input plugin
9
24
 
10
25
  ## 3.1.16
11
- - Docs: Add note indicating that the multiline codec should not be used with the Beats input plugin
26
+ - Version yanked from RubyGems for packaging issues
12
27
 
13
28
  ## 3.1.15
14
29
  - DEBUG: Add information about the remote when an exception is catched #192
data/VERSION CHANGED
@@ -1 +1 @@
1
- 4.0.2
1
+ 4.0.3
data/docs/index.asciidoc CHANGED
@@ -14,7 +14,7 @@ END - GENERATED VARIABLES, DO NOT EDIT!
14
14
 
15
15
  [id="plugins-{type}-{plugin}"]
16
16
 
17
- === Beats
17
+ === Beats input plugin
18
18
 
19
19
  include::{include_path}/plugin_header.asciidoc[]
20
20
 
@@ -9,4 +9,4 @@ require_jar('com.fasterxml.jackson.core', 'jackson-annotations', '2.7.5')
9
9
  require_jar('com.fasterxml.jackson.core', 'jackson-databind', '2.7.5')
10
10
  require_jar('com.fasterxml.jackson.module', 'jackson-module-afterburner', '2.7.5')
11
11
  require_jar('log4j', 'log4j', '1.2.17')
12
- require_jar('org.logstash.beats', 'logstash-input-beats', '4.0.2')
12
+ require_jar('org.logstash.beats', 'logstash-input-beats', '4.0.3')
@@ -39,8 +39,7 @@ require_relative "beats/patch"
39
39
  # IMPORTANT: If you are shipping events that span multiple lines, you need to
40
40
  # use the configuration options available in Filebeat to handle multiline events
41
41
  # before sending the event data to Logstash. You cannot use the
42
- # <<plugins-codecs-multiline>> codec to handle multiline events. Doing so may
43
- # result in the mixing of streams and corrupted event data.
42
+ # <<plugins-codecs-multiline>> codec to handle multiline events.
44
43
  #
45
44
  class LogStash::Inputs::Beats < LogStash::Inputs::Base
46
45
  require "logstash/inputs/beats/codec_callback_listener"
@@ -29,6 +29,12 @@ module LogStash module Inputs class Beats
29
29
  def onNewMessage(ctx, message)
30
30
  hash = message.getData()
31
31
 
32
+ begin
33
+ hash.get("@metadata").put("ip_address", ctx.channel().remoteAddress().getAddress().getHostAddress())
34
+ rescue #should never happen, but don't allow an error here to stop beats input
35
+ input.logger.warn("Could not retrieve remote IP address for beats input.")
36
+ end
37
+
32
38
  target_field = extract_target_field(hash)
33
39
 
34
40
  if target_field.nil?
data/lib/tasks/test.rake CHANGED
@@ -2,10 +2,11 @@
2
2
  OS_PLATFORM = RbConfig::CONFIG["host_os"]
3
3
  VENDOR_PATH = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "vendor"))
4
4
 
5
+ #TODO: Figure out better means to keep this version in sync
5
6
  if OS_PLATFORM == "linux"
6
- FILEBEAT_URL = "https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-5.0.0-linux-x86_64.tar.gz"
7
+ FILEBEAT_URL = "https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-6.0.0-alpha2-linux-x86_64.tar.gz"
7
8
  elsif OS_PLATFORM == "darwin"
8
- FILEBEAT_URL = "https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-5.0.0-darwin-x86_64.tar.gz"
9
+ FILEBEAT_URL = "https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-6.0.0-alpha2-darwin-x86_64.tar.gz"
9
10
  end
10
11
 
11
12
  LSF_URL = "https://download.elastic.co/logstash-forwarder/binaries/logstash-forwarder_#{OS_PLATFORM}_amd64"
@@ -6,7 +6,10 @@ require "logstash/inputs/beats/message_listener"
6
6
  require "logstash/instrument/namespaced_null_metric"
7
7
  require "thread"
8
8
 
9
+ java_import java.util.HashMap
10
+
9
11
  class MockMessage
12
+
10
13
  def initialize(identity_stream, data = {})
11
14
  @identity_stream = identity_stream
12
15
  @data = data
@@ -21,6 +24,22 @@ class MockMessage
21
24
  end
22
25
  end
23
26
 
27
+ # General purpose single method mock class. Will keep generating mocks until requested method name (no args) is found.
28
+ class OngoingMethodMock
29
+ def initialize(method_name, return_value)
30
+ @method_name = method_name
31
+ @return_value = return_value
32
+ end
33
+
34
+ def method_missing(method)
35
+ if(method.to_s.eql? @method_name)
36
+ return @return_value
37
+ else
38
+ return OngoingMethodMock.new(@method_name, @return_value)
39
+ end
40
+ end
41
+ end
42
+
24
43
  class DummyCodec < LogStash::Codecs::Base
25
44
  DUMMY_EVENT = LogStash::Event.new
26
45
 
@@ -98,7 +117,14 @@ describe LogStash::Inputs::Beats::MessageListener do
98
117
  end
99
118
 
100
119
  context "when the message is from any libbeat" do
101
- let(:message) { MockMessage.new("abc", { "metric" => 1, "name" => "super-stats"} )}
120
+ #Requires data modeled as Java, not Ruby since the actual code pulls from Java backed (Netty) object
121
+ data = java.util.HashMap.new
122
+ data.put("@metadata", java.util.HashMap.new)
123
+ data.put("metric", 1)
124
+ data.put("name", "super-stats")
125
+
126
+ let(:message) { MockMessage.new("abc", data)}
127
+ let(:ctx) {OngoingMethodMock.new("getHostAddress", "10.0.0.1")}
102
128
 
103
129
  it "extract the event" do
104
130
  subject.onNewMessage(ctx, message)
@@ -106,8 +132,10 @@ describe LogStash::Inputs::Beats::MessageListener do
106
132
  expect(event.get("message")).to be_nil
107
133
  expect(event.get("metric")).to eq(1)
108
134
  expect(event.get("name")).to eq("super-stats")
135
+ expect(event.get("[@metadata][ip_address]")).to eq("10.0.0.1")
109
136
  end
110
137
  end
138
+
111
139
  end
112
140
 
113
141
  context "onException" do
@@ -52,6 +52,7 @@ describe "Filebeat", :integration => true do
52
52
  before :each do
53
53
  FileUtils.rm_rf(File.join(File.dirname(__FILE__), "..", "..", "vendor", "filebeat", "data"))
54
54
  start_client
55
+ raise 'Filebeat did not start in alloted time' unless is_alive
55
56
  sleep(20) # give some time to FB to send something
56
57
  end
57
58
 
@@ -76,7 +77,7 @@ describe "Filebeat", :integration => true do
76
77
  end
77
78
 
78
79
  ############################################################
79
- # Actuals tests
80
+ # Actuals tests
80
81
  context "Plain TCP" do
81
82
  include_examples "send events"
82
83
  end
@@ -190,6 +191,9 @@ describe "Filebeat", :integration => true do
190
191
  context "CA root" do
191
192
  include_context "Root CA"
192
193
 
194
+ let_tmp_file(:certificate_key_file) { convert_to_pkcs8(certificate_data.last) }
195
+ let_tmp_file(:certificate_file) { certificate_data.first }
196
+
193
197
  context "directly signed client certificate" do
194
198
  let(:certificate_authorities) { [root_ca_certificate_file] }
195
199
  let(:certificate_data) { Flores::PKI.create_client_certicate("CN=localhost", root_ca_certificate, root_ca_key) }
@@ -202,7 +206,7 @@ describe "Filebeat", :integration => true do
202
206
 
203
207
  let(:certificate_data) { Flores::PKI.create_client_certicate("CN=localhost", intermediate_ca_certificate, intermediate_ca_key) }
204
208
  let(:certificate_authorities) { [certificate_authorities_chain] }
205
-
209
+
206
210
  include_examples "send events"
207
211
  end
208
212
  end
@@ -224,7 +228,7 @@ describe "Filebeat", :integration => true do
224
228
  end
225
229
 
226
230
  let(:input_config) do
227
- super.merge({
231
+ super.merge({
228
232
  "ssl" => true,
229
233
  "ssl_certificate_authorities" => certificate_authorities,
230
234
  "ssl_certificate" => server_certificate_file,
@@ -249,6 +253,8 @@ describe "Filebeat", :integration => true do
249
253
 
250
254
  let_tmp_file(:server_certificate_file) { server_certificate_data.first }
251
255
  let_tmp_file(:server_certificate_key_file) { convert_to_pkcs8(server_certificate_data.last) }
256
+ let_tmp_file(:certificate_file) { certificate_data.first }
257
+ let_tmp_file(:certificate_key_file) { convert_to_pkcs8(certificate_data.last) }
252
258
 
253
259
  context "directly signed client certificate" do
254
260
  let(:certificate_authorities) { [root_ca_certificate_file] }
@@ -262,7 +268,7 @@ describe "Filebeat", :integration => true do
262
268
  include_context "Intermediate CA"
263
269
 
264
270
  let(:certificate_data) { Flores::PKI.create_client_certicate("CN=localhost", intermediate_ca_certificate, intermediate_ca_key) }
265
- let(:server_certificate_data) { Flores::PKI.create_client_certicate("CN=localhost", intermediate_ca_certificate, intermediate_ca_key) }
271
+ let(:server_certificate_data) { Flores::PKI.create_client_certicate("CN=localhost", intermediate_ca_certificate, intermediate_ca_key) }
266
272
  let(:certificate_authorities) { [intermediate_ca_certificate_file] }
267
273
 
268
274
  include_examples "send events"
@@ -298,7 +304,7 @@ describe "Filebeat", :integration => true do
298
304
 
299
305
  let(:server_certificate_data) { Flores::PKI.create_client_certicate("CN=localhost", root_ca_certificate, root_ca_key) }
300
306
 
301
- context "client from primary CA" do
307
+ context "client from primary CA" do
302
308
  include_examples "send events"
303
309
  end
304
310
 
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
  require "childprocess"
3
3
  module ClientProcessHelpers
4
- def start_client(timeout = 1)
4
+ def start_client(timeout = 5)
5
5
  @client_out = Stud::Temporary.file
6
6
  @client_out.sync
7
7
 
@@ -11,13 +11,26 @@ module ClientProcessHelpers
11
11
  ChildProcess.posix_spawn = true
12
12
  @process.start
13
13
 
14
- sleep(0.1)
14
+ sleep_interval = 0.1
15
+ max_iterations = (timeout / sleep_interval).to_i
16
+ max_iterations.times do
17
+ sleep(sleep_interval)
18
+ if @process.alive?
19
+ break
20
+ end
21
+ end
22
+ #Note - can not raise error here if process failed to start, since some tests expects for the process to not start due to invalid configuration
23
+
15
24
  @client_out.rewind
16
25
 
17
26
  # can be used to helper debugging when a test fails
18
27
  @execution_output = @client_out.read
19
28
  end
20
29
 
30
+ def is_alive
31
+ return @process.alive?
32
+ end
33
+
21
34
  def stop_client
22
35
  begin
23
36
  @process.poll_for_exit(5)
@@ -1,49 +1,68 @@
1
1
  # encoding: utf-8
2
2
  require "flores/pki"
3
3
  require "flores/random"
4
+ require "socket"
4
5
 
5
6
  module Flores
6
7
  module Random
7
8
  DEFAULT_PORT_RANGE = 1024..65535
8
- DEFAULT_PORT_CHECK_TIMEOUT = 1
9
- DEFAULT_MAXIMUM_PORT_FIND_TRY = 15
10
-
11
9
  class << self
12
10
  def port(range = DEFAULT_PORT_RANGE)
13
- try = 0
14
- while try < DEFAULT_MAXIMUM_PORT_FIND_TRY
15
- candidate = integer(range)
16
-
17
- if port_available?(candidate)
18
- break
19
- else
20
- try += 1
21
- end
11
+ integer(range)
12
+ end
13
+ end
14
+ end
15
+
16
+ module PKI
17
+
18
+ # Monkey patched the fix for https://github.com/jordansissel/ruby-flores/issues/9
19
+ # TODO: remove this once Flores is released with fix.
20
+ CertificateSigningRequest.class_eval do
21
+ def create
22
+ validate!
23
+ extensions = OpenSSL::X509::ExtensionFactory.new
24
+ extensions.subject_certificate = certificate
25
+ extensions.issuer_certificate = self_signed? ? certificate : signing_certificate
26
+
27
+ certificate.issuer = extensions.issuer_certificate.subject
28
+ certificate.add_extension(extensions.create_extension("subjectKeyIdentifier", "hash", false))
29
+
30
+ if want_signature_ability?
31
+ # Create a CA.
32
+ certificate.add_extension(extensions.create_extension("basicConstraints", "CA:TRUE", true))
33
+ # Rough googling seems to indicate at least keyCertSign is required for CA and intermediate certs.
34
+ certificate.add_extension(extensions.create_extension("keyUsage", "keyCertSign, cRLSign, digitalSignature", true))
35
+ else
36
+ # Create a client+server certificate
37
+ #
38
+ # It feels weird to create a certificate that's valid as both server and client, but a brief inspection of major
39
+ # web properties (apple.com, google.com, yahoo.com, github.com, fastly.com, mozilla.com, amazon.com) reveals that
40
+ # major web properties have certificates with both clientAuth and serverAuth extended key usages. Further,
41
+ # these major server certificates all have digitalSignature and keyEncipherment for key usage.
42
+ #
43
+ # Here's the command I used to check this:
44
+ # echo mozilla.com apple.com github.com google.com yahoo.com fastly.com elastic.co amazon.com \
45
+ # | xargs -n1 sh -c 'openssl s_client -connect $1:443 \
46
+ # | sed -ne "/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p" \
47
+ # | openssl x509 -text -noout | sed -ne "/X509v3 extensions/,/Signature Algorithm/p" | sed -e "s/^/$1 /"' - \
48
+ # | grep -A2 'Key Usage'
49
+ certificate.add_extension(extensions.create_extension("keyUsage", "digitalSignature, keyEncipherment", true))
50
+ certificate.add_extension(extensions.create_extension("extendedKeyUsage", "clientAuth, serverAuth", false))
22
51
  end
23
-
24
- raise "Flores.random_port: Cannot find an available port, tried #{DEFAULT_MAXIMUM_PORT_FIND_TRY} times, range was: #{range}" if try == DEFAULT_MAXIMUM_PORT_FIND_TRY
25
52
 
26
- candidate
27
- end
28
-
29
- def port_available?(port)
30
- begin
31
- server = TCPServer.new(port)
32
- available = true
33
- rescue # Assume that any errors can do this
34
- available = false
35
- ensure
36
- server.close if server
53
+ if @subject_alternates
54
+ certificate.add_extension(extensions.create_extension("subjectAltName", @subject_alternates.join(",")))
37
55
  end
38
56
 
39
- return available
57
+ certificate.serial = OpenSSL::BN.new(serial)
58
+ certificate.sign(signing_key, digest_method)
59
+ certificate
40
60
  end
41
61
  end
42
- end
43
62
 
44
- module PKI
63
+
45
64
  DEFAULT_CERTIFICATE_OPTIONS = {
46
- :duration => Flores::Random.number(100..2000),
65
+ :duration => 86400, #one day
47
66
  :key_size => GENERATE_DEFAULT_KEY_SIZE,
48
67
  :exponent => GENERATE_DEFAULT_EXPONENT,
49
68
  :want_signature_ability => false
@@ -78,5 +97,9 @@ module Flores
78
97
 
79
98
  [csr.create, client_key]
80
99
  end
100
+
101
+
102
+
81
103
  end
82
104
  end
105
+
@@ -3,7 +3,7 @@ require "flores/random"
3
3
 
4
4
  shared_examples "send events" do
5
5
  it "successfully send the events" do
6
- try(50) { expect(queue.size).to eq(number_of_events), "Expected: #{number_of_events} got: #{queue.size}, execution output:\n #{@execution_output}" }
6
+ try(25) { expect(queue.size).to eq(number_of_events), "Expected: #{number_of_events} got: #{queue.size}, execution output:\n #{@execution_output}" }
7
7
  expect(queue.collect { |e| e.get("message") }).to eq(events)
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-input-beats
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.2
4
+ version: 4.0.3
5
5
  platform: java
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-06-07 00:00:00.000000000 Z
11
+ date: 2017-06-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -264,7 +264,7 @@ files:
264
264
  - vendor/jar-dependencies/io/netty/netty-tcnative-boringssl-static/1.1.33.Fork23/netty-tcnative-boringssl-static-1.1.33.Fork23.jar
265
265
  - vendor/jar-dependencies/log4j/log4j/1.2.17/log4j-1.2.17.jar
266
266
  - vendor/jar-dependencies/org/javassist/javassist/3.20.0-GA/javassist-3.20.0-GA.jar
267
- - vendor/jar-dependencies/org/logstash/beats/logstash-input-beats/4.0.2/logstash-input-beats-4.0.2.jar
267
+ - vendor/jar-dependencies/org/logstash/beats/logstash-input-beats/4.0.3/logstash-input-beats-4.0.3.jar
268
268
  homepage: http://www.elastic.co/guide/en/logstash/current/index.html
269
269
  licenses:
270
270
  - Apache License (2.0)