logstash-input-beats 3.1.0.beta1-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 +7 -0
- data/CHANGELOG.md +131 -0
- data/CONTRIBUTORS +17 -0
- data/Gemfile +4 -0
- data/LICENSE +14 -0
- data/NOTICE.TXT +5 -0
- data/PROTOCOL.md +127 -0
- data/README.md +98 -0
- data/VERSION +1 -0
- data/lib/logstash-input-beats_jars.rb +17 -0
- data/lib/logstash/inputs/beats.rb +184 -0
- data/lib/logstash/inputs/beats/codec_callback_listener.rb +26 -0
- data/lib/logstash/inputs/beats/decoded_event_transform.rb +34 -0
- data/lib/logstash/inputs/beats/event_transform_common.rb +48 -0
- data/lib/logstash/inputs/beats/message_listener.rb +96 -0
- data/lib/logstash/inputs/beats/raw_event_transform.rb +18 -0
- data/lib/logstash/inputs/beats/tls.rb +40 -0
- data/lib/tasks/build.rake +15 -0
- data/lib/tasks/test.rake +65 -0
- data/logstash-input-beats.gemspec +41 -0
- data/spec/inputs/beats/codec_callback_listener_spec.rb +33 -0
- data/spec/inputs/beats/decoded_event_transform_spec.rb +74 -0
- data/spec/inputs/beats/event_transform_common_spec.rb +11 -0
- data/spec/inputs/beats/message_listener_spec.rb +108 -0
- data/spec/inputs/beats/raw_event_transform_spec.rb +26 -0
- data/spec/inputs/beats/tls_spec.rb +39 -0
- data/spec/inputs/beats_spec.rb +99 -0
- data/spec/integration/filebeat_spec.rb +234 -0
- data/spec/integration/logstash_forwarder_spec.rb +104 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/support/client_process_helpers.rb +28 -0
- data/spec/support/file_helpers.rb +61 -0
- data/spec/support/flores_extensions.rb +82 -0
- data/spec/support/integration_shared_context.rb +73 -0
- data/spec/support/logstash_test.rb +66 -0
- data/spec/support/shared_examples.rb +56 -0
- data/vendor/jar-dependencies/com/fasterxml/jackson/core/jackson-annotations/2.7.5/jackson-annotations-2.7.5.jar +0 -0
- data/vendor/jar-dependencies/com/fasterxml/jackson/core/jackson-core/2.7.5/jackson-core-2.7.5.jar +0 -0
- data/vendor/jar-dependencies/com/fasterxml/jackson/core/jackson-databind/2.7.5/jackson-databind-2.7.5.jar +0 -0
- data/vendor/jar-dependencies/com/fasterxml/jackson/module/jackson-module-afterburner/2.7.5/jackson-module-afterburner-2.7.5.jar +0 -0
- data/vendor/jar-dependencies/io/netty/netty-all/4.1.1.Final/netty-all-4.1.1.Final.jar +0 -0
- data/vendor/jar-dependencies/io/netty/netty-tcnative-boringssl-static/1.1.33.Fork17/netty-tcnative-boringssl-static-1.1.33.Fork17.jar +0 -0
- data/vendor/jar-dependencies/org/apache/logging/log4j/log4j-1.2-api/2.6.1/log4j-1.2-api-2.6.1.jar +0 -0
- data/vendor/jar-dependencies/org/apache/logging/log4j/log4j-api/2.6.1/log4j-api-2.6.1.jar +0 -0
- data/vendor/jar-dependencies/org/apache/logging/log4j/log4j-core/2.6.1/log4j-core-2.6.1.jar +0 -0
- data/vendor/jar-dependencies/org/apache/logging/log4j/log4j-slf4j-impl/2.6.1/log4j-slf4j-impl-2.6.1.jar +0 -0
- data/vendor/jar-dependencies/org/bouncycastle/bcpkix-jdk15on/1.54/bcpkix-jdk15on-1.54.jar +0 -0
- data/vendor/jar-dependencies/org/bouncycastle/bcprov-jdk15on/1.54/bcprov-jdk15on-1.54.jar +0 -0
- data/vendor/jar-dependencies/org/javassist/javassist/3.20.0-GA/javassist-3.20.0-GA.jar +0 -0
- data/vendor/jar-dependencies/org/logstash/beats/logstash-input-beats/3.1.0.beta1/logstash-input-beats-3.1.0.beta1.jar +0 -0
- metadata +313 -0
@@ -0,0 +1,11 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/event"
|
3
|
+
require "logstash/inputs/beats"
|
4
|
+
require_relative "../../support/shared_examples"
|
5
|
+
require "spec_helper"
|
6
|
+
|
7
|
+
describe LogStash::Inputs::Beats::EventTransformCommon do
|
8
|
+
subject { described_class.new(input).transform(event) }
|
9
|
+
|
10
|
+
include_examples "Common Event Transformation"
|
11
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/inputs/beats"
|
3
|
+
require "logstash/event"
|
4
|
+
require "logstash/inputs/beats/message_listener"
|
5
|
+
require "thread"
|
6
|
+
|
7
|
+
class MockMessage
|
8
|
+
def initialize(identity_stream, data = {})
|
9
|
+
@identity_stream = identity_stream
|
10
|
+
@data = data
|
11
|
+
end
|
12
|
+
|
13
|
+
def getData
|
14
|
+
@data
|
15
|
+
end
|
16
|
+
|
17
|
+
def getIdentityStream
|
18
|
+
@identity_stream
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class DummyCodec < LogStash::Codecs::Base
|
23
|
+
DUMMY_EVENT = LogStash::Event.new
|
24
|
+
|
25
|
+
def decode(message, &block)
|
26
|
+
block.call(LogStash::Event.new({"message" => message}))
|
27
|
+
end
|
28
|
+
|
29
|
+
def flush(&block)
|
30
|
+
block.call(DUMMY_EVENT)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe LogStash::Inputs::Beats::MessageListener do
|
35
|
+
let(:queue) { Queue.new }
|
36
|
+
let(:codec) { DummyCodec.new }
|
37
|
+
let(:input) { LogStash::Inputs::Beats.new({ "port" => 5555, "codec" => codec }) }
|
38
|
+
let(:ctx) { double("ChannelHandlerContext") }
|
39
|
+
let(:message) { MockMessage.new("abc", { "message" => "hello world"}) }
|
40
|
+
|
41
|
+
subject { described_class.new(queue, input) }
|
42
|
+
|
43
|
+
before do
|
44
|
+
subject.onNewConnection(ctx)
|
45
|
+
end
|
46
|
+
|
47
|
+
context "onNewConnection" do
|
48
|
+
it "register the connection to the connection list" do
|
49
|
+
expect { subject.onNewConnection(double("ChannelHandlerContext")) }.to change { subject.connections_list.count }.by(1)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context "onNewMessage" do
|
54
|
+
context "when the message is from filebeat" do
|
55
|
+
let(:message) { MockMessage.new("abc", { "message" => "hello world" } )}
|
56
|
+
|
57
|
+
it "extract the event" do
|
58
|
+
subject.onNewMessage(ctx, message)
|
59
|
+
event = queue.pop
|
60
|
+
expect(event.get("message")).to eq("hello world")
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context "when the message is from LSF" do
|
65
|
+
let(:message) { MockMessage.new("abc", { "line" => "hello world" } )}
|
66
|
+
|
67
|
+
it "extract the event" do
|
68
|
+
subject.onNewMessage(ctx, message)
|
69
|
+
event = queue.pop
|
70
|
+
expect(event.get("message")).to eq("hello world")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context "when the message is from any libbeat" do
|
75
|
+
let(:message) { MockMessage.new("abc", { "metric" => 1, "name" => "super-stats"} )}
|
76
|
+
|
77
|
+
it "extract the event" do
|
78
|
+
subject.onNewMessage(ctx, message)
|
79
|
+
event = queue.pop
|
80
|
+
expect(event.get("message")).to be_nil
|
81
|
+
expect(event.get("metric")).to eq(1)
|
82
|
+
expect(event.get("name")).to eq("super-stats")
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context "onException" do
|
88
|
+
it "remove the connection to the connection list" do
|
89
|
+
expect { subject.onException(ctx) }.to change { subject.connections_list.count }.by(-1)
|
90
|
+
end
|
91
|
+
|
92
|
+
it "calls flush on codec" do
|
93
|
+
subject.onConnectionClose(ctx)
|
94
|
+
expect(queue).not_to be_empty
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context "onConnectionClose" do
|
99
|
+
it "remove the connection to the connection list" do
|
100
|
+
expect { subject.onConnectionClose(ctx) }.to change { subject.connections_list.count }.by(-1)
|
101
|
+
end
|
102
|
+
|
103
|
+
it "calls flush on codec" do
|
104
|
+
subject.onConnectionClose(ctx)
|
105
|
+
expect(queue).not_to be_empty
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/event"
|
3
|
+
require "logstash/inputs/beats"
|
4
|
+
require_relative "../../support/shared_examples"
|
5
|
+
require "spec_helper"
|
6
|
+
|
7
|
+
describe LogStash::Inputs::Beats::RawEventTransform do
|
8
|
+
let(:config) do
|
9
|
+
{
|
10
|
+
"port" => 0,
|
11
|
+
"type" => "example",
|
12
|
+
"tags" => "beats"
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:input) { LogStash::Inputs::Beats.new(config) }
|
17
|
+
let(:event) { LogStash::Event.new }
|
18
|
+
|
19
|
+
subject { described_class.new(input).transform(event) }
|
20
|
+
|
21
|
+
include_examples "Common Event Transformation"
|
22
|
+
|
23
|
+
it "tags the event" do
|
24
|
+
expect(subject.get("tags")).to include("beats_input_raw_event")
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/inputs/beats/tls"
|
3
|
+
|
4
|
+
describe LogStash::Inputs::Beats::TLS do
|
5
|
+
subject { described_class }
|
6
|
+
|
7
|
+
it "returns the minimum supported tls" do
|
8
|
+
expect(subject.min.version).to eq(1)
|
9
|
+
expect(subject.min.name).to eq("TLSv1")
|
10
|
+
end
|
11
|
+
|
12
|
+
it "returns the maximum supported tls" do
|
13
|
+
expect(subject.max.version).to eq(1.2)
|
14
|
+
expect(subject.max.name).to eq("TLSv1.2")
|
15
|
+
end
|
16
|
+
|
17
|
+
describe ".get_supported" do
|
18
|
+
context "when a range is given" do
|
19
|
+
it "returns the list of compatible TLS from a range" do
|
20
|
+
expect(subject.get_supported((1.1)..(1.2)).map(&:version)).to match([1.1, 1.2])
|
21
|
+
end
|
22
|
+
|
23
|
+
it "it return an empty array when nothing match" do
|
24
|
+
expect(subject.get_supported((3.1)..(8.2))).to be_empty
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "when a scalar is given" do
|
29
|
+
it "when a scalar is given we return the compatible value" do
|
30
|
+
expect(subject.get_supported(1.1).map(&:version)).to match([1.1])
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
it "it return an empty array when nothing match" do
|
35
|
+
expect(subject.get_supported(9)).to be_empty
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require_relative "../spec_helper"
|
3
|
+
require "stud/temporary"
|
4
|
+
require "logstash/inputs/beats"
|
5
|
+
require "logstash/codecs/plain"
|
6
|
+
require "logstash/codecs/json"
|
7
|
+
require "logstash/codecs/multiline"
|
8
|
+
require "logstash/event"
|
9
|
+
|
10
|
+
describe LogStash::Inputs::Beats do
|
11
|
+
let(:connection) { double("connection") }
|
12
|
+
let(:certificate) { BeatsInputTest.certificate }
|
13
|
+
let(:port) { BeatsInputTest.random_port }
|
14
|
+
let(:queue) { Queue.new }
|
15
|
+
let(:config) { { "port" => 0, "ssl_certificate" => certificate.ssl_cert, "ssl_key" => certificate.ssl_key, "type" => "example", "tags" => "beats"} }
|
16
|
+
|
17
|
+
context "#register" do
|
18
|
+
context "identity map" do
|
19
|
+
subject(:plugin) { LogStash::Inputs::Beats.new(config) }
|
20
|
+
before { plugin.register }
|
21
|
+
|
22
|
+
context "when using the multiline codec" do
|
23
|
+
let(:codec) { LogStash::Codecs::Multiline.new("pattern" => '^2015',
|
24
|
+
"what" => "previous",
|
25
|
+
"negate" => true) }
|
26
|
+
let(:config) { super.merge({ "codec" => codec }) }
|
27
|
+
|
28
|
+
it "wraps the codec with the identity_map" do
|
29
|
+
expect(plugin.codec).to be_kind_of(LogStash::Codecs::IdentityMapCodec)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "when using non buffered codecs" do
|
34
|
+
let(:config) { super.merge({ "codec" => "json" }) }
|
35
|
+
|
36
|
+
it "doesnt wrap the codec with the identity map" do
|
37
|
+
expect(plugin.codec).to be_kind_of(LogStash::Codecs::JSON)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
it "raise no exception" do
|
43
|
+
plugin = LogStash::Inputs::Beats.new(config)
|
44
|
+
expect { plugin.register }.not_to raise_error
|
45
|
+
end
|
46
|
+
|
47
|
+
context "with ssl enabled" do
|
48
|
+
context "without certificate configuration" do
|
49
|
+
let(:config) {{ "port" => 0, "ssl" => true, "ssl_key" => certificate.ssl_key, "type" => "example", "tags" => "beats" }}
|
50
|
+
|
51
|
+
it "should fail to register the plugin with ConfigurationError" do
|
52
|
+
plugin = LogStash::Inputs::Beats.new(config)
|
53
|
+
expect {plugin.register}.to raise_error(LogStash::ConfigurationError)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context "without key configuration" do
|
58
|
+
let(:config) { { "port" => 0, "ssl" => true, "ssl_certificate" => certificate.ssl_cert, "type" => "example", "tags" => "Beats"} }
|
59
|
+
it "should fail to register the plugin with ConfigurationError" do
|
60
|
+
plugin = LogStash::Inputs::Beats.new(config)
|
61
|
+
expect {plugin.register}.to raise_error(LogStash::ConfigurationError)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context "with ssl disabled" do
|
67
|
+
context "and certificate configuration" do
|
68
|
+
let(:config) { { "port" => 0, "ssl" => false, "ssl_certificate" => certificate.ssl_cert, "type" => "example", "tags" => "Beats" } }
|
69
|
+
|
70
|
+
it "should not fail" do
|
71
|
+
plugin = LogStash::Inputs::Beats.new(config)
|
72
|
+
expect {plugin.register}.not_to raise_error
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context "and certificate key configuration" do
|
77
|
+
let(:config) {{ "port" => 0, "ssl" => false, "ssl_key" => certificate.ssl_key, "type" => "example", "tags" => "beats" }}
|
78
|
+
|
79
|
+
it "should not fail" do
|
80
|
+
plugin = LogStash::Inputs::Beats.new(config)
|
81
|
+
expect {plugin.register}.not_to raise_error
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context "and no certificate or key configured" do
|
86
|
+
let(:config) {{ "ssl" => false, "port" => 0, "type" => "example", "tags" => "beats" }}
|
87
|
+
|
88
|
+
it "should work just fine" do
|
89
|
+
plugin = LogStash::Inputs::Beats.new(config)
|
90
|
+
expect {plugin.register}.not_to raise_error
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context "when interrupting the plugin" do
|
97
|
+
it_behaves_like "an interruptible input plugin"
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,234 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/inputs/beats"
|
3
|
+
require "stud/temporary"
|
4
|
+
require "flores/pki"
|
5
|
+
require "fileutils"
|
6
|
+
require "thread"
|
7
|
+
require "spec_helper"
|
8
|
+
require "yaml"
|
9
|
+
require "fileutils"
|
10
|
+
require "flores/pki"
|
11
|
+
require_relative "../support/flores_extensions"
|
12
|
+
require_relative "../support/file_helpers"
|
13
|
+
require_relative "../support/integration_shared_context"
|
14
|
+
require_relative "../support/client_process_helpers"
|
15
|
+
|
16
|
+
FILEBEAT_BINARY = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "vendor", "filebeat", "filebeat"))
|
17
|
+
|
18
|
+
describe "Filebeat", :integration => true do
|
19
|
+
include ClientProcessHelpers
|
20
|
+
include FileHelpers
|
21
|
+
|
22
|
+
before :all do
|
23
|
+
unless File.exist?(FILEBEAT_BINARY)
|
24
|
+
raise "Cannot find `Filebeat` binary in `vendor/filebeat`. Did you run `bundle exec rake test:integration:setup` before running the integration suite?"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
include_context "beats configuration"
|
29
|
+
|
30
|
+
# Filebeat related variables
|
31
|
+
let(:cmd) { [filebeat_exec, "-c", filebeat_config_path, "-e", "-v"] }
|
32
|
+
|
33
|
+
let(:filebeat_exec) { FILEBEAT_BINARY }
|
34
|
+
|
35
|
+
let_empty_tmp_file(:registry_file)
|
36
|
+
let(:filebeat_config) do
|
37
|
+
{
|
38
|
+
"filebeat" => {
|
39
|
+
"prospectors" => [{ "paths" => [log_file], "input_type" => "log" }],
|
40
|
+
"registry_file" => registry_file,
|
41
|
+
"scan_frequency" => "1s"
|
42
|
+
},
|
43
|
+
"output" => {
|
44
|
+
"logstash" => { "hosts" => ["#{host}:#{port}"] },
|
45
|
+
"logging" => { "level" => "debug" }
|
46
|
+
}
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
let_tmp_file(:filebeat_config_path) { YAML.dump(filebeat_config) }
|
51
|
+
before :each do
|
52
|
+
start_client
|
53
|
+
sleep(2) # give some time to FB to send something
|
54
|
+
stop_client
|
55
|
+
end
|
56
|
+
|
57
|
+
###########################################################
|
58
|
+
shared_context "Root CA" do
|
59
|
+
let(:root_ca) { Flores::PKI.generate("CN=root.localhost") }
|
60
|
+
let(:root_ca_certificate) { root_ca.first }
|
61
|
+
let(:root_ca_key) { root_ca.last }
|
62
|
+
let_tmp_file(:root_ca_certificate_file) { root_ca_certificate }
|
63
|
+
end
|
64
|
+
|
65
|
+
shared_context "Intermediate CA" do
|
66
|
+
let(:intermediate_ca) { Flores::PKI.create_intermediate_certificate("CN=intermediate.localhost", root_ca_certificate, root_ca_key) }
|
67
|
+
let(:intermediate_ca_certificate) { intermediate_ca.first }
|
68
|
+
let(:intermediate_ca_key) { intermediate_ca.last }
|
69
|
+
let_tmp_file(:intermediate_ca_certificate_file) { intermediate_ca_certificate }
|
70
|
+
let_tmp_file(:certificate_authorities_chain) { Flores::PKI.chain_certificates(root_ca_certificate, intermediate_ca_certificate) }
|
71
|
+
end
|
72
|
+
|
73
|
+
############################################################
|
74
|
+
# Actuals tests
|
75
|
+
context "Plain TCP" do
|
76
|
+
include_examples "send events"
|
77
|
+
end
|
78
|
+
|
79
|
+
context "TLS" do
|
80
|
+
context "Server verification" do
|
81
|
+
let(:filebeat_config) do
|
82
|
+
super.merge({
|
83
|
+
"output" => {
|
84
|
+
"logstash" => {
|
85
|
+
"hosts" => ["#{host}:#{port}"],
|
86
|
+
"tls" => { "certificate_authorities" => certificate_authorities }
|
87
|
+
},
|
88
|
+
"logging" => { "level" => "debug" }
|
89
|
+
}})
|
90
|
+
end
|
91
|
+
|
92
|
+
let(:input_config) do
|
93
|
+
super.merge({
|
94
|
+
"ssl" => true,
|
95
|
+
"ssl_certificate" => certificate_file,
|
96
|
+
"ssl_key" => certificate_key_file
|
97
|
+
})
|
98
|
+
end
|
99
|
+
|
100
|
+
let(:certificate_authorities) { [certificate_file] }
|
101
|
+
let(:certificate_data) { Flores::PKI.generate }
|
102
|
+
let_tmp_file(:certificate_key_file) { certificate_data.last }
|
103
|
+
let_tmp_file(:certificate_file) { certificate_data.first }
|
104
|
+
|
105
|
+
context "self signed certificate" do
|
106
|
+
include_examples "send events"
|
107
|
+
end
|
108
|
+
|
109
|
+
context "CA root" do
|
110
|
+
include_context "Root CA"
|
111
|
+
|
112
|
+
context "directly signed client certificate" do
|
113
|
+
let(:certificate_authorities) { [root_ca_certificate_file] }
|
114
|
+
let(:certificate_data) { Flores::PKI.create_client_certicate("CN=localhost", root_ca_certificate, root_ca_key) }
|
115
|
+
|
116
|
+
include_examples "send events"
|
117
|
+
end
|
118
|
+
|
119
|
+
context "intermediate CA signs client certificate" do
|
120
|
+
include_context "Intermediate CA"
|
121
|
+
|
122
|
+
let(:certificate_data) { Flores::PKI.create_client_certicate("CN=localhost", intermediate_ca_certificate, intermediate_ca_key) }
|
123
|
+
let(:certificate_authorities) { [certificate_authorities_chain] }
|
124
|
+
|
125
|
+
include_examples "send events"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
context "Client verification / Mutual validation" do
|
130
|
+
let(:filebeat_config) do
|
131
|
+
super.merge({
|
132
|
+
"output" => {
|
133
|
+
"logstash" => {
|
134
|
+
"hosts" => ["#{host}:#{port}"],
|
135
|
+
"tls" => {
|
136
|
+
"certificate_authorities" => certificate_authorities,
|
137
|
+
"certificate" => certificate_file,
|
138
|
+
"certificate_key" => certificate_key_file
|
139
|
+
}
|
140
|
+
},
|
141
|
+
"logging" => { "level" => "debug" }
|
142
|
+
}})
|
143
|
+
end
|
144
|
+
|
145
|
+
let(:input_config) do
|
146
|
+
super.merge({
|
147
|
+
"ssl" => true,
|
148
|
+
"ssl_certificate_authorities" => certificate_authorities,
|
149
|
+
"ssl_certificate" => server_certificate_file,
|
150
|
+
"ssl_key" => server_certificate_key_file,
|
151
|
+
"ssl_verify_mode" => "force_peer"
|
152
|
+
})
|
153
|
+
end
|
154
|
+
|
155
|
+
context "with a self signed certificate" do
|
156
|
+
let(:certificate_authorities) { [certificate_file] }
|
157
|
+
let(:certificate_data) { Flores::PKI.generate }
|
158
|
+
let_tmp_file(:certificate_key_file) { certificate_data.last }
|
159
|
+
let_tmp_file(:certificate_file) { certificate_data.first }
|
160
|
+
let_tmp_file(:server_certificate_file) { certificate_data.first }
|
161
|
+
let_tmp_file(:server_certificate_key_file) { certificate_data.last }
|
162
|
+
|
163
|
+
include_examples "send events"
|
164
|
+
end
|
165
|
+
|
166
|
+
context "CA root" do
|
167
|
+
include_context "Root CA"
|
168
|
+
|
169
|
+
let_tmp_file(:server_certificate_file) { server_certificate_data.first }
|
170
|
+
let_tmp_file(:server_certificate_key_file) { server_certificate_data.last }
|
171
|
+
|
172
|
+
context "directly signed client certificate" do
|
173
|
+
let(:certificate_authorities) { [root_ca_certificate_file] }
|
174
|
+
let(:certificate_data) { Flores::PKI.create_client_certicate("CN=localhost", root_ca_certificate, root_ca_key) }
|
175
|
+
let(:server_certificate_data) { Flores::PKI.create_client_certicate("CN=localhost", root_ca_certificate, root_ca_key) }
|
176
|
+
|
177
|
+
include_examples "send events"
|
178
|
+
end
|
179
|
+
|
180
|
+
### DOESNT WORK
|
181
|
+
context "intermediate create server and client certificate" do
|
182
|
+
include_context "Intermediate CA"
|
183
|
+
|
184
|
+
let(:certificate_data) { Flores::PKI.create_client_certicate("CN=localhost", intermediate_ca_certificate, intermediate_ca_key) }
|
185
|
+
let(:server_certificate_data) { Flores::PKI.create_client_certicate("CN=localhost", intermediate_ca_certificate, intermediate_ca_key) }
|
186
|
+
let(:certificate_authorities) { [intermediate_ca_certificate_file] }
|
187
|
+
|
188
|
+
include_examples "send events"
|
189
|
+
end
|
190
|
+
|
191
|
+
context "and Secondary CA multiples clients" do
|
192
|
+
context "with CA in different files" do
|
193
|
+
let(:secondary_ca) { Flores::PKI.generate }
|
194
|
+
let(:secondary_ca_key) { secondary_ca.last }
|
195
|
+
let(:secondary_ca_certificate) { secondary_ca.first }
|
196
|
+
let_tmp_file(:secondary_ca_certificate_file) { secondary_ca.first }
|
197
|
+
|
198
|
+
let(:secondary_client_certificate_data) { Flores::PKI.create_client_certicate("CN=localhost", secondary_ca_certificate, secondary_ca_key) }
|
199
|
+
let_tmp_file(:secondary_client_certificate_file) { secondary_client_certificate_data.first }
|
200
|
+
let_tmp_file(:secondary_client_certificate_key_file) { secondary_client_certificate_data.last }
|
201
|
+
let(:certificate_authorities) { [root_ca_certificate_file, secondary_ca_certificate_file] }
|
202
|
+
let(:certificate_data) { Flores::PKI.create_client_certicate("CN=localhost", root_ca_certificate, root_ca_key) }
|
203
|
+
|
204
|
+
let(:server_certificate_data) { Flores::PKI.create_client_certicate("CN=localhost", root_ca_certificate, root_ca_key) }
|
205
|
+
|
206
|
+
context "client from primary CA" do
|
207
|
+
include_examples "send events"
|
208
|
+
end
|
209
|
+
|
210
|
+
context "client from secondary CA" do
|
211
|
+
let(:filebeat_config) do
|
212
|
+
super.merge({
|
213
|
+
"output" => {
|
214
|
+
"logstash" => {
|
215
|
+
"hosts" => ["#{host}:#{port}"],
|
216
|
+
"tls" => {
|
217
|
+
"certificate_authorities" => certificate_authorities,
|
218
|
+
"certificate" => secondary_client_certificate_file,
|
219
|
+
"certificate_key" => secondary_client_certificate_key_file
|
220
|
+
}
|
221
|
+
},
|
222
|
+
"logging" => { "level" => "debug" }
|
223
|
+
}})
|
224
|
+
end
|
225
|
+
|
226
|
+
include_examples "send events"
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|