logstash-core 6.0.0.alpha2-java → 6.0.0.beta1-java
Sign up to get free protection for your applications and to get access to all the features.
- 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
|