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 +4 -4
- data/CHANGELOG.md +19 -4
- data/VERSION +1 -1
- data/docs/index.asciidoc +1 -1
- data/lib/logstash-input-beats_jars.rb +1 -1
- data/lib/logstash/inputs/beats.rb +1 -2
- data/lib/logstash/inputs/beats/message_listener.rb +6 -0
- data/lib/tasks/test.rake +3 -2
- data/spec/inputs/beats/message_listener_spec.rb +29 -1
- data/spec/integration/filebeat_spec.rb +11 -5
- data/spec/support/client_process_helpers.rb +15 -2
- data/spec/support/flores_extensions.rb +52 -29
- data/spec/support/integration_shared_context.rb +1 -1
- data/vendor/jar-dependencies/org/logstash/beats/logstash-input-beats/4.0.3/logstash-input-beats-4.0.3.jar +0 -0
- metadata +3 -3
- data/vendor/jar-dependencies/org/logstash/beats/logstash-input-beats/4.0.2/logstash-input-beats-4.0.2.jar +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d406faf577912c1b8e53353eb01a297b91ca4de5
|
4
|
+
data.tar.gz: ac879f92b4b6e6699ed9c56fd40db3248b6810ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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
|
-
-
|
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
|
-
-
|
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.
|
1
|
+
4.0.3
|
data/docs/index.asciidoc
CHANGED
@@ -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.
|
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.
|
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-
|
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-
|
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
|
-
|
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 =
|
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
|
-
|
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
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
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
|
-
|
27
|
-
|
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
|
-
|
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
|
-
|
63
|
+
|
45
64
|
DEFAULT_CERTIFICATE_OPTIONS = {
|
46
|
-
:duration =>
|
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(
|
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
|
Binary file
|
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.
|
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-
|
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.
|
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)
|