logstash-input-beats 4.0.2-java → 4.0.3-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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)