logstash-core 5.6.16-java → 6.0.0.alpha1-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 +4 -4
- data/gemspec_jars.rb +4 -7
- data/lib/logstash-core/logstash-core.jar +0 -0
- data/lib/logstash-core/version.rb +4 -8
- data/lib/logstash-core_jars.rb +12 -26
- data/lib/logstash/agent.rb +261 -246
- data/lib/logstash/api/commands/default_metadata.rb +1 -1
- data/lib/logstash/api/commands/hot_threads_reporter.rb +5 -11
- data/lib/logstash/api/commands/node.rb +3 -2
- data/lib/logstash/api/commands/stats.rb +3 -2
- data/lib/logstash/bootstrap_check/bad_java.rb +16 -0
- data/lib/logstash/bootstrap_check/bad_ruby.rb +12 -0
- data/lib/logstash/bootstrap_check/default_config.rb +17 -0
- data/lib/logstash/compiler.rb +38 -0
- data/lib/logstash/compiler/lscl.rb +566 -0
- data/lib/logstash/compiler/lscl/lscl_grammar.rb +3503 -0
- data/lib/logstash/compiler/treetop_monkeypatches.rb +92 -0
- data/lib/logstash/config/config_ast.rb +4 -82
- data/lib/logstash/config/mixin.rb +73 -41
- data/lib/logstash/config/pipeline_config.rb +48 -0
- data/lib/logstash/config/source/base.rb +16 -0
- data/lib/logstash/config/source/local.rb +215 -0
- data/lib/logstash/config/source_loader.rb +125 -0
- data/lib/logstash/converge_result.rb +103 -0
- data/lib/logstash/environment.rb +6 -19
- data/lib/logstash/errors.rb +2 -0
- data/lib/logstash/execution_context.rb +4 -7
- data/lib/logstash/filter_delegator.rb +6 -9
- data/lib/logstash/inputs/base.rb +0 -2
- data/lib/logstash/instrument/collector.rb +5 -7
- data/lib/logstash/instrument/metric_store.rb +12 -12
- data/lib/logstash/instrument/metric_type/mean.rb +0 -5
- data/lib/logstash/instrument/namespaced_metric.rb +0 -4
- data/lib/logstash/instrument/namespaced_null_metric.rb +0 -4
- data/lib/logstash/instrument/null_metric.rb +0 -10
- data/lib/logstash/instrument/periodic_poller/cgroup.rb +85 -168
- data/lib/logstash/instrument/periodic_poller/jvm.rb +5 -5
- data/lib/logstash/instrument/periodic_poller/pq.rb +3 -7
- data/lib/logstash/instrument/periodic_pollers.rb +1 -3
- data/lib/logstash/instrument/wrapped_write_client.rb +24 -33
- data/lib/logstash/logging/logger.rb +15 -47
- data/lib/logstash/namespace.rb +0 -1
- data/lib/logstash/output_delegator.rb +5 -7
- data/lib/logstash/outputs/base.rb +0 -2
- data/lib/logstash/pipeline.rb +159 -87
- data/lib/logstash/pipeline_action.rb +13 -0
- data/lib/logstash/pipeline_action/base.rb +29 -0
- data/lib/logstash/pipeline_action/create.rb +47 -0
- data/lib/logstash/pipeline_action/reload.rb +48 -0
- data/lib/logstash/pipeline_action/stop.rb +23 -0
- data/lib/logstash/plugin.rb +0 -1
- data/lib/logstash/plugins/hooks_registry.rb +6 -0
- data/lib/logstash/plugins/registry.rb +0 -1
- data/lib/logstash/program.rb +14 -0
- data/lib/logstash/queue_factory.rb +5 -1
- data/lib/logstash/runner.rb +58 -80
- data/lib/logstash/settings.rb +3 -27
- data/lib/logstash/state_resolver.rb +41 -0
- data/lib/logstash/util/java_version.rb +6 -0
- data/lib/logstash/util/safe_uri.rb +12 -148
- data/lib/logstash/util/thread_dump.rb +4 -7
- data/lib/logstash/util/wrapped_acked_queue.rb +36 -39
- data/lib/logstash/util/wrapped_synchronous_queue.rb +29 -39
- data/lib/logstash/version.rb +10 -8
- data/locales/en.yml +3 -54
- data/logstash-core.gemspec +8 -35
- data/spec/{logstash/api/modules → api/lib/api}/logging_spec.rb +10 -1
- data/spec/{logstash/api/modules → api/lib/api}/node_plugins_spec.rb +2 -1
- data/spec/{logstash/api/modules → api/lib/api}/node_spec.rb +3 -3
- data/spec/{logstash/api/modules → api/lib/api}/node_stats_spec.rb +3 -7
- data/spec/{logstash/api/modules → api/lib/api}/plugins_spec.rb +3 -4
- data/spec/{logstash/api/modules → api/lib/api}/root_spec.rb +2 -2
- data/spec/api/lib/api/support/resource_dsl_methods.rb +87 -0
- data/spec/{logstash/api/commands/stats_spec.rb → api/lib/commands/stats.rb} +2 -7
- data/spec/{logstash/api → api/lib}/errors_spec.rb +1 -1
- data/spec/{logstash/api → api/lib}/rack_app_spec.rb +0 -0
- data/spec/api/spec_helper.rb +106 -0
- data/spec/logstash/agent/converge_spec.rb +286 -0
- data/spec/logstash/agent/metrics_spec.rb +244 -0
- data/spec/logstash/agent_spec.rb +213 -225
- data/spec/logstash/compiler/compiler_spec.rb +584 -0
- data/spec/logstash/config/config_ast_spec.rb +8 -47
- data/spec/logstash/config/mixin_spec.rb +2 -42
- data/spec/logstash/config/pipeline_config_spec.rb +75 -0
- data/spec/logstash/config/source/local_spec.rb +395 -0
- data/spec/logstash/config/source_loader_spec.rb +122 -0
- data/spec/logstash/converge_result_spec.rb +179 -0
- data/spec/logstash/event_spec.rb +0 -66
- data/spec/logstash/execution_context_spec.rb +8 -12
- data/spec/logstash/filter_delegator_spec.rb +12 -24
- data/spec/logstash/inputs/base_spec.rb +7 -5
- data/spec/logstash/instrument/periodic_poller/cgroup_spec.rb +92 -225
- data/spec/logstash/instrument/periodic_poller/jvm_spec.rb +1 -1
- data/spec/logstash/instrument/periodic_poller/os_spec.rb +32 -29
- data/spec/logstash/instrument/wrapped_write_client_spec.rb +33 -33
- data/spec/logstash/legacy_ruby_event_spec.rb +13 -4
- data/spec/logstash/output_delegator_spec.rb +11 -20
- data/spec/logstash/outputs/base_spec.rb +7 -5
- data/spec/logstash/pipeline_action/create_spec.rb +83 -0
- data/spec/logstash/pipeline_action/reload_spec.rb +83 -0
- data/spec/logstash/pipeline_action/stop_spec.rb +37 -0
- data/spec/logstash/pipeline_pq_file_spec.rb +1 -1
- data/spec/logstash/pipeline_spec.rb +81 -137
- data/spec/logstash/plugin_spec.rb +2 -1
- data/spec/logstash/plugins/hooks_registry_spec.rb +6 -0
- data/spec/logstash/queue_factory_spec.rb +13 -1
- data/spec/logstash/runner_spec.rb +29 -140
- data/spec/logstash/settings/writable_directory_spec.rb +10 -13
- data/spec/logstash/settings_spec.rb +0 -91
- data/spec/logstash/state_resolver_spec.rb +156 -0
- data/spec/logstash/timestamp_spec.rb +2 -6
- data/spec/logstash/util/java_version_spec.rb +22 -0
- data/spec/logstash/util/safe_uri_spec.rb +0 -56
- data/spec/logstash/util/wrapped_synchronous_queue_spec.rb +22 -0
- data/spec/support/helpers.rb +9 -11
- data/spec/support/matchers.rb +96 -6
- data/spec/support/mocks_classes.rb +80 -0
- data/spec/support/shared_contexts.rb +2 -27
- metadata +100 -149
- data/lib/logstash/config/loader.rb +0 -107
- data/lib/logstash/config/modules_common.rb +0 -103
- data/lib/logstash/config/source/modules.rb +0 -55
- data/lib/logstash/config/string_escape.rb +0 -27
- data/lib/logstash/dependency_report.rb +0 -131
- data/lib/logstash/dependency_report_runner.rb +0 -17
- data/lib/logstash/elasticsearch_client.rb +0 -142
- data/lib/logstash/instrument/global_metrics.rb +0 -13
- data/lib/logstash/instrument/periodic_poller/dlq.rb +0 -24
- data/lib/logstash/modules/cli_parser.rb +0 -74
- data/lib/logstash/modules/elasticsearch_config.rb +0 -22
- data/lib/logstash/modules/elasticsearch_importer.rb +0 -37
- data/lib/logstash/modules/elasticsearch_resource.rb +0 -10
- data/lib/logstash/modules/file_reader.rb +0 -36
- data/lib/logstash/modules/kibana_base.rb +0 -24
- data/lib/logstash/modules/kibana_client.rb +0 -124
- data/lib/logstash/modules/kibana_config.rb +0 -105
- data/lib/logstash/modules/kibana_dashboards.rb +0 -36
- data/lib/logstash/modules/kibana_importer.rb +0 -17
- data/lib/logstash/modules/kibana_resource.rb +0 -10
- data/lib/logstash/modules/kibana_settings.rb +0 -40
- data/lib/logstash/modules/logstash_config.rb +0 -120
- data/lib/logstash/modules/resource_base.rb +0 -38
- data/lib/logstash/modules/scaffold.rb +0 -52
- data/lib/logstash/modules/settings_merger.rb +0 -23
- data/lib/logstash/modules/util.rb +0 -17
- data/lib/logstash/util/dead_letter_queue_manager.rb +0 -61
- data/lib/logstash/util/environment_variables.rb +0 -43
- data/spec/logstash/config/loader_spec.rb +0 -38
- data/spec/logstash/config/string_escape_spec.rb +0 -24
- data/spec/logstash/instrument/periodic_poller/dlq_spec.rb +0 -17
- data/spec/logstash/modules/logstash_config_spec.rb +0 -56
- data/spec/logstash/modules/scaffold_spec.rb +0 -234
- data/spec/logstash/pipeline_dlq_commit_spec.rb +0 -109
- data/spec/logstash/settings/splittable_string_array_spec.rb +0 -51
- data/spec/logstash/util/wrapped_acked_queue_spec.rb +0 -49
- data/versions-gem-copy.yml +0 -12
@@ -6,8 +6,6 @@ require "logstash/config/grammar"
|
|
6
6
|
require "logstash/config/config_ast"
|
7
7
|
|
8
8
|
describe LogStashConfigParser do
|
9
|
-
let(:settings) { mock_settings({}) }
|
10
|
-
|
11
9
|
context '#parse' do
|
12
10
|
context "valid configuration" do
|
13
11
|
it "should permit single-quoted attribute names" do
|
@@ -79,7 +77,7 @@ describe LogStashConfigParser do
|
|
79
77
|
}
|
80
78
|
CONFIG
|
81
79
|
subject { LogStashConfigParser.new }
|
82
|
-
|
80
|
+
|
83
81
|
it "should compile successfully" do
|
84
82
|
result = subject.parse(config)
|
85
83
|
expect(result).not_to(be_nil)
|
@@ -144,50 +142,12 @@ describe LogStashConfigParser do
|
|
144
142
|
expect(config).to be_nil
|
145
143
|
end
|
146
144
|
end
|
147
|
-
|
148
|
-
context "when config.support_escapes" do
|
149
|
-
let(:parser) { LogStashConfigParser.new }
|
150
|
-
|
151
|
-
let(:processed_value) { 'The computer says, "No"' }
|
152
|
-
|
153
|
-
let(:config) {
|
154
|
-
parser.parse(%q(
|
155
|
-
input {
|
156
|
-
foo {
|
157
|
-
bar => "The computer says, \"No\""
|
158
|
-
}
|
159
|
-
}
|
160
|
-
))
|
161
|
-
}
|
162
|
-
|
163
|
-
let(:compiled_string) { eval(config.recursive_select(LogStash::Config::AST::String).first.compile) }
|
164
|
-
|
165
|
-
before do
|
166
|
-
config.process_escape_sequences = escapes
|
167
|
-
end
|
168
|
-
|
169
|
-
context "is enabled" do
|
170
|
-
let(:escapes) { true }
|
171
|
-
|
172
|
-
it "should process escape sequences" do
|
173
|
-
expect(compiled_string).to be == processed_value
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
context "is false" do
|
178
|
-
let(:escapes) { false }
|
179
|
-
|
180
|
-
it "should not process escape sequences" do
|
181
|
-
expect(compiled_string).not_to be == processed_value
|
182
|
-
end
|
183
|
-
end
|
184
|
-
end
|
185
145
|
end
|
186
146
|
|
187
147
|
context "when using two plugin sections of the same type" do
|
188
148
|
let(:pipeline_klass) do
|
189
149
|
Class.new do
|
190
|
-
def initialize(config
|
150
|
+
def initialize(config)
|
191
151
|
grammar = LogStashConfigParser.new
|
192
152
|
@config = grammar.parse(config)
|
193
153
|
@code = @config.compile
|
@@ -206,7 +166,7 @@ describe LogStashConfigParser do
|
|
206
166
|
|
207
167
|
|
208
168
|
it "should create a pipeline with both sections" do
|
209
|
-
generated_objects = pipeline_klass.new(config_string
|
169
|
+
generated_objects = pipeline_klass.new(config_string).instance_variable_get("@generated_objects")
|
210
170
|
filters = generated_objects.keys.map(&:to_s).select {|obj_name| obj_name.match(/^filter.+?_\d+$/) }
|
211
171
|
expect(filters.size).to eq(2)
|
212
172
|
end
|
@@ -221,13 +181,14 @@ describe LogStashConfigParser do
|
|
221
181
|
|
222
182
|
|
223
183
|
it "should create a pipeline with both sections" do
|
224
|
-
generated_objects = pipeline_klass.new(config_string
|
184
|
+
generated_objects = pipeline_klass.new(config_string).instance_variable_get("@generated_objects")
|
225
185
|
outputs = generated_objects.keys.map(&:to_s).select {|obj_name| obj_name.match(/^output.+?_\d+$/) }
|
226
186
|
expect(outputs.size).to eq(2)
|
227
187
|
end
|
228
188
|
end
|
229
189
|
end
|
230
190
|
context "when creating two instances of the same configuration" do
|
191
|
+
|
231
192
|
let(:config_string) {
|
232
193
|
"input { generator { } }
|
233
194
|
filter {
|
@@ -240,7 +201,7 @@ describe LogStashConfigParser do
|
|
240
201
|
|
241
202
|
let(:pipeline_klass) do
|
242
203
|
Class.new do
|
243
|
-
def initialize(config
|
204
|
+
def initialize(config)
|
244
205
|
grammar = LogStashConfigParser.new
|
245
206
|
@config = grammar.parse(config)
|
246
207
|
@code = @config.compile
|
@@ -252,8 +213,8 @@ describe LogStashConfigParser do
|
|
252
213
|
|
253
214
|
describe "generated conditional functionals" do
|
254
215
|
it "should be created per instance" do
|
255
|
-
instance_1 = pipeline_klass.new(config_string
|
256
|
-
instance_2 = pipeline_klass.new(config_string
|
216
|
+
instance_1 = pipeline_klass.new(config_string)
|
217
|
+
instance_2 = pipeline_klass.new(config_string)
|
257
218
|
generated_method_1 = instance_1.instance_variable_get("@generated_objects")[:cond_func_1]
|
258
219
|
generated_method_2 = instance_2.instance_variable_get("@generated_objects")[:cond_func_1]
|
259
220
|
expect(generated_method_1).to_not be(generated_method_2)
|
@@ -3,34 +3,6 @@ require "spec_helper"
|
|
3
3
|
require "logstash/config/mixin"
|
4
4
|
|
5
5
|
describe LogStash::Config::Mixin do
|
6
|
-
context "when encountering a deprecated option" do
|
7
|
-
let(:password) { "sekret" }
|
8
|
-
let(:double_logger) { double("logger").as_null_object }
|
9
|
-
|
10
|
-
subject do
|
11
|
-
Class.new(LogStash::Filters::Base) do
|
12
|
-
include LogStash::Config::Mixin
|
13
|
-
config_name "test_deprecated"
|
14
|
-
milestone 1
|
15
|
-
config :old_opt, :validate => :string, :deprecated => "this is old school"
|
16
|
-
config :password, :validate => :password
|
17
|
-
end.new({
|
18
|
-
"old_opt" => "whut",
|
19
|
-
"password" => password
|
20
|
-
})
|
21
|
-
end
|
22
|
-
|
23
|
-
it "should not log the password" do
|
24
|
-
expect(LogStash::Logging::Logger).to receive(:new).with(anything).and_return(double_logger)
|
25
|
-
expect(double_logger).to receive(:warn) do |arg1,arg2|
|
26
|
-
message = 'You are using a deprecated config setting "old_opt" set in test_deprecated. Deprecated settings will continue to work, but are scheduled for removal from logstash in the future. this is old school If you have any questions about this, please visit the #logstash channel on freenode irc.'
|
27
|
-
expect(arg1).to eq(message)
|
28
|
-
expect(arg2[:plugin].to_s).to include('"password"=><password>')
|
29
|
-
end.once
|
30
|
-
subject
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
6
|
context "when validating :bytes successfully" do
|
35
7
|
subject do
|
36
8
|
local_num_bytes = num_bytes # needs to be locally scoped :(
|
@@ -220,8 +192,8 @@ describe LogStash::Config::Mixin do
|
|
220
192
|
expect(clone.uri.to_s).to eql(uri_hidden)
|
221
193
|
end
|
222
194
|
|
223
|
-
it "should make the real
|
224
|
-
expect(subject.uri.uri).to be_a(
|
195
|
+
it "should make the real URI object available under #uri" do
|
196
|
+
expect(subject.uri.uri).to be_a(::URI)
|
225
197
|
end
|
226
198
|
|
227
199
|
it "should obfuscate original_params" do
|
@@ -397,13 +369,11 @@ describe LogStash::Config::Mixin do
|
|
397
369
|
before do
|
398
370
|
ENV["FunString"] = "fancy"
|
399
371
|
ENV["FunBool"] = "true"
|
400
|
-
ENV["SERVER_LS_TEST_ADDRESS"] = "some.host.address.tld"
|
401
372
|
end
|
402
373
|
|
403
374
|
after do
|
404
375
|
ENV.delete("FunString")
|
405
376
|
ENV.delete("FunBool")
|
406
|
-
ENV.delete("SERVER_LS_TEST_ADDRESS")
|
407
377
|
end
|
408
378
|
|
409
379
|
subject do
|
@@ -427,16 +397,6 @@ describe LogStash::Config::Mixin do
|
|
427
397
|
expect(subject.nestedArray).to(be == { "level1" => [{ "key1" => "http://fancy:8080/blah.txt" }, { "key2" => "http://fancy:8080/foo.txt" }] })
|
428
398
|
expect(subject.deepHash).to(be == { "level1" => { "level2" => { "level3" => { "key1" => "http://fancy:8080/blah.txt" } } } })
|
429
399
|
end
|
430
|
-
|
431
|
-
it "should validate settings after interpolating ENV variables" do
|
432
|
-
expect {
|
433
|
-
Class.new(LogStash::Filters::Base) do
|
434
|
-
include LogStash::Config::Mixin
|
435
|
-
config_name "test"
|
436
|
-
config :server_address, :validate => :uri
|
437
|
-
end.new({"server_address" => "${SERVER_LS_TEST_ADDRESS}"})
|
438
|
-
}.not_to raise_error
|
439
|
-
end
|
440
400
|
end
|
441
401
|
|
442
402
|
context "should support $ in values" do
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/config/pipeline_config"
|
3
|
+
require "logstash/config/source/local"
|
4
|
+
|
5
|
+
describe LogStash::Config::PipelineConfig do
|
6
|
+
let(:source) { LogStash::Config::Source::Local }
|
7
|
+
let(:pipeline_id) { :main }
|
8
|
+
let(:ordered_config_parts) do
|
9
|
+
[
|
10
|
+
org.logstash.common.SourceWithMetadata.new("file", "/tmp/1", "input { generator1 }"),
|
11
|
+
org.logstash.common.SourceWithMetadata.new("file", "/tmp/2", "input { generator2 }"),
|
12
|
+
org.logstash.common.SourceWithMetadata.new("file", "/tmp/3", "input { generator3 }"),
|
13
|
+
org.logstash.common.SourceWithMetadata.new("file", "/tmp/4", "input { generator4 }"),
|
14
|
+
org.logstash.common.SourceWithMetadata.new("file", "/tmp/5", "input { generator5 }"),
|
15
|
+
org.logstash.common.SourceWithMetadata.new("file", "/tmp/6", "input { generator6 }"),
|
16
|
+
org.logstash.common.SourceWithMetadata.new("string", "config_string", "input { generator1 }"),
|
17
|
+
]
|
18
|
+
end
|
19
|
+
|
20
|
+
let(:unordered_config_parts) { ordered_config_parts.shuffle }
|
21
|
+
let(:settings) { LogStash::SETTINGS }
|
22
|
+
|
23
|
+
subject { described_class.new(source, pipeline_id, unordered_config_parts, settings) }
|
24
|
+
|
25
|
+
it "returns the source" do
|
26
|
+
expect(subject.source).to eq(source)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "returns the pipeline id" do
|
30
|
+
expect(subject.pipeline_id).to eq(pipeline_id)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "returns the sorted config parts" do
|
34
|
+
expect(subject.config_parts).to eq(ordered_config_parts)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "returns the config_hash" do
|
38
|
+
expect(subject.config_hash).not_to be_nil
|
39
|
+
end
|
40
|
+
|
41
|
+
it "returns the merged `ConfigPart#config_string`" do
|
42
|
+
expect(subject.config_string).to eq(ordered_config_parts.collect(&:text).join("\n"))
|
43
|
+
end
|
44
|
+
|
45
|
+
it "records when the config was read" do
|
46
|
+
expect(subject.read_at).to be <= Time.now
|
47
|
+
end
|
48
|
+
|
49
|
+
it "does object equality on config_hash and pipeline_id" do
|
50
|
+
another_exact_pipeline = described_class.new(source, pipeline_id, ordered_config_parts, settings)
|
51
|
+
expect(subject).to eq(another_exact_pipeline)
|
52
|
+
|
53
|
+
not_matching_pipeline = described_class.new(source, pipeline_id, [], settings)
|
54
|
+
expect(subject).not_to eq(not_matching_pipeline)
|
55
|
+
|
56
|
+
not_same_pipeline_id = described_class.new(source, :another_pipeline, unordered_config_parts, settings)
|
57
|
+
expect(subject).not_to eq(not_same_pipeline_id)
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "#system?" do
|
61
|
+
context "when the pipeline is a system pipeline" do
|
62
|
+
let(:settings) { mock_settings({ "pipeline.system" => true })}
|
63
|
+
|
64
|
+
it "returns true if the pipeline is a system pipeline" do
|
65
|
+
expect(subject.system?).to be_truthy
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "when is not a system pipeline" do
|
70
|
+
it "returns false if the pipeline is not a system pipeline" do
|
71
|
+
expect(subject.system?).to be_falsey
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,395 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/config/source/local"
|
3
|
+
require "rspec/expectations"
|
4
|
+
require "stud/temporary"
|
5
|
+
require "fileutils"
|
6
|
+
require "pathname"
|
7
|
+
require_relative "../../../support/helpers"
|
8
|
+
require_relative "../../../support/matchers"
|
9
|
+
require "spec_helper"
|
10
|
+
require "webmock/rspec"
|
11
|
+
|
12
|
+
describe LogStash::Config::Source::Local::ConfigStringLoader do
|
13
|
+
subject { described_class }
|
14
|
+
let(:config_string) { "input { generator {} } output { stdout {} }"}
|
15
|
+
|
16
|
+
it "returns one config_parts" do
|
17
|
+
expect(subject.read(config_string).size).to eq(1)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "returns a valid config part" do
|
21
|
+
config_part = subject.read(config_string).first
|
22
|
+
expect(config_part).to be_a_source_with_metadata("string", "config_string", config_string)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe LogStash::Config::Source::Local::ConfigPathLoader do
|
27
|
+
subject { described_class }
|
28
|
+
|
29
|
+
context "no configs" do
|
30
|
+
context "in the directory" do
|
31
|
+
let(:directory) do
|
32
|
+
p = Stud::Temporary.pathname
|
33
|
+
FileUtils.mkdir_p(p)
|
34
|
+
p
|
35
|
+
end
|
36
|
+
|
37
|
+
it "returns an empty array" do
|
38
|
+
expect(subject.read(directory)).to be_empty
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "target file doesn't exist" do
|
43
|
+
let(:directory) do
|
44
|
+
p = Stud::Temporary.pathname
|
45
|
+
FileUtils.mkdir_p(p)
|
46
|
+
::File.join(p, "ls.conf")
|
47
|
+
end
|
48
|
+
|
49
|
+
it "returns an empty array" do
|
50
|
+
expect(subject.read(directory)).to be_empty
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context "when it exist" do
|
56
|
+
shared_examples "read config from files" do
|
57
|
+
let(:directory) { Stud::Temporary.pathname }
|
58
|
+
|
59
|
+
before do
|
60
|
+
files.each do |file, content|
|
61
|
+
temporary_file(content, file, directory)
|
62
|
+
end
|
63
|
+
|
64
|
+
expect(files.size).to be >= 1
|
65
|
+
expect(Dir.glob(::File.join(directory, "*")).size).to eq(files.size)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "returns a `config_parts` per file" do
|
69
|
+
expect(subject.read(reader_config).size).to eq(files.size)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "returns alphabetically sorted parts" do
|
73
|
+
parts = subject.read(reader_config)
|
74
|
+
expect(parts.collect { |part| ::File.basename(part.id) }).to eq(files.keys.sort)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "returns valid `config_parts`" do
|
78
|
+
parts = subject.read(reader_config)
|
79
|
+
|
80
|
+
parts.each do |part|
|
81
|
+
basename = ::File.basename(part.id)
|
82
|
+
file_path = ::File.join(directory, basename)
|
83
|
+
content = files[basename]
|
84
|
+
expect(part).to be_a_source_with_metadata("file", file_path, content)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context "when the files have invalid encoding" do
|
90
|
+
let(:config_string) { "\x80" }
|
91
|
+
let(:file_path) { Stud::Temporary.pathname }
|
92
|
+
let(:file) { ::File.join(file_path, "wrong_encoding.conf") }
|
93
|
+
|
94
|
+
before do
|
95
|
+
FileUtils.mkdir_p(file_path)
|
96
|
+
f = File.open(file, "wb") do |file|
|
97
|
+
file.write(config_string)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
it "raises an exception" do
|
102
|
+
expect { subject.read(file_path) }.to raise_error LogStash::ConfigLoadingError, /#{file_path}/
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context "when we target one file" do
|
107
|
+
let(:reader_config) { ::File.join(directory, files.keys.first) }
|
108
|
+
let(:files) {
|
109
|
+
{
|
110
|
+
"config1.conf" => "input1",
|
111
|
+
}
|
112
|
+
}
|
113
|
+
|
114
|
+
include_examples "read config from files"
|
115
|
+
end
|
116
|
+
|
117
|
+
context "when we target a path with multiples files" do
|
118
|
+
let(:reader_config) { directory }
|
119
|
+
|
120
|
+
let(:files) {
|
121
|
+
{
|
122
|
+
"config1.conf" => "input1",
|
123
|
+
"config2.conf" => "input2",
|
124
|
+
"config3.conf" => "input3",
|
125
|
+
"config4.conf" => "input4"
|
126
|
+
}
|
127
|
+
}
|
128
|
+
|
129
|
+
include_examples "read config from files"
|
130
|
+
end
|
131
|
+
|
132
|
+
context "when there temporary files in the directory" do
|
133
|
+
let(:reader_config) { ::File.join(directory, "conf*.conf") }
|
134
|
+
|
135
|
+
let(:files) {
|
136
|
+
{
|
137
|
+
"config1.conf" => "input1",
|
138
|
+
"config2.conf" => "input2",
|
139
|
+
"config3.conf" => "input3",
|
140
|
+
"config4.conf" => "input4"
|
141
|
+
}
|
142
|
+
}
|
143
|
+
|
144
|
+
let(:other_files) do
|
145
|
+
{
|
146
|
+
"config1.conf~" => "input1",
|
147
|
+
"config2.conf~" => "input2",
|
148
|
+
"config3.conf~" => "input3",
|
149
|
+
"config4.conf~" => "input4"
|
150
|
+
}
|
151
|
+
end
|
152
|
+
|
153
|
+
include_examples "read config from files" do
|
154
|
+
before do
|
155
|
+
other_files.keys.shuffle.each do |file|
|
156
|
+
content = files[file]
|
157
|
+
temporary_file(content, file, directory)
|
158
|
+
end
|
159
|
+
|
160
|
+
# make sure we actually do some filtering
|
161
|
+
expect(Dir.glob(::File.join(directory, "*")).size).to eq(other_files.size + files.size)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
context "when the path is a wildcard" do
|
167
|
+
let(:reader_config) { ::File.join(directory, "conf*.conf") }
|
168
|
+
|
169
|
+
let(:files) {
|
170
|
+
{
|
171
|
+
"config1.conf" => "input1",
|
172
|
+
"config2.conf" => "input2",
|
173
|
+
"config3.conf" => "input3",
|
174
|
+
"config4.conf" => "input4"
|
175
|
+
}
|
176
|
+
}
|
177
|
+
|
178
|
+
let(:other_files) do
|
179
|
+
{
|
180
|
+
"bad1.conf" => "input1",
|
181
|
+
"bad2.conf" => "input2",
|
182
|
+
"bad3.conf" => "input3",
|
183
|
+
"bad4.conf" => "input4"
|
184
|
+
}
|
185
|
+
end
|
186
|
+
|
187
|
+
include_examples "read config from files" do
|
188
|
+
before do
|
189
|
+
other_files.keys.shuffle.each do |file|
|
190
|
+
content = files[file]
|
191
|
+
temporary_file(content, file, directory)
|
192
|
+
end
|
193
|
+
|
194
|
+
# make sure we actually do some filtering
|
195
|
+
expect(Dir.glob(::File.join(directory, "*")).size).to eq(other_files.size + files.size)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
context "URI defined path (file://..)" do
|
201
|
+
let(:reader_config) { "file://#{::File.join(directory, files.keys.first)}" }
|
202
|
+
let(:files) {
|
203
|
+
{
|
204
|
+
"config1.conf" => "input1",
|
205
|
+
}
|
206
|
+
}
|
207
|
+
|
208
|
+
include_examples "read config from files"
|
209
|
+
end
|
210
|
+
|
211
|
+
context "relative path" do
|
212
|
+
let(:reader_config) do
|
213
|
+
FileUtils.mkdir_p(::File.join(directory, "inside"))
|
214
|
+
::File.join(directory, "inside", "../")
|
215
|
+
end
|
216
|
+
|
217
|
+
let(:files) {
|
218
|
+
{
|
219
|
+
"config2.conf" => "input1",
|
220
|
+
"config1.conf" => "input2",
|
221
|
+
}
|
222
|
+
}
|
223
|
+
|
224
|
+
include_examples "read config from files"
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
describe LogStash::Config::Source::Local::ConfigRemoteLoader do
|
230
|
+
before :all do
|
231
|
+
WebMock.disable_net_connect!
|
232
|
+
end
|
233
|
+
|
234
|
+
after :all do
|
235
|
+
WebMock.allow_net_connect!
|
236
|
+
end
|
237
|
+
|
238
|
+
subject { described_class }
|
239
|
+
|
240
|
+
let(:remote_url) { "http://test.dev/superconfig.conf" }
|
241
|
+
|
242
|
+
context "when the remote configuration exist" do
|
243
|
+
let(:config_string) { "input { generator {} } output { stdout {} }"}
|
244
|
+
|
245
|
+
before do
|
246
|
+
stub_request(:get, remote_url)
|
247
|
+
.to_return({
|
248
|
+
:body => config_string,
|
249
|
+
:status => 200
|
250
|
+
})
|
251
|
+
end
|
252
|
+
|
253
|
+
it "returns one config_parts" do
|
254
|
+
expect(subject.read(remote_url).size).to eq(1)
|
255
|
+
end
|
256
|
+
|
257
|
+
it "returns a valid config part" do
|
258
|
+
config_part = subject.read(remote_url).first
|
259
|
+
expect(config_part).to be_a_source_with_metadata("http", remote_url, config_string)
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
# I am aware that 656 http doesn't exist I am just testing the
|
264
|
+
# catch all block
|
265
|
+
[302, 404, 500, 403, 656].each do |code|
|
266
|
+
context "when the remote return an error code: #{code}" do
|
267
|
+
before do
|
268
|
+
stub_request(:get, remote_url)
|
269
|
+
.to_return({ :status => code })
|
270
|
+
end
|
271
|
+
|
272
|
+
it "raises the exception up" do
|
273
|
+
expect { subject.read(remote_url) }.to raise_error LogStash::ConfigLoadingError
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
describe LogStash::Config::Source::Local do
|
280
|
+
let(:input_block) { "input { generator {} }" }
|
281
|
+
let(:filter_block) { "filter { mutate {} } " }
|
282
|
+
let(:output_block) { "output { elasticsearch {}}" }
|
283
|
+
subject { described_class.new(settings) }
|
284
|
+
|
285
|
+
context "when `config.string` and `config.path` are set`" do
|
286
|
+
let(:config_file) { temporary_file(input_block) }
|
287
|
+
|
288
|
+
let(:settings) do
|
289
|
+
mock_settings(
|
290
|
+
"config.string" => "#{filter_block} #{output_block}",
|
291
|
+
"path.config" => config_file
|
292
|
+
)
|
293
|
+
end
|
294
|
+
|
295
|
+
it "returns a merged config" do
|
296
|
+
expect(subject.pipeline_configs.first.config_string).to include(input_block, output_block, filter_block)
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
context "when only the `config.string` is set" do
|
301
|
+
let(:settings) do
|
302
|
+
mock_settings( "config.string" => filter_block)
|
303
|
+
end
|
304
|
+
|
305
|
+
it "returns a config" do
|
306
|
+
expect(subject.pipeline_configs.first.config_string).to include(filter_block)
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
context "when only the `path.config` is set" do
|
311
|
+
let(:config_file) { temporary_file(input_block) }
|
312
|
+
let(:settings) do
|
313
|
+
mock_settings( "path.config" => config_file)
|
314
|
+
end
|
315
|
+
|
316
|
+
it "returns a config" do
|
317
|
+
expect(subject.pipeline_configs.first.config_string).to include(input_block)
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
context "when the `path.config` is an url" do
|
322
|
+
let(:remote_url) { "http://test.dev/superconfig.conf" }
|
323
|
+
|
324
|
+
before :all do
|
325
|
+
WebMock.disable_net_connect!
|
326
|
+
end
|
327
|
+
|
328
|
+
after :all do
|
329
|
+
WebMock.allow_net_connect!
|
330
|
+
end
|
331
|
+
|
332
|
+
before do
|
333
|
+
stub_request(:get, remote_url)
|
334
|
+
.to_return({
|
335
|
+
:body => input_block,
|
336
|
+
:status => 200
|
337
|
+
})
|
338
|
+
end
|
339
|
+
|
340
|
+
let(:settings) do
|
341
|
+
mock_settings( "path.config" => remote_url)
|
342
|
+
end
|
343
|
+
|
344
|
+
it "returns a config" do
|
345
|
+
expect(subject.pipeline_configs.first.config_string).to include(input_block)
|
346
|
+
end
|
347
|
+
|
348
|
+
context "when `config.string` is set" do
|
349
|
+
let(:settings) do
|
350
|
+
mock_settings(
|
351
|
+
"path.config" => remote_url,
|
352
|
+
"config.string" => filter_block
|
353
|
+
)
|
354
|
+
end
|
355
|
+
|
356
|
+
it "returns a merged config" do
|
357
|
+
expect(subject.pipeline_configs.first.config_string).to include(input_block, filter_block)
|
358
|
+
end
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
context "incomplete configuration" do
|
363
|
+
context "when the input block is missing" do
|
364
|
+
let(:settings) { mock_settings( "config.string" => "#{filter_block} #{output_block}") }
|
365
|
+
|
366
|
+
it "add stdin input" do
|
367
|
+
expect(subject.pipeline_configs.first.config_string).to include(LogStash::Config::Defaults.input)
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
context "when the output block is missing" do
|
372
|
+
let(:settings) { mock_settings( "config.string" => "#{input_block} #{filter_block}") }
|
373
|
+
|
374
|
+
it "add stdout output" do
|
375
|
+
expect(subject.pipeline_configs.first.config_string).to include(LogStash::Config::Defaults.output)
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
context "when both the output block and input block are missing" do
|
380
|
+
let(:settings) { mock_settings( "config.string" => "#{filter_block}") }
|
381
|
+
|
382
|
+
it "add stdin and output" do
|
383
|
+
expect(subject.pipeline_configs.first.config_string).to include(LogStash::Config::Defaults.output, LogStash::Config::Defaults.input)
|
384
|
+
end
|
385
|
+
end
|
386
|
+
|
387
|
+
context "when it has an input and an output" do
|
388
|
+
let(:settings) { mock_settings( "config.string" => "#{input_block} #{filter_block} #{output_block}") }
|
389
|
+
|
390
|
+
it "doesn't add anything" do
|
391
|
+
expect(subject.pipeline_configs.first.config_string).not_to include(LogStash::Config::Defaults.output, LogStash::Config::Defaults.input)
|
392
|
+
end
|
393
|
+
end
|
394
|
+
end
|
395
|
+
end
|