logstash-core 6.0.0.alpha2-java → 6.0.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 +5 -5
- data/gemspec_jars.rb +6 -4
- data/lib/logstash-core/logstash-core.jar +0 -0
- data/lib/logstash-core/logstash-core.rb +2 -2
- data/lib/logstash-core/version.rb +1 -1
- data/lib/logstash-core_jars.rb +14 -10
- data/lib/logstash/agent.rb +4 -2
- data/lib/logstash/api/commands/default_metadata.rb +1 -1
- data/lib/logstash/api/commands/hot_threads_reporter.rb +8 -2
- data/lib/logstash/api/commands/node.rb +2 -2
- data/lib/logstash/api/commands/stats.rb +2 -2
- data/lib/logstash/bootstrap_check/bad_ruby.rb +2 -2
- data/lib/logstash/bootstrap_check/default_config.rb +2 -3
- data/lib/logstash/compiler.rb +12 -12
- data/lib/logstash/compiler/lscl.rb +17 -7
- data/lib/logstash/compiler/treetop_monkeypatches.rb +1 -0
- data/lib/logstash/config/config_ast.rb +11 -1
- data/lib/logstash/config/mixin.rb +5 -0
- data/lib/logstash/config/modules_common.rb +101 -0
- data/lib/logstash/config/source/base.rb +75 -0
- data/lib/logstash/config/source/local.rb +52 -50
- data/lib/logstash/config/source/modules.rb +55 -0
- data/lib/logstash/config/source/multi_local.rb +54 -10
- data/lib/logstash/config/source_loader.rb +1 -0
- data/lib/logstash/config/string_escape.rb +27 -0
- data/lib/logstash/elasticsearch_client.rb +142 -0
- data/lib/logstash/environment.rb +5 -1
- data/lib/logstash/event.rb +0 -1
- data/lib/logstash/instrument/global_metrics.rb +13 -0
- data/lib/logstash/instrument/metric_store.rb +16 -13
- data/lib/logstash/instrument/metric_type/counter.rb +6 -18
- data/lib/logstash/instrument/metric_type/gauge.rb +6 -12
- data/lib/logstash/instrument/periodic_poller/dlq.rb +19 -0
- data/lib/logstash/instrument/periodic_pollers.rb +3 -1
- data/lib/logstash/logging/logger.rb +43 -14
- data/lib/logstash/modules/cli_parser.rb +74 -0
- data/lib/logstash/modules/elasticsearch_config.rb +22 -0
- data/lib/logstash/modules/elasticsearch_importer.rb +37 -0
- data/lib/logstash/modules/elasticsearch_resource.rb +10 -0
- data/lib/logstash/modules/file_reader.rb +36 -0
- data/lib/logstash/modules/kibana_base.rb +24 -0
- data/lib/logstash/modules/kibana_client.rb +122 -0
- data/lib/logstash/modules/kibana_config.rb +125 -0
- data/lib/logstash/modules/kibana_dashboards.rb +36 -0
- data/lib/logstash/modules/kibana_importer.rb +17 -0
- data/lib/logstash/modules/kibana_resource.rb +10 -0
- data/lib/logstash/modules/kibana_settings.rb +40 -0
- data/lib/logstash/modules/logstash_config.rb +120 -0
- data/lib/logstash/modules/resource_base.rb +38 -0
- data/lib/logstash/modules/scaffold.rb +50 -0
- data/lib/logstash/modules/settings_merger.rb +23 -0
- data/lib/logstash/modules/util.rb +17 -0
- data/lib/logstash/namespace.rb +1 -0
- data/lib/logstash/pipeline.rb +66 -27
- data/lib/logstash/pipeline_settings.rb +1 -0
- data/lib/logstash/plugins/registry.rb +1 -0
- data/lib/logstash/runner.rb +47 -3
- data/lib/logstash/settings.rb +20 -1
- data/lib/logstash/util/dead_letter_queue_manager.rb +1 -1
- data/lib/logstash/util/safe_uri.rb +146 -11
- data/lib/logstash/util/thread_dump.rb +4 -3
- data/lib/logstash/util/wrapped_acked_queue.rb +28 -24
- data/lib/logstash/util/wrapped_synchronous_queue.rb +19 -20
- data/lib/logstash/version.rb +1 -1
- data/locales/en.yml +56 -1
- data/logstash-core.gemspec +6 -4
- data/spec/logstash/agent/converge_spec.rb +2 -2
- data/spec/logstash/agent_spec.rb +11 -3
- data/spec/logstash/api/modules/logging_spec.rb +13 -7
- data/spec/logstash/api/modules/node_plugins_spec.rb +23 -5
- data/spec/logstash/api/modules/node_spec.rb +17 -15
- data/spec/logstash/api/modules/node_stats_spec.rb +0 -1
- data/spec/logstash/api/modules/plugins_spec.rb +40 -9
- data/spec/logstash/api/modules/root_spec.rb +0 -1
- data/spec/logstash/api/rack_app_spec.rb +2 -1
- data/spec/logstash/compiler/compiler_spec.rb +54 -7
- data/spec/logstash/config/config_ast_spec.rb +47 -8
- data/spec/logstash/config/mixin_spec.rb +14 -2
- data/spec/logstash/config/pipeline_config_spec.rb +7 -7
- data/spec/logstash/config/source/local_spec.rb +5 -2
- data/spec/logstash/config/source/multi_local_spec.rb +56 -10
- data/spec/logstash/config/source_loader_spec.rb +1 -1
- data/spec/logstash/config/string_escape_spec.rb +24 -0
- data/spec/logstash/event_spec.rb +9 -0
- data/spec/logstash/filters/base_spec.rb +1 -1
- data/spec/logstash/instrument/metric_store_spec.rb +2 -3
- data/spec/logstash/instrument/metric_type/counter_spec.rb +0 -12
- data/spec/logstash/instrument/metric_type/gauge_spec.rb +1 -8
- data/spec/logstash/instrument/periodic_poller/dlq_spec.rb +17 -0
- data/spec/logstash/instrument/periodic_poller/jvm_spec.rb +1 -1
- data/spec/logstash/legacy_ruby_event_spec.rb +0 -9
- data/spec/logstash/legacy_ruby_timestamp_spec.rb +19 -14
- data/spec/logstash/modules/cli_parser_spec.rb +129 -0
- data/spec/logstash/modules/logstash_config_spec.rb +56 -0
- data/spec/logstash/modules/scaffold_spec.rb +239 -0
- data/spec/logstash/pipeline_dlq_commit_spec.rb +1 -1
- data/spec/logstash/pipeline_spec.rb +87 -20
- data/spec/logstash/runner_spec.rb +122 -5
- data/spec/logstash/setting_spec.rb +2 -2
- data/spec/logstash/settings/splittable_string_array_spec.rb +51 -0
- data/spec/logstash/timestamp_spec.rb +8 -2
- data/spec/logstash/util/safe_uri_spec.rb +16 -0
- data/spec/logstash/util/wrapped_acked_queue_spec.rb +63 -0
- data/spec/logstash/util/wrapped_synchronous_queue_spec.rb +0 -22
- data/spec/support/helpers.rb +1 -1
- data/spec/support/matchers.rb +21 -4
- metadata +102 -19
- data/lib/logstash/instrument/metric_type/base.rb +0 -31
- data/lib/logstash/program.rb +0 -14
- data/lib/logstash/string_interpolation.rb +0 -18
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "spec_helper"
|
3
|
+
require "logstash/instrument/periodic_poller/dlq"
|
4
|
+
require "logstash/instrument/collector"
|
5
|
+
|
6
|
+
describe LogStash::Instrument::PeriodicPoller::DeadLetterQueue do
|
7
|
+
subject { LogStash::Instrument::PeriodicPoller::DeadLetterQueue }
|
8
|
+
|
9
|
+
let(:metric) { LogStash::Instrument::Metric.new(LogStash::Instrument::Collector.new) }
|
10
|
+
let(:agent) { double("agent")}
|
11
|
+
let(:options) { {} }
|
12
|
+
subject(:dlq) { described_class.new(metric, agent, options) }
|
13
|
+
|
14
|
+
it "should initialize cleanly" do
|
15
|
+
expect { dlq }.not_to raise_error
|
16
|
+
end
|
17
|
+
end
|
@@ -44,7 +44,7 @@ describe LogStash::Instrument::PeriodicPoller::JVM do
|
|
44
44
|
before do
|
45
45
|
expect(LogStash::Environment).to receive(:windows?).and_return(false)
|
46
46
|
expect(LogStash::Environment).to receive(:linux?).and_return(true)
|
47
|
-
expect(::File).to receive(:read).with("/proc/loadavg").and_raise("Didnt work out so well")
|
47
|
+
expect(::File).to receive(:read).with("/proc/loadavg").at_least(:once).and_raise("Didnt work out so well")
|
48
48
|
end
|
49
49
|
|
50
50
|
it "doesn't raise an exception" do
|
@@ -590,15 +590,6 @@ describe LogStash::Event do
|
|
590
590
|
describe "#to_s" do
|
591
591
|
let(:timestamp) { LogStash::Timestamp.new }
|
592
592
|
let(:event1) { LogStash::Event.new({ "@timestamp" => timestamp, "host" => "foo", "message" => "bar"}) }
|
593
|
-
let(:event2) { LogStash::Event.new({ "host" => "bar", "message" => "foo"}) }
|
594
|
-
|
595
|
-
it "should cache only one template" do
|
596
|
-
LogStash::StringInterpolation.clear_cache
|
597
|
-
expect {
|
598
|
-
event1.to_s
|
599
|
-
event2.to_s
|
600
|
-
}.to change { LogStash::StringInterpolation.cache_size }.by(1)
|
601
|
-
end
|
602
593
|
|
603
594
|
it "return the string containing the timestamp, the host and the message" do
|
604
595
|
expect(event1.to_s).to eq("#{timestamp.to_iso8601} #{event1.get("host")} #{event1.get("message")}")
|
@@ -4,7 +4,12 @@ require "logstash/timestamp"
|
|
4
4
|
require "bigdecimal"
|
5
5
|
|
6
6
|
describe LogStash::Timestamp do
|
7
|
-
|
7
|
+
# Via JRuby 9k time see logstash/issues/7463
|
8
|
+
# JRuby 9k now uses Java 8 Time with nanosecond precision but
|
9
|
+
# our Timestamp use Joda with millisecond precision
|
10
|
+
# expected: 10
|
11
|
+
# got: 9.999000001
|
12
|
+
# we may need to use `be_within(0.000999999).of()` in other places too
|
8
13
|
it "should parse its own iso8601 output" do
|
9
14
|
t = Time.now
|
10
15
|
ts = LogStash::Timestamp.new(t)
|
@@ -12,7 +17,7 @@ describe LogStash::Timestamp do
|
|
12
17
|
end
|
13
18
|
|
14
19
|
it "should coerce iso8601 string" do
|
15
|
-
t =
|
20
|
+
t = DateTime.now.to_time
|
16
21
|
ts = LogStash::Timestamp.new(t)
|
17
22
|
expect(LogStash::Timestamp.coerce(ts.to_iso8601).to_i).to eq(t.to_i)
|
18
23
|
end
|
@@ -44,7 +49,7 @@ describe LogStash::Timestamp do
|
|
44
49
|
end
|
45
50
|
|
46
51
|
it "should support timestamp comparison" do
|
47
|
-
current = LogStash::Timestamp.new(Time.now)
|
52
|
+
current = LogStash::Timestamp.new(Time.now)
|
48
53
|
future = LogStash::Timestamp.new(Time.now + 100)
|
49
54
|
|
50
55
|
expect(future > current).to eq(true)
|
@@ -57,29 +62,29 @@ describe LogStash::Timestamp do
|
|
57
62
|
end
|
58
63
|
|
59
64
|
it "should allow unary operation +" do
|
60
|
-
current =
|
65
|
+
current = DateTime.now.to_time
|
61
66
|
t = LogStash::Timestamp.new(current) + 10
|
62
|
-
expect(t).to
|
67
|
+
expect(t).to be_within(0.000999999).of(current + 10)
|
63
68
|
end
|
64
69
|
|
65
70
|
describe "subtraction" do
|
66
71
|
it "should work on a timestamp object" do
|
67
|
-
t =
|
72
|
+
t = DateTime.now.to_time
|
68
73
|
current = LogStash::Timestamp.new(t)
|
69
74
|
future = LogStash::Timestamp.new(t + 10)
|
70
|
-
expect(future - current).to
|
75
|
+
expect(future - current).to be_within(0.000999999).of(10)
|
71
76
|
end
|
72
77
|
|
73
78
|
it "should work on with time object" do
|
74
|
-
current =
|
79
|
+
current = DateTime.now.to_time
|
75
80
|
t = LogStash::Timestamp.new(current + 10)
|
76
|
-
expect(t - current).to
|
81
|
+
expect(t - current).to be_within(0.000999999).of(10)
|
77
82
|
end
|
78
83
|
|
79
84
|
it "should work with numeric value" do
|
80
|
-
current =
|
85
|
+
current = DateTime.now.to_time
|
81
86
|
t = LogStash::Timestamp.new(current + 10)
|
82
|
-
expect(t - 10).to
|
87
|
+
expect(t - 10).to be_within(0.000999999).of(current)
|
83
88
|
end
|
84
89
|
end
|
85
90
|
|
@@ -96,15 +101,15 @@ describe LogStash::Timestamp do
|
|
96
101
|
end
|
97
102
|
|
98
103
|
context "numeric casting methods" do
|
99
|
-
let
|
104
|
+
let(:now) { Time.now }
|
100
105
|
subject { LogStash::Timestamp.new(now) }
|
101
106
|
|
102
107
|
it "should support to_i" do
|
103
|
-
expect(subject.to_i).to
|
108
|
+
expect(subject.to_i).to be_kind_of(Integer)
|
104
109
|
end
|
105
110
|
|
106
111
|
it "should support to_f" do
|
107
|
-
expect(subject.to_f).to
|
112
|
+
expect(subject.to_f).to be_kind_of(Float)
|
108
113
|
end
|
109
114
|
end
|
110
115
|
|
@@ -0,0 +1,129 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "logstash/logging"
|
3
|
+
require "logstash/errors"
|
4
|
+
require "logstash/modules/cli_parser"
|
5
|
+
|
6
|
+
describe LogStash::Modules::CLIParser do
|
7
|
+
|
8
|
+
subject { LogStash::Modules::CLIParser.new(module_names, module_variables) }
|
9
|
+
let(:logger) { double("logger") }
|
10
|
+
let(:module_name) { "foo" }
|
11
|
+
let(:module_names) { [ module_name, "bar" ] }
|
12
|
+
let(:proto_key_value) { "var.input.stdin.type=example" }
|
13
|
+
let(:proto_mod_vars) { module_name + "." + proto_key_value }
|
14
|
+
let(:module_variables) { [ proto_mod_vars ] }
|
15
|
+
let(:expected_output) { { "name" => module_name, "var.input.stdin.type" => "example" } }
|
16
|
+
|
17
|
+
describe ".parse_modules" do
|
18
|
+
let(:module1) { "module1" }
|
19
|
+
let(:module2) { "module2" }
|
20
|
+
let(:csv_modules) { "#{module1},#{module2}" }
|
21
|
+
let(:list_with_csv) { [ module_name, csv_modules ] }
|
22
|
+
let(:post_parse) { [ module_name, module1, module2 ] }
|
23
|
+
|
24
|
+
context "when it receives an array without a csv entry" do
|
25
|
+
it "return the array unaltered" do
|
26
|
+
expect(subject.parse_modules(module_names)).to eq(module_names)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "when it receives an empty array" do
|
31
|
+
it "return an empty array" do
|
32
|
+
expect(subject.parse_modules([])).to eq([])
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "when it receives an array with a csv entry" do
|
37
|
+
it "return the original array with the csv values split into elements" do
|
38
|
+
expect(subject.parse_modules(list_with_csv)).to eq(post_parse)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "when it receives an array with a bad csv entry" do
|
43
|
+
let(:bad_modules) { [ "-Minvalid", module1 ] }
|
44
|
+
it "raise a LogStash::ConfigLoadingError exception" do
|
45
|
+
expect { subject.parse_modules(bad_modules) }.to raise_error LogStash::ConfigLoadingError
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "when it receives a nil value in an array" do
|
50
|
+
let(:array_with_nil) { list_with_csv << nil }
|
51
|
+
it "skip it" do
|
52
|
+
expect(subject.parse_modules(array_with_nil)).to eq(post_parse)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe ".get_kv" do
|
58
|
+
context "when it receives a valid string" do
|
59
|
+
let(:expected_key) { "var.input.stdin.type" }
|
60
|
+
let(:expected_value) { "example" }
|
61
|
+
let(:unparsed) { expected_key + "=" + expected_value }
|
62
|
+
it "split it into a key value pair" do
|
63
|
+
expect(subject.get_kv(module_name,unparsed)).to eq([expected_key,expected_value])
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context "when it receives an invalid string" do
|
68
|
+
let(:bad_example) { "var.fail" }
|
69
|
+
it "raise a LogStash::ConfigLoadingError exception" do
|
70
|
+
expect { subject.get_kv(module_name,bad_example) }.to raise_error LogStash::ConfigLoadingError
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe ".name_splitter" do
|
76
|
+
context "when it receives a valid string" do
|
77
|
+
let(:expected) { "var.input.stdin.type=example" }
|
78
|
+
it "split the module name from the rest of the string" do
|
79
|
+
expect(subject.name_splitter(proto_mod_vars)).to eq([module_name,expected])
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context "when it receives an invalid string" do
|
84
|
+
let(:bad_example) { "var.fail" }
|
85
|
+
it "raise a LogStash::ConfigLoadingError exception" do
|
86
|
+
expect { subject.name_splitter(bad_example) }.to raise_error LogStash::ConfigLoadingError
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe ".parse_vars" do
|
92
|
+
context "when it receives a vars_list with valid strings" do
|
93
|
+
it "return a hash with the module name and associated variables as key value pairs" do
|
94
|
+
expect(subject.parse_vars(module_name, module_variables)).to eq(expected_output)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context "when it receives a string that doesn't start with module_name" do
|
99
|
+
let(:has_unrelated) { module_variables << "bar.var.input.stdin.type=different" }
|
100
|
+
it "skips it" do
|
101
|
+
expect(subject.parse_vars(module_name, has_unrelated)).to eq(expected_output)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context "when it receives an empty vars_list" do
|
106
|
+
let(:name_only) { { "name" => module_name } }
|
107
|
+
it "return a hash with only 'name => module_name'" do
|
108
|
+
expect(subject.parse_vars(module_name, [])).to eq(name_only)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe ".parse_it" do
|
114
|
+
context "when it receives a valid module_list and module_variable_list" do
|
115
|
+
let(:module_names) { [ module_name ]}
|
116
|
+
it "@output is array of hashes with the module name and associated variables as key value pairs" do
|
117
|
+
expect(subject.output).to eq([expected_output])
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context "when it receives a non-array value for module_list" do
|
122
|
+
let(:module_names) { "string value" }
|
123
|
+
it "return an empty array" do
|
124
|
+
expect(subject.output).to eq([])
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/modules/logstash_config"
|
3
|
+
|
4
|
+
describe LogStash::Modules::LogStashConfig do
|
5
|
+
let(:mod) { instance_double("module", :directory => Stud::Temporary.directory, :module_name => "testing") }
|
6
|
+
let(:settings) { {"var.logstash.testing.pants" => "fancy" }}
|
7
|
+
subject { described_class.new(mod, settings) }
|
8
|
+
|
9
|
+
describe "configured inputs" do
|
10
|
+
context "when no inputs is send" do
|
11
|
+
it "returns the default" do
|
12
|
+
expect(subject.configured_inputs(["kafka"])).to include("kafka")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context "when inputs are send" do
|
17
|
+
let(:settings) { { "var.inputs" => "tcp" } }
|
18
|
+
|
19
|
+
it "returns the configured inputs" do
|
20
|
+
expect(subject.configured_inputs(["kafka"])).to include("tcp")
|
21
|
+
end
|
22
|
+
|
23
|
+
context "when alias is specified" do
|
24
|
+
let(:settings) { { "var.inputs" => "smartconnector" } }
|
25
|
+
|
26
|
+
it "returns the configured inputs" do
|
27
|
+
expect(subject.configured_inputs(["kafka"], { "smartconnector" => "tcp" })).to include("tcp", "smartconnector")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "array to logstash array string" do
|
34
|
+
it "return an escaped string" do
|
35
|
+
expect(subject.array_to_string(["hello", "ninja"])).to eq("['hello', 'ninja']")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "alias modules options" do
|
40
|
+
let(:alias_table) do
|
41
|
+
{ "var.logstash.testing" => "var.logstash.better" }
|
42
|
+
end
|
43
|
+
|
44
|
+
before do
|
45
|
+
subject.alias_settings_keys!(alias_table)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "allow to retrieve settings" do
|
49
|
+
expect(subject.setting("var.logstash.better.pants", "dont-exist")).to eq("fancy")
|
50
|
+
end
|
51
|
+
|
52
|
+
it "allow to retrieve settings with the original name" do
|
53
|
+
expect(subject.setting("var.logstash.testing.pants", "dont-exist")).to eq("fancy")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,239 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
require "logstash/namespace"
|
4
|
+
require "logstash/elasticsearch_client"
|
5
|
+
require "logstash/modules/kibana_client"
|
6
|
+
require "logstash/modules/kibana_config"
|
7
|
+
require "logstash/modules/scaffold"
|
8
|
+
require "logstash/modules/elasticsearch_importer"
|
9
|
+
require "logstash/modules/kibana_importer"
|
10
|
+
|
11
|
+
require_relative "../../support/helpers"
|
12
|
+
|
13
|
+
describe LogStash::Modules::Scaffold do
|
14
|
+
let(:base_dir) { "gem-home" }
|
15
|
+
let(:mname) { "foo" }
|
16
|
+
subject(:test_module) { described_class.new(mname, base_dir) }
|
17
|
+
let(:module_settings) do
|
18
|
+
{
|
19
|
+
"var.elasticsearch.hosts" => "es.mycloud.com:9200",
|
20
|
+
"var.elasticsearch.user" => "foo",
|
21
|
+
"var.elasticsearch.password" => "password",
|
22
|
+
"var.input.tcp.port" => 5606,
|
23
|
+
}
|
24
|
+
end
|
25
|
+
let(:dashboard_hash) do
|
26
|
+
{
|
27
|
+
"hits" => 0,
|
28
|
+
"timeRestore" => false,
|
29
|
+
"description" => "",
|
30
|
+
"title" => "Filebeat Apache2 Dashboard",
|
31
|
+
"uiStateJSON" => "{}",
|
32
|
+
"panelsJSON" => '[{"col":1,"id":"foo-c","panelIndex":1,"row":1,"size_x":12,"size_y":3,"type":"visualization"},{"id":"foo-d","type":"search","panelIndex":7,"size_x":12,"size_y":3,"col":1,"row":11,"columns":["apache2.error.client","apache2.error.level","apache2.error.module","apache2.error.message"],"sort":["@timestamp","desc"]}]',
|
33
|
+
"optionsJSON" => "{}",
|
34
|
+
"version" => 1,
|
35
|
+
"kibanaSavedObjectMeta" => {
|
36
|
+
"searchSourceJSON" => "{}"
|
37
|
+
}
|
38
|
+
}
|
39
|
+
end
|
40
|
+
let(:viz_hash) do
|
41
|
+
{
|
42
|
+
"visState" => "",
|
43
|
+
"description" => "",
|
44
|
+
"title" => "foo-c",
|
45
|
+
"uiStateJSON" => "",
|
46
|
+
"version" => 1,
|
47
|
+
"savedSearchId" => "foo-e",
|
48
|
+
"kibanaSavedObjectMeta" => {}
|
49
|
+
}
|
50
|
+
end
|
51
|
+
let(:index_pattern_hash) do
|
52
|
+
{
|
53
|
+
"title" => "foo-*",
|
54
|
+
"timeFieldName" =>"time",
|
55
|
+
"fieldFormatMap" => "{some map}",
|
56
|
+
"fields" => "[some array]"
|
57
|
+
}
|
58
|
+
end
|
59
|
+
context "logstash operation" do
|
60
|
+
let(:ls_conf) do
|
61
|
+
<<-ERB
|
62
|
+
input {
|
63
|
+
tcp {
|
64
|
+
port => <%= setting("var.input.tcp.port", 45) %>
|
65
|
+
host => <%= setting("var.input.tcp.host", "localhost") %>
|
66
|
+
type => <%= setting("var.input.tcp.type", "server") %>
|
67
|
+
}
|
68
|
+
}
|
69
|
+
filter {
|
70
|
+
|
71
|
+
}
|
72
|
+
output {
|
73
|
+
<%= elasticsearch_output_config() %>
|
74
|
+
}
|
75
|
+
ERB
|
76
|
+
end
|
77
|
+
|
78
|
+
before do
|
79
|
+
allow(LogStash::Modules::FileReader).to receive(:read).and_return(ls_conf)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "provides a logstash config" do
|
83
|
+
expect(test_module.logstash_configuration).to be_nil
|
84
|
+
test_module.with_settings(module_settings)
|
85
|
+
expect(test_module.logstash_configuration).not_to be_nil
|
86
|
+
config_string = test_module.config_string
|
87
|
+
expect(config_string).to include("port => 5606")
|
88
|
+
expect(config_string).to include("hosts => ['es.mycloud.com:9200']")
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context "elasticsearch operation" do
|
93
|
+
it "provides the elasticsearch mapping file paths" do
|
94
|
+
test_module.with_settings(module_settings)
|
95
|
+
expect(test_module.elasticsearch_configuration).not_to be_nil
|
96
|
+
files = test_module.elasticsearch_configuration.resources
|
97
|
+
expect(files.size).to eq(1)
|
98
|
+
expect(files.first).to be_a(LogStash::Modules::ElasticsearchResource)
|
99
|
+
expect(files.first.content_path).to eq("gem-home/elasticsearch/foo.json")
|
100
|
+
expect(files.first.import_path).to eq("_template/foo")
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context "kibana operation" do
|
105
|
+
before do
|
106
|
+
# allow(LogStash::Modules::FileReader).to receive(:read_json).and_return({})
|
107
|
+
allow(LogStash::Modules::FileReader).to receive(:read_json).with("gem-home/kibana/6.x/dashboard/foo.json").and_return(["Foo-Dashboard"])
|
108
|
+
allow(LogStash::Modules::FileReader).to receive(:read_json).with("gem-home/kibana/6.x/dashboard/Foo-Dashboard.json").and_return(dashboard_hash)
|
109
|
+
allow(LogStash::Modules::FileReader).to receive(:read_json).with("gem-home/kibana/6.x/visualization/foo-c.json").and_return(viz_hash)
|
110
|
+
allow(LogStash::Modules::FileReader).to receive(:read_json).with("gem-home/kibana/6.x/search/foo-d.json").and_return({"d" => "search"})
|
111
|
+
allow(LogStash::Modules::FileReader).to receive(:read_json).with("gem-home/kibana/6.x/search/foo-e.json").and_return({"e" => "search"})
|
112
|
+
allow(LogStash::Modules::FileReader).to receive(:read_json).with("gem-home/kibana/6.x/index-pattern/foo.json").and_return(index_pattern_hash)
|
113
|
+
end
|
114
|
+
|
115
|
+
it "provides a list of importable files" do
|
116
|
+
expect(test_module.kibana_configuration).to be_nil
|
117
|
+
test_module.with_settings(module_settings)
|
118
|
+
expect(test_module.kibana_configuration).not_to be_nil
|
119
|
+
resources = test_module.kibana_configuration.resources
|
120
|
+
expect(resources.size).to eq(2)
|
121
|
+
resource1 = resources[0]
|
122
|
+
resource2 = resources[1]
|
123
|
+
expect(resource1).to be_a(LogStash::Modules::KibanaSettings)
|
124
|
+
expect(resource2).to be_a(LogStash::Modules::KibanaDashboards)
|
125
|
+
expect(resource1.import_path).to eq("api/kibana/settings")
|
126
|
+
expect(resource1.content).to be_a(Array)
|
127
|
+
expect(resource1.content.size).to eq(2)
|
128
|
+
|
129
|
+
test_object = resource1.content[0]
|
130
|
+
expect(test_object).to be_a(LogStash::Modules::KibanaSettings::Setting)
|
131
|
+
expect(test_object.name).to eq("defaultIndex")
|
132
|
+
expect(test_object.value).to eq("foo-*")
|
133
|
+
|
134
|
+
test_object = resource1.content[1]
|
135
|
+
expect(test_object).to be_a(LogStash::Modules::KibanaSettings::Setting)
|
136
|
+
expect(test_object.name).to eq("metrics:max_buckets")
|
137
|
+
expect(test_object.value).to eq(86400)
|
138
|
+
|
139
|
+
expect(resource2.import_path).to eq("api/kibana/dashboards/import")
|
140
|
+
expect(resource2.content).to be_a(Array)
|
141
|
+
expect(resource2.content.size).to eq(5)
|
142
|
+
expect(resource2.content.map{|o| o.class}.uniq).to eq([LogStash::Modules::KibanaResource])
|
143
|
+
|
144
|
+
test_object = resource2.content[0]
|
145
|
+
expect(test_object.content_id).to eq("foo-*")
|
146
|
+
expect(test_object.content_type).to eq("index-pattern")
|
147
|
+
expect(test_object.content_as_object).to eq(index_pattern_hash)
|
148
|
+
|
149
|
+
test_object = resource2.content[1]
|
150
|
+
expect(test_object.content_id).to eq("Foo-Dashboard")
|
151
|
+
expect(test_object.content_type).to eq("dashboard")
|
152
|
+
expect(test_object.content_as_object).to eq(dashboard_hash)
|
153
|
+
|
154
|
+
test_object = resource2.content[2]
|
155
|
+
expect(test_object.content_id).to eq("foo-c") #<- the panels can contain items from other folders
|
156
|
+
expect(test_object.content_type).to eq("visualization")
|
157
|
+
expect(test_object.content_as_object).to eq(viz_hash)
|
158
|
+
expect(test_object.content_as_object["savedSearchId"]).to eq("foo-e")
|
159
|
+
|
160
|
+
test_object = resource2.content[3]
|
161
|
+
expect(test_object.content_id).to eq("foo-d") #<- the panels can contain items from other folders
|
162
|
+
expect(test_object.content_type).to eq("search")
|
163
|
+
expect(test_object.content_as_object).to eq("d"=>"search")
|
164
|
+
|
165
|
+
test_object = resource2.content[4]
|
166
|
+
expect(test_object.content_id).to eq("foo-e") # <- the visualization can contain items from the search folder
|
167
|
+
expect(test_object.content_type).to eq("search")
|
168
|
+
expect(test_object.content_as_object).to eq("e"=>"search")
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
context "importing to elasticsearch stubbed client" do
|
173
|
+
let(:mname) { "tester" }
|
174
|
+
let(:base_dir) { File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "modules_test_files", "modules", "#{mname}", "configuration")) }
|
175
|
+
let(:response) { double(:response) }
|
176
|
+
let(:client) { double(:client) }
|
177
|
+
let(:kbnclient) { double(:kbnclient) }
|
178
|
+
let(:paths) { [] }
|
179
|
+
let(:expected_paths) { ["_template/tester", "api/kibana/settings", "api/kibana/dashboards/import"] }
|
180
|
+
let(:contents) { [] }
|
181
|
+
let(:expected_objects) do
|
182
|
+
[
|
183
|
+
"index-pattern tester-*",
|
184
|
+
"dashboard FW-Dashboard",
|
185
|
+
"visualization FW-Viz-1",
|
186
|
+
"visualization FW-Viz-2",
|
187
|
+
"search Search-Tester"
|
188
|
+
]
|
189
|
+
end
|
190
|
+
|
191
|
+
before do
|
192
|
+
allow(response).to receive(:status).and_return(404)
|
193
|
+
allow(client).to receive(:head).and_return(response)
|
194
|
+
allow(kbnclient).to receive(:version).and_return("9.8.7-6")
|
195
|
+
end
|
196
|
+
|
197
|
+
it "calls the import method" do
|
198
|
+
expect(client).to receive(:put).once do |path, content|
|
199
|
+
paths << path
|
200
|
+
LogStash::ElasticsearchClient::Response.new(201, "", {})
|
201
|
+
end
|
202
|
+
expect(kbnclient).to receive(:post).twice do |path, content|
|
203
|
+
paths << path
|
204
|
+
contents << content
|
205
|
+
LogStash::Modules::KibanaClient::Response.new(201, "", {})
|
206
|
+
end
|
207
|
+
test_module.with_settings(module_settings)
|
208
|
+
test_module.import(LogStash::Modules::ElasticsearchImporter.new(client), LogStash::Modules::KibanaImporter.new(kbnclient))
|
209
|
+
expect(paths).to eq(expected_paths)
|
210
|
+
expect(contents[0]).to eq({"changes"=>{"defaultIndex"=>"tester-*", "metrics:max_buckets"=>"86400"}})
|
211
|
+
second_kbn_post = contents[1]
|
212
|
+
expect(second_kbn_post[:version]).to eq("9.8.7-6")
|
213
|
+
expect(second_kbn_post[:objects]).to be_a(Array)
|
214
|
+
expect(second_kbn_post[:objects].size).to eq(5)
|
215
|
+
objects_types_ids = second_kbn_post[:objects].map {|h| "#{h["type"]} #{h["id"]}"}
|
216
|
+
expect(objects_types_ids).to eq(expected_objects)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
context "import 4 realz", :skip => "integration" do
|
221
|
+
let(:mname) { "cef" }
|
222
|
+
let(:base_dir) { File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "modules_test_files", "#{mname}")) }
|
223
|
+
let(:module_settings) do
|
224
|
+
{
|
225
|
+
"var.elasticsearch.hosts" => "localhost:9200",
|
226
|
+
"var.elasticsearch.user" => "foo",
|
227
|
+
"var.elasticsearch.password" => "password",
|
228
|
+
"var.input.tcp.port" => 5606,
|
229
|
+
}
|
230
|
+
end
|
231
|
+
it "puts stuff in ES" do
|
232
|
+
test_module.with_settings(module_settings)
|
233
|
+
client = LogStash::ElasticsearchClient.build(module_settings)
|
234
|
+
import_engine = LogStash::Modules::Importer.new(client)
|
235
|
+
test_module.import(import_engine)
|
236
|
+
expect(1).to eq(1)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|