logstash-input-tcp 2.0.5 → 3.0.0
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 +4 -4
- data/CHANGELOG.md +10 -0
- data/lib/logstash/inputs/tcp.rb +41 -15
- data/logstash-input-tcp.gemspec +4 -1
- data/spec/inputs/tcp_spec.rb +151 -3
- data/spec/spec_helper.rb +69 -0
- metadata +32 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bc8a144097d1b6d3ee89c67da0a9598c20816dc0
|
4
|
+
data.tar.gz: db3e1d7399ee28bcdbad61d343c589249287ad3d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d8b9f22e646a94b0624d961075589d48899595e9aaedb4111fcc1cf6118a9173366f3caf6f7b0315c8048d0a6d850ee6da0319eea9f413413d5a6d2511d09c12
|
7
|
+
data.tar.gz: a5d0c419104ca62126ad38c4e3a0a83a81083df5febe5184a4c7edff44893a9b4141589830a99bbfaff365652cbcb43f8cdeb11e88d3fe6b341e36b32911a175
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
## 3.0.0
|
2
|
+
- Deprecate ssl_cacert as it's confusing, does it job but when willing to add a chain of certificated the name and behaviour is a bit confusing.
|
3
|
+
- Add ssl_extra_chain_certs that allows you to specify a list of certificates path that will be added to the CAStore.
|
4
|
+
- Make ssl_verify=true as a default value, if using ssl and performing validation is not reasonable as security might be compromised.
|
5
|
+
- Add tests to verify behaviour under different SSL connection circumstances.
|
6
|
+
- Fixes #3 and #9.
|
7
|
+
|
8
|
+
## 2.1.0
|
9
|
+
- Added the receiving port in the event payload, fixes #4
|
10
|
+
|
1
11
|
## 2.0.5
|
2
12
|
- Fixed malformed SSL crashing Logstash, see https://github.com/logstash-plugins/logstash-input-tcp/pull/25
|
3
13
|
|
data/lib/logstash/inputs/tcp.rb
CHANGED
@@ -35,10 +35,10 @@ class LogStash::Inputs::Tcp < LogStash::Inputs::Base
|
|
35
35
|
|
36
36
|
# Verify the identity of the other end of the SSL connection against the CA.
|
37
37
|
# For input, sets the field `sslsubject` to that of the client certificate.
|
38
|
-
config :ssl_verify, :validate => :boolean, :default =>
|
38
|
+
config :ssl_verify, :validate => :boolean, :default => true
|
39
39
|
|
40
40
|
# The SSL CA certificate, chainfile or CA path. The system CA path is automatically included.
|
41
|
-
config :ssl_cacert, :validate => :path
|
41
|
+
config :ssl_cacert, :validate => :path, :deprecated => "This setting is deprecated in favor of extra_chain_cert as it sets a more clear expectation to add more X509 certificates to the store"
|
42
42
|
|
43
43
|
# SSL certificate path
|
44
44
|
config :ssl_cert, :validate => :path
|
@@ -49,6 +49,10 @@ class LogStash::Inputs::Tcp < LogStash::Inputs::Base
|
|
49
49
|
# SSL key passphrase
|
50
50
|
config :ssl_key_passphrase, :validate => :password, :default => nil
|
51
51
|
|
52
|
+
# An Array of extra X509 certificates to be added to the certificate chain.
|
53
|
+
# Useful when the CA chain is not necessary in the system store.
|
54
|
+
config :ssl_extra_chain_certs, :validate => :array, :default => []
|
55
|
+
|
52
56
|
def initialize(*args)
|
53
57
|
super(*args)
|
54
58
|
|
@@ -126,7 +130,7 @@ class LogStash::Inputs::Tcp < LogStash::Inputs::Base
|
|
126
130
|
def run_client(output_queue)
|
127
131
|
while !stop?
|
128
132
|
self.client_socket = new_client_socket
|
129
|
-
handle_socket(client_socket, client_socket.peeraddr[3], output_queue, @codec.clone)
|
133
|
+
handle_socket(client_socket, client_socket.peeraddr[3], client_socket.peeraddr[1], output_queue, @codec.clone)
|
130
134
|
end
|
131
135
|
ensure
|
132
136
|
# catch all rescue nil on close to discard any close errors or invalid socket
|
@@ -137,17 +141,18 @@ class LogStash::Inputs::Tcp < LogStash::Inputs::Base
|
|
137
141
|
Thread.new(output_queue, socket) do |q, s|
|
138
142
|
begin
|
139
143
|
@logger.debug? && @logger.debug("Accepted connection", :client => s.peer, :server => "#{@host}:#{@port}")
|
140
|
-
handle_socket(s, s.peeraddr[3], q, @codec.clone)
|
144
|
+
handle_socket(s, s.peeraddr[3], s.peeraddr[1], q, @codec.clone)
|
141
145
|
ensure
|
142
146
|
delete_connection_socket(s)
|
143
147
|
end
|
144
148
|
end
|
145
149
|
end
|
146
150
|
|
147
|
-
def handle_socket(socket, client_address, output_queue, codec)
|
151
|
+
def handle_socket(socket, client_address, client_port, output_queue, codec)
|
148
152
|
while !stop?
|
149
153
|
codec.decode(read(socket)) do |event|
|
150
154
|
event["host"] ||= client_address
|
155
|
+
event["port"] ||= client_port
|
151
156
|
event["sslsubject"] ||= socket.peer_cert.subject if @ssl_enable && @ssl_verify
|
152
157
|
decorate(event)
|
153
158
|
output_queue << event
|
@@ -170,12 +175,28 @@ class LogStash::Inputs::Tcp < LogStash::Inputs::Base
|
|
170
175
|
|
171
176
|
codec.respond_to?(:flush) && codec.flush do |event|
|
172
177
|
event["host"] ||= client_address
|
178
|
+
event["port"] ||= client_port
|
173
179
|
event["sslsubject"] ||= socket.peer_cert.subject if @ssl_enable && @ssl_verify
|
174
180
|
decorate(event)
|
175
181
|
output_queue << event
|
176
182
|
end
|
177
183
|
end
|
178
184
|
|
185
|
+
private
|
186
|
+
def client_thread(output_queue, socket)
|
187
|
+
Thread.new(output_queue, socket) do |q, s|
|
188
|
+
begin
|
189
|
+
@logger.debug? && @logger.debug("Accepted connection", :client => s.peer, :server => "#{@host}:#{@port}")
|
190
|
+
handle_socket(s, s.peeraddr[3], s.peeraddr[1], q, @codec.clone)
|
191
|
+
rescue Interrupted
|
192
|
+
s.close rescue nil
|
193
|
+
ensure
|
194
|
+
@client_threads_lock.synchronize{@client_threads.delete(Thread.current)}
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
private
|
179
200
|
def server?
|
180
201
|
@mode == "server"
|
181
202
|
end
|
@@ -192,15 +213,7 @@ class LogStash::Inputs::Tcp < LogStash::Inputs::Base
|
|
192
213
|
@ssl_context.cert = OpenSSL::X509::Certificate.new(File.read(@ssl_cert))
|
193
214
|
@ssl_context.key = OpenSSL::PKey::RSA.new(File.read(@ssl_key),@ssl_key_passphrase)
|
194
215
|
if @ssl_verify
|
195
|
-
@cert_store
|
196
|
-
# Load the system default certificate path to the store
|
197
|
-
@cert_store.set_default_paths
|
198
|
-
if File.directory?(@ssl_cacert)
|
199
|
-
@cert_store.add_path(@ssl_cacert)
|
200
|
-
else
|
201
|
-
@cert_store.add_file(@ssl_cacert)
|
202
|
-
end
|
203
|
-
@ssl_context.cert_store = @cert_store
|
216
|
+
@ssl_context.cert_store = load_cert_store
|
204
217
|
@ssl_context.verify_mode = OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
|
205
218
|
end
|
206
219
|
rescue => e
|
@@ -211,9 +224,22 @@ class LogStash::Inputs::Tcp < LogStash::Inputs::Base
|
|
211
224
|
@ssl_context
|
212
225
|
end
|
213
226
|
|
227
|
+
def load_cert_store
|
228
|
+
cert_store = OpenSSL::X509::Store.new
|
229
|
+
cert_store.set_default_paths
|
230
|
+
if File.directory?(@ssl_cacert)
|
231
|
+
cert_store.add_path(@ssl_cacert)
|
232
|
+
else
|
233
|
+
cert_store.add_file(@ssl_cacert)
|
234
|
+
end if @ssl_cacert
|
235
|
+
@ssl_extra_chain_certs.each do |cert|
|
236
|
+
cert_store.add_file(cert)
|
237
|
+
end
|
238
|
+
cert_store
|
239
|
+
end
|
240
|
+
|
214
241
|
def new_server_socket
|
215
242
|
@logger.info("Starting tcp input listener", :address => "#{@host}:#{@port}")
|
216
|
-
|
217
243
|
begin
|
218
244
|
socket = TCPServer.new(@host, @port)
|
219
245
|
rescue Errno::EADDRINUSE
|
data/logstash-input-tcp.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
|
3
3
|
s.name = 'logstash-input-tcp'
|
4
|
-
s.version = '
|
4
|
+
s.version = '3.0.0'
|
5
5
|
s.licenses = ['Apache License (2.0)']
|
6
6
|
s.summary = "Read events over a TCP socket."
|
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/plugin install gemname. This gem is not a stand-alone program"
|
@@ -26,6 +26,9 @@ Gem::Specification.new do |s|
|
|
26
26
|
s.add_runtime_dependency 'logstash-codec-line'
|
27
27
|
s.add_runtime_dependency 'logstash-codec-json'
|
28
28
|
s.add_runtime_dependency 'logstash-codec-json_lines'
|
29
|
+
|
29
30
|
s.add_development_dependency 'logstash-devutils'
|
31
|
+
s.add_development_dependency 'flores', '~> 0.0.6'
|
32
|
+
s.add_development_dependency 'stud', '~> 0.0.22'
|
30
33
|
end
|
31
34
|
|
data/spec/inputs/tcp_spec.rb
CHANGED
@@ -4,7 +4,10 @@ require "socket"
|
|
4
4
|
require "timeout"
|
5
5
|
require "logstash/json"
|
6
6
|
require "logstash/inputs/tcp"
|
7
|
-
require
|
7
|
+
require "stud/try"
|
8
|
+
require "flores/pki"
|
9
|
+
require "openssl"
|
10
|
+
|
8
11
|
require_relative "../spec_helper"
|
9
12
|
|
10
13
|
describe LogStash::Inputs::Tcp do
|
@@ -251,7 +254,6 @@ describe LogStash::Inputs::Tcp do
|
|
251
254
|
socket.flush
|
252
255
|
end
|
253
256
|
end
|
254
|
-
|
255
257
|
socket.close rescue nil
|
256
258
|
|
257
259
|
result
|
@@ -269,8 +271,154 @@ describe LogStash::Inputs::Tcp do
|
|
269
271
|
end
|
270
272
|
end
|
271
273
|
|
272
|
-
|
274
|
+
it "should add the host and port to the generated event" do
|
275
|
+
events.each do |event|
|
276
|
+
expect(event["host"]).to eq("127.0.0.1")
|
277
|
+
expect(event["port"]).to be_an(Fixnum)
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
describe "ssl" do
|
282
|
+
|
283
|
+
let(:certificate) { helper.certificate }
|
284
|
+
|
285
|
+
subject(:input) { LogStash::Plugin.lookup("input", "tcp").new(config) }
|
286
|
+
|
287
|
+
let(:config) do
|
288
|
+
{ "host" => "0.0.0.0", "port" => port, "ssl_verify" => false,
|
289
|
+
"ssl_enable" => true, "ssl_cert" => certificate[0].path, "ssl_key" => certificate[1].path }
|
290
|
+
end
|
291
|
+
|
292
|
+
let(:events) do
|
293
|
+
|
294
|
+
socket = Stud::try(5.times) do
|
295
|
+
ssl_context = OpenSSL::SSL::SSLContext.new
|
296
|
+
socket = TCPSocket.new("127.0.0.1", port)
|
297
|
+
OpenSSL::SSL::SSLSocket.new(socket, ssl_context)
|
298
|
+
end
|
299
|
+
|
300
|
+
result = helper.pipelineless_input(subject, nevents) do
|
301
|
+
socket.connect
|
302
|
+
nevents.times do |i|
|
303
|
+
socket.puts("msg #{i}")
|
304
|
+
socket.flush
|
305
|
+
end
|
306
|
+
end
|
307
|
+
socket.close rescue nil
|
308
|
+
|
309
|
+
result
|
310
|
+
end
|
311
|
+
|
312
|
+
it "should receive events" do
|
313
|
+
expect(events.size).to be(nevents)
|
314
|
+
end
|
315
|
+
|
316
|
+
describe "when ssl_verify is on" do
|
317
|
+
|
318
|
+
let(:chain_of_certificates) { helper.chain_of_certificates }
|
319
|
+
|
320
|
+
let(:ssl_context) do
|
321
|
+
ssl_context = OpenSSL::SSL::SSLContext.new
|
322
|
+
ssl_context.cert = OpenSSL::X509::Certificate.new(client_certificate)
|
323
|
+
ssl_context.key = OpenSSL::PKey::RSA.new(client_key)
|
324
|
+
ssl_context
|
325
|
+
end
|
326
|
+
|
327
|
+
context "and the verification fails" do
|
328
|
+
|
329
|
+
let(:config) do
|
330
|
+
{ "host" => "0.0.0.0", "port" => port,
|
331
|
+
"ssl_enable" => true, "ssl_verify" => true,
|
332
|
+
"ssl_cert" => chain_of_certificates[:a_cert].path, "ssl_key" => chain_of_certificates[:a_key].path }
|
333
|
+
end
|
334
|
+
|
335
|
+
let(:client_certificate) { File.read(chain_of_certificates[:b_cert].path) }
|
336
|
+
let(:client_key) { File.read(chain_of_certificates[:b_key].path) }
|
337
|
+
|
338
|
+
let(:socket) do
|
339
|
+
client = TCPSocket.new("127.0.0.1", port)
|
340
|
+
OpenSSL::SSL::SSLSocket.new(client, ssl_context)
|
341
|
+
end
|
273
342
|
|
343
|
+
it "should raise an exception when connecting" do
|
344
|
+
helper.pipelineless_input(subject, 0) do
|
345
|
+
expect { socket.connect }.to raise_error
|
346
|
+
socket.close rescue nil
|
347
|
+
end
|
348
|
+
end
|
349
|
+
end
|
350
|
+
context "and using the root CA" do
|
351
|
+
|
352
|
+
let(:config) do
|
353
|
+
{ "host" => "0.0.0.0", "port" => port,
|
354
|
+
"ssl_enable" => true, "ssl_verify" => true,
|
355
|
+
"ssl_cert" => chain_of_certificates[:a_cert].path, "ssl_key" => chain_of_certificates[:a_key].path,
|
356
|
+
"ssl_cacert" => chain_of_certificates[:root_ca].path }
|
357
|
+
end
|
358
|
+
|
359
|
+
let(:client_certificate) { File.read(chain_of_certificates[:aa_cert].path) }
|
360
|
+
let(:client_key) { File.read(chain_of_certificates[:aa_key].path) }
|
361
|
+
|
362
|
+
let(:events) do
|
363
|
+
socket = Stud::try(5.times) do
|
364
|
+
socket = TCPSocket.new("127.0.0.1", port)
|
365
|
+
OpenSSL::SSL::SSLSocket.new(socket, ssl_context)
|
366
|
+
end
|
367
|
+
result = helper.pipelineless_input(subject, nevents) do
|
368
|
+
socket.connect
|
369
|
+
nevents.times do |i|
|
370
|
+
socket.puts("msg #{i}")
|
371
|
+
socket.flush
|
372
|
+
end
|
373
|
+
end
|
374
|
+
socket.close rescue nil
|
375
|
+
|
376
|
+
result
|
377
|
+
end
|
378
|
+
|
379
|
+
it "should receive events" do
|
380
|
+
expect(events.size).to be(nevents)
|
381
|
+
end
|
382
|
+
|
383
|
+
end
|
384
|
+
|
385
|
+
context "using an extra chain of certificates" do
|
386
|
+
|
387
|
+
let(:config) do
|
388
|
+
{ "host" => "0.0.0.0", "port" => port,
|
389
|
+
"ssl_enable" => true, "ssl_verify" => true,
|
390
|
+
"ssl_cert" => chain_of_certificates[:b_cert].path, "ssl_key" => chain_of_certificates[:b_key].path,
|
391
|
+
"ssl_extra_chain_certs" => [ chain_of_certificates[:root_ca].path, chain_of_certificates[:a_cert].path, chain_of_certificates[:b_cert].path ] }
|
392
|
+
end
|
393
|
+
|
394
|
+
let(:client_certificate) { File.read(chain_of_certificates[:c_cert].path) }
|
395
|
+
let(:client_key) { File.read(chain_of_certificates[:c_key].path) }
|
396
|
+
|
397
|
+
let(:events) do
|
398
|
+
socket = Stud::try(5.times) do
|
399
|
+
socket = TCPSocket.new("127.0.0.1", port)
|
400
|
+
OpenSSL::SSL::SSLSocket.new(socket, ssl_context)
|
401
|
+
end
|
402
|
+
result = helper.pipelineless_input(subject, nevents) do
|
403
|
+
socket.connect
|
404
|
+
nevents.times do |i|
|
405
|
+
socket.puts("msg #{i}")
|
406
|
+
socket.flush
|
407
|
+
end
|
408
|
+
end
|
409
|
+
socket.close rescue nil
|
410
|
+
|
411
|
+
result
|
412
|
+
end
|
413
|
+
|
414
|
+
it "should receive events" do
|
415
|
+
expect(events.size).to be(nevents)
|
416
|
+
end
|
417
|
+
end
|
418
|
+
end
|
419
|
+
|
420
|
+
end
|
421
|
+
end
|
274
422
|
it_behaves_like "an interruptible input plugin" do
|
275
423
|
let(:config) { { "port" => port } }
|
276
424
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require "logstash/devutils/rspec/spec_helper"
|
3
|
+
require "tempfile"
|
4
|
+
require "stud/temporary"
|
3
5
|
|
4
6
|
# this has been taken from the udp input, it should be DRYed
|
5
7
|
|
@@ -19,4 +21,71 @@ class TcpHelpers
|
|
19
21
|
input_thread.join
|
20
22
|
result
|
21
23
|
end
|
24
|
+
|
25
|
+
def certificate
|
26
|
+
certificate, key = Flores::PKI.generate("CN=localhost", { :key_size => 2048 })
|
27
|
+
[new_temp_file('cert', certificate), new_temp_file('key', key)]
|
28
|
+
end
|
29
|
+
|
30
|
+
def chain_of_certificates
|
31
|
+
root_ca, root_key = build_root_ca
|
32
|
+
a_cert, a_key = build_certificate(root_ca, root_key, "A_Cert")
|
33
|
+
aa_cert, aa_key = build_certificate(root_ca, root_key, "AA_Cert")
|
34
|
+
b_cert, b_key = build_certificate(a_cert, a_key, "B_Cert")
|
35
|
+
c_cert, c_key = build_certificate(b_cert, b_key, "C_Cert")
|
36
|
+
{ :root_ca => new_temp_file('', root_ca), :root_key => new_temp_file('', root_key),
|
37
|
+
:a_cert => new_temp_file('', a_cert), :a_key => new_temp_file('', a_key),
|
38
|
+
:aa_cert => new_temp_file('', aa_cert), :aa_key => new_temp_file('', aa_key),
|
39
|
+
:b_cert => new_temp_file('', b_cert), :b_key => new_temp_file('', b_key),
|
40
|
+
:c_cert => new_temp_file('', c_cert), :c_key => new_temp_file('', c_key)}
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def new_temp_file(name, data)
|
46
|
+
file = Stud::Temporary.file
|
47
|
+
file.write(data)
|
48
|
+
file.rewind
|
49
|
+
file
|
50
|
+
end
|
51
|
+
|
52
|
+
def build_certificate(root_ca, root_key=nil, name="")
|
53
|
+
key = ( root_key.nil? ? OpenSSL::PKey::RSA.new(2048) : root_key )
|
54
|
+
options = { :serial => 2, :subject => "/DC=org/DC=ruby-lang/CN=Ruby#{name}", :key => key, :issuer => root_ca.subject}
|
55
|
+
cert = new_certificate(options)
|
56
|
+
add_ca_extensions(cert, nil, root_ca)
|
57
|
+
[ cert.sign(key, OpenSSL::Digest::SHA256.new), key ]
|
58
|
+
end
|
59
|
+
|
60
|
+
def build_root_ca
|
61
|
+
key = OpenSSL::PKey::RSA.new(2048)
|
62
|
+
options = { :serial => 1, :subject => "/DC=org/DC=ruby-lang/CN=Ruby CA", :key => key}
|
63
|
+
ca = new_certificate(options)
|
64
|
+
add_ca_extensions(ca)
|
65
|
+
[ ca.sign(key, OpenSSL::Digest::SHA256.new), key ]
|
66
|
+
end
|
67
|
+
|
68
|
+
def new_certificate(options)
|
69
|
+
cert = OpenSSL::X509::Certificate.new
|
70
|
+
cert.version = 2
|
71
|
+
cert.serial = options.fetch(:serial, 1)
|
72
|
+
cert.subject = OpenSSL::X509::Name.parse(options.fetch(:subject, "/DC=org/DC=ruby-lang/CN=Ruby CA"))
|
73
|
+
cert.issuer = options.fetch(:issuer, cert.subject)
|
74
|
+
cert.public_key = options[:key].public_key
|
75
|
+
cert.not_before = Time.now
|
76
|
+
cert.not_after = cert.not_before + 2 * 365 * 86400
|
77
|
+
cert
|
78
|
+
end
|
79
|
+
|
80
|
+
def add_ca_extensions(certificate, subject=nil, issuer=nil)
|
81
|
+
factory = OpenSSL::X509::ExtensionFactory.new
|
82
|
+
factory.subject_certificate = (subject.nil? ? certificate : subject)
|
83
|
+
factory.issuer_certificate = (issuer.nil? ? certificate : issuer)
|
84
|
+
|
85
|
+
certificate.add_extension(factory.create_extension("basicConstraints","CA:TRUE",true))
|
86
|
+
certificate.add_extension(factory.create_extension("keyUsage","keyCertSign, cRLSign, digitalSignature", true))
|
87
|
+
certificate.add_extension(factory.create_extension("subjectKeyIdentifier","hash",false))
|
88
|
+
certificate.add_extension(factory.create_extension("authorityKeyIdentifier","keyid:always",false))
|
89
|
+
end
|
90
|
+
|
22
91
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-input-tcp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Elastic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-11-
|
11
|
+
date: 2015-11-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: logstash-core
|
@@ -100,6 +100,34 @@ dependencies:
|
|
100
100
|
version: '0'
|
101
101
|
prerelease: false
|
102
102
|
type: :development
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: flores
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 0.0.6
|
110
|
+
requirement: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - ~>
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: 0.0.6
|
115
|
+
prerelease: false
|
116
|
+
type: :development
|
117
|
+
- !ruby/object:Gem::Dependency
|
118
|
+
name: stud
|
119
|
+
version_requirements: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ~>
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: 0.0.22
|
124
|
+
requirement: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - ~>
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: 0.0.22
|
129
|
+
prerelease: false
|
130
|
+
type: :development
|
103
131
|
description: This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program
|
104
132
|
email: info@elastic.co
|
105
133
|
executables: []
|
@@ -138,10 +166,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
138
166
|
version: '0'
|
139
167
|
requirements: []
|
140
168
|
rubyforge_project:
|
141
|
-
rubygems_version: 2.4.
|
169
|
+
rubygems_version: 2.4.6
|
142
170
|
signing_key:
|
143
171
|
specification_version: 4
|
144
172
|
summary: Read events over a TCP socket.
|
145
173
|
test_files:
|
146
174
|
- spec/inputs/tcp_spec.rb
|
147
175
|
- spec/spec_helper.rb
|
176
|
+
has_rdoc:
|