logstash-mixin-validator_support 1.0.1-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +3 -0
- data/LICENSE +13 -0
- data/README.md +63 -0
- data/lib/logstash/plugin_mixins/validator_support.rb +100 -0
- data/lib/logstash/plugin_mixins/validator_support/field_reference_validation_adapter.rb +29 -0
- data/spec/logstash/plugin_mixins/validator_support/field_reference_validation_adapter_spec.rb +52 -0
- data/spec/logstash/plugin_mixins/validator_support_spec.rb +52 -0
- metadata +98 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c5e8b335df368ec737d61dcb43db27b9876979758c615b69ade06865a973e8b8
|
4
|
+
data.tar.gz: b8668657d6af8402ed487f959750d03d49156d22f52304b4c463a8a7e0d1214f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 48b38367a6d71c35ad0fa8d65c898e01f13ef54c8e018259c01d7b620b43398d421735b853699b813af40630f60730a1ad34fc83ba1b57ea2d277781e5a2056e
|
7
|
+
data.tar.gz: a6953c1504f89a087df7b9ffd890c8dc8db21cca1665eafed30c39d514c763315d77733637d0dc7a0fb710f25aec2c47da929c04e82f844588b6e9ceed8afc6d
|
data/CHANGELOG.md
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Copyright (c) 2020 Elastic N.V. <http://www.elastic.co>
|
2
|
+
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
you may not use this file except in compliance with the License.
|
5
|
+
You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
See the License for the specific language governing permissions and
|
13
|
+
limitations under the License.
|
data/README.md
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
# Validator Support Mixin
|
2
|
+
|
3
|
+
This gem provides back-ports of new validators that have been added to Logstash
|
4
|
+
core. By using this support adapter, plugin developers can use newly-introduced
|
5
|
+
validators without constraining the versions of Logstash on which their plugin
|
6
|
+
can run.
|
7
|
+
|
8
|
+
When a plugin using this adapter runs on a version of Logstash that does _not_
|
9
|
+
provide the named validator, the back-ported validator provided by this adapter
|
10
|
+
is used instead.
|
11
|
+
|
12
|
+
## Usage
|
13
|
+
|
14
|
+
1. Add this gem as a runtime dependency of your plugin. To avoid conflicts with
|
15
|
+
other plugins, you should always use the [pessimistic operator][] `~>` to
|
16
|
+
match the minimum `1.x` that provides the back-ports you intend to use:
|
17
|
+
|
18
|
+
~~~ ruby
|
19
|
+
Gem::Specification.new do |s|
|
20
|
+
# ...
|
21
|
+
|
22
|
+
s.add_runtime_dependency 'logstash-mixin-validator_support', '~>1.0'
|
23
|
+
end
|
24
|
+
~~~
|
25
|
+
|
26
|
+
2. In your plugin code, require this library and extend one or more of the
|
27
|
+
provided validators into your plugin. For example, to use the
|
28
|
+
`:field_reference` validator introduced in Logstash 7.11:
|
29
|
+
|
30
|
+
~~~ ruby
|
31
|
+
require 'logstash/plugin_mixins/validator_support/field_reference_validation_adapter'
|
32
|
+
|
33
|
+
class LogStash::Inputs::Foo < Logstash::Inputs::Base
|
34
|
+
extend LogStash::PluginMixins::ValidatorSupport::FieldReferenceValidationAdapter
|
35
|
+
|
36
|
+
# ...
|
37
|
+
end
|
38
|
+
~~~
|
39
|
+
|
40
|
+
3. Use the validator as normal when defining config options; your plugin does
|
41
|
+
not need to know whether the validator was provided by Logstash core or by
|
42
|
+
this gem.
|
43
|
+
|
44
|
+
~~~ ruby
|
45
|
+
config :target, :validate => :field_reference
|
46
|
+
~~~
|
47
|
+
|
48
|
+
## Development
|
49
|
+
|
50
|
+
This gem:
|
51
|
+
- *MUST* remain API-stable at 1.x
|
52
|
+
- *MUST NOT* introduce additional runtime dependencies
|
53
|
+
|
54
|
+
When developing back-ports, sometimes it may not be possible to provide a
|
55
|
+
verbatim validation. In these cases, developers should err on the side of the
|
56
|
+
back-port accepting input that the core implementation may consider invalid.
|
57
|
+
|
58
|
+
Each time a new validator is added, the runtime dependency of this library on
|
59
|
+
Logstash core should be updated to require a minimium of the OLDEST supported
|
60
|
+
release. This allows plugins using this adapter to supply patch-level fixes to
|
61
|
+
any supported Logstash version without maintaining multiple branches.
|
62
|
+
|
63
|
+
[pessimistic operator]: https://thoughtbot.com/blog/rubys-pessimistic-operator
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'logstash/version'
|
4
|
+
require 'logstash/namespace'
|
5
|
+
|
6
|
+
module LogStash
|
7
|
+
module PluginMixins
|
8
|
+
module ValidatorSupport
|
9
|
+
|
10
|
+
##
|
11
|
+
# @api internal
|
12
|
+
#
|
13
|
+
# @param base [#validate_value]
|
14
|
+
# @param validator_name [Symbol]
|
15
|
+
def self.native?(base, validator_name)
|
16
|
+
native_is_valid, native_coerced_or_error = base.validate_value(nil, validator_name)
|
17
|
+
|
18
|
+
native_is_valid || !native_coerced_or_error.start_with?('Unknown validator')
|
19
|
+
end
|
20
|
+
|
21
|
+
##
|
22
|
+
# A NamedValidationAdapter is a module that can be mixed into a Logstash
|
23
|
+
# plugin to ensure the named validator is present and available, whether
|
24
|
+
# provided by Logstash core or approximated with the provided backport
|
25
|
+
# implementation.
|
26
|
+
#
|
27
|
+
# @api internal
|
28
|
+
#
|
29
|
+
class NamedValidationAdapter < Module
|
30
|
+
##
|
31
|
+
# Create a new named validation adapter, to approximate the implementation
|
32
|
+
# of a named validation that exists in Logstash Core.
|
33
|
+
#
|
34
|
+
# @api private
|
35
|
+
#
|
36
|
+
# @param validator_name [Symbol]
|
37
|
+
# @yieldparam value [Hash,Array]
|
38
|
+
# @yieldreturn [true, Object]: validation success returns true with coerced value (see: ValidationResult#success)
|
39
|
+
# @yieldreturn [false, String]: validation failure returns false with error message (see: ValidationResult#failure)
|
40
|
+
def initialize(validator_name, &validator_implementation)
|
41
|
+
fail(ArgumentError, '`validator_name` must be a Symbol') unless validator_name.kind_of?(Symbol)
|
42
|
+
fail(ArgumentError, '`validator_implementation` block required') unless validator_implementation
|
43
|
+
|
44
|
+
define_singleton_method(:validate, &validator_implementation)
|
45
|
+
define_singleton_method(:name) { "#{NamedValidationAdapter}(#{validator_name})" }
|
46
|
+
|
47
|
+
define_singleton_method(:extended) do |base|
|
48
|
+
# Only include the interceptor if support is not natively provided.
|
49
|
+
unless ValidatorSupport.native?(base, validator_name)
|
50
|
+
interceptor = NamedValidationInterceptor.new(validator_name, self)
|
51
|
+
base.extend(interceptor)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
##
|
58
|
+
# A NamedValidationInterceptor intercepts requests to validate input with the given
|
59
|
+
# name and instead substitutes its own implementation. This implementation will
|
60
|
+
# override Logstash core functionality.
|
61
|
+
#
|
62
|
+
# @api private
|
63
|
+
#
|
64
|
+
class NamedValidationInterceptor < Module
|
65
|
+
##
|
66
|
+
# @param validator_name [Symbol]
|
67
|
+
# @param validator [#validate]
|
68
|
+
def initialize(validator_name, validator)
|
69
|
+
fail(ArgumentError, '`validator_name` must be a Symbol') unless validator_name.kind_of?(Symbol)
|
70
|
+
fail(ArgumentError, '`validator` must respond to `\#{validate}`') unless validator.respond_to?(:validate)
|
71
|
+
|
72
|
+
define_method(:validate_value) do |value, required_validator|
|
73
|
+
if required_validator != validator_name
|
74
|
+
super(value, required_validator)
|
75
|
+
else
|
76
|
+
value = deep_replace(value)
|
77
|
+
value = hash_or_array(value)
|
78
|
+
|
79
|
+
validator.validate(value)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
define_singleton_method(:name) { "#{NamedValidationInterceptor}(#{validator_name})" }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
##
|
88
|
+
# Helper functions for returning success and failure tuples
|
89
|
+
module ValidationResult
|
90
|
+
def self.success(coerced_value)
|
91
|
+
[true, coerced_value]
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.failure(error_message)
|
95
|
+
[false, error_message]
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'logstash/plugin_mixins/validator_support'
|
4
|
+
|
5
|
+
module LogStash
|
6
|
+
module PluginMixins
|
7
|
+
module ValidatorSupport
|
8
|
+
field_name = /[^\[\]]+/ # anything but brackets
|
9
|
+
path_fragment = /\[#{field_name}\]/ # bracket-wrapped field name
|
10
|
+
field_reference_literal = /#{path_fragment}+/ # one or more path fragments
|
11
|
+
embedded_field_reference = /\[#{field_reference_literal}\]/ # bracket-wrapped field reference literal
|
12
|
+
composite_field_reference = /#{Regexp.union(path_fragment, embedded_field_reference)}+/
|
13
|
+
|
14
|
+
# anchored pattern matching either a stand-alone field name, or a composite field reference
|
15
|
+
field_reference_pattern = /\A#{Regexp.union(field_name,composite_field_reference)}\z/
|
16
|
+
|
17
|
+
FieldReferenceValidationAdapter = NamedValidationAdapter.new(:field_reference) do |value|
|
18
|
+
break ValidationResult.failure("Expected exactly one field reference, got `#{value.inspect}`") unless value.kind_of?(Array) && value.size <= 1
|
19
|
+
break ValidationResult.success(nil) if value.empty? || value.first.nil?
|
20
|
+
|
21
|
+
candidate = value.first
|
22
|
+
|
23
|
+
break ValidationResult.failure("Expected a valid field reference, got `#{candidate.inspect}`") unless field_reference_pattern =~ candidate
|
24
|
+
|
25
|
+
break ValidationResult.success(candidate)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'logstash/plugin_mixins/validator_support/field_reference_validation_adapter'
|
4
|
+
|
5
|
+
describe LogStash::PluginMixins::ValidatorSupport::FieldReferenceValidationAdapter do
|
6
|
+
it 'is an instance of NamedValidationAdapter' do
|
7
|
+
expect(described_class).to be_a_kind_of LogStash::PluginMixins::ValidatorSupport::NamedValidationAdapter
|
8
|
+
end
|
9
|
+
|
10
|
+
context '#validate' do
|
11
|
+
[
|
12
|
+
['@timestamp'],
|
13
|
+
['[@timestamp]'],
|
14
|
+
['[@metadata][ssl]'],
|
15
|
+
['[link][0]'],
|
16
|
+
['one'],
|
17
|
+
['[fruit][[bananas][oranges]]'],
|
18
|
+
[],
|
19
|
+
[nil]
|
20
|
+
].each do |candidate|
|
21
|
+
context "valid input `#{candidate.inspect}`" do
|
22
|
+
it 'correctly reports the value as valid', :aggregate_failures do
|
23
|
+
is_valid_result, coerced_or_error = described_class.validate(candidate)
|
24
|
+
|
25
|
+
expect(is_valid_result).to be true
|
26
|
+
expect(coerced_or_error).to eq candidate.first
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
[
|
32
|
+
['link[0]'],
|
33
|
+
['][N\\//\\L][D'],
|
34
|
+
["one","two"],
|
35
|
+
{"this" => "that"},
|
36
|
+
['[fruit][bananas[oranges]]'],
|
37
|
+
].each do |candidate|
|
38
|
+
let(:candidate) { candidate }
|
39
|
+
|
40
|
+
context "invalid input `#{candidate.inspect}`" do
|
41
|
+
it 'correctly reports the value as invalid', :aggregate_failures do
|
42
|
+
is_valid_result, coerced_or_error = described_class.validate(candidate)
|
43
|
+
|
44
|
+
expect(is_valid_result).to be false
|
45
|
+
expect(coerced_or_error).to be_a_kind_of String
|
46
|
+
expect(coerced_or_error).to_not include('Unknown validator')
|
47
|
+
expect(coerced_or_error).to include('field reference')
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "logstash/devutils/rspec/spec_helper"
|
4
|
+
|
5
|
+
require 'logstash/plugin_mixins/validator_support'
|
6
|
+
|
7
|
+
require 'securerandom'
|
8
|
+
|
9
|
+
describe LogStash::PluginMixins::ValidatorSupport::NamedValidationAdapter do
|
10
|
+
context 'an adapter re-defining a named validator that exists in Logstash core' do
|
11
|
+
let(:adapter) { described_class.new(:string) { |value| [false, 'intentional failure'] } }
|
12
|
+
let(:plugin_class) { Class.new(LogStash::Plugin) }
|
13
|
+
before(:each) { plugin_class.extend(adapter) }
|
14
|
+
context '#validate_value' do
|
15
|
+
it 'does not intercept validation' do
|
16
|
+
expect(adapter).to_not receive(:validate)
|
17
|
+
|
18
|
+
result = plugin_class.validate_value("banana", :string)
|
19
|
+
|
20
|
+
expect(result).to be_a_kind_of(Array)
|
21
|
+
expect(result.size).to eq(2)
|
22
|
+
|
23
|
+
expect(result[0]).to eq true
|
24
|
+
expect(result[1]).to eq 'banana'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'an adapter defining a named validator that does not exist in Logstash core' do
|
30
|
+
let(:validator_name) { "some_custom_validator_name_#{SecureRandom.hex(10)}".to_sym }
|
31
|
+
let(:adapter) { described_class.new(validator_name) { |value| [false, 'intentional failure'] } }
|
32
|
+
let(:plugin_class) { Class.new(LogStash::Plugin) }
|
33
|
+
before(:each) { plugin_class.extend(adapter) }
|
34
|
+
|
35
|
+
context '#validate_value' do
|
36
|
+
it 'intercepts validation' do
|
37
|
+
expect(plugin_class).to receive(:hash_or_array).and_call_original
|
38
|
+
expect(plugin_class).to receive(:deep_replace).and_call_original
|
39
|
+
|
40
|
+
expect(adapter).to receive(:validate).with(["banana"]).and_call_original
|
41
|
+
|
42
|
+
result = plugin_class.validate_value("banana", validator_name)
|
43
|
+
|
44
|
+
expect(result).to be_a_kind_of(Array)
|
45
|
+
expect(result.size).to eq(2)
|
46
|
+
|
47
|
+
expect(result[0]).to eq false
|
48
|
+
expect(result[1]).to eq 'intentional failure'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
metadata
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: logstash-mixin-validator_support
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: java
|
6
|
+
authors:
|
7
|
+
- Elastic
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-12-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - ">="
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '6.8'
|
19
|
+
name: logstash-core
|
20
|
+
prerelease: false
|
21
|
+
type: :runtime
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '6.8'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - "~>"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '3.9'
|
33
|
+
name: rspec
|
34
|
+
prerelease: false
|
35
|
+
type: :development
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.9'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
name: logstash-devutils
|
48
|
+
prerelease: false
|
49
|
+
type: :development
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: This gem is meant to be a dependency of any Logstash plugin that wishes
|
56
|
+
to use validators introduced in recent versions of Logstash while maintaining backward-compatibility
|
57
|
+
with earlier Logstashes. When used on older Logstash versions, it provides back-ports
|
58
|
+
of the new validators.
|
59
|
+
email: info@elastic.co
|
60
|
+
executables: []
|
61
|
+
extensions: []
|
62
|
+
extra_rdoc_files: []
|
63
|
+
files:
|
64
|
+
- CHANGELOG.md
|
65
|
+
- LICENSE
|
66
|
+
- README.md
|
67
|
+
- lib/logstash/plugin_mixins/validator_support.rb
|
68
|
+
- lib/logstash/plugin_mixins/validator_support/field_reference_validation_adapter.rb
|
69
|
+
- spec/logstash/plugin_mixins/validator_support/field_reference_validation_adapter_spec.rb
|
70
|
+
- spec/logstash/plugin_mixins/validator_support_spec.rb
|
71
|
+
homepage: https://github.com/logstash-plugins/logstash-mixin-validator_support
|
72
|
+
licenses:
|
73
|
+
- Apache-2.0
|
74
|
+
metadata: {}
|
75
|
+
post_install_message:
|
76
|
+
rdoc_options: []
|
77
|
+
require_paths:
|
78
|
+
- lib
|
79
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
requirements: []
|
90
|
+
rubyforge_project:
|
91
|
+
rubygems_version: 2.6.11
|
92
|
+
signing_key:
|
93
|
+
specification_version: 4
|
94
|
+
summary: Support for the plugin parameter validations introduced in recent releases
|
95
|
+
of Logstash, for plugins wishing to use them on older Logstashes
|
96
|
+
test_files:
|
97
|
+
- spec/logstash/plugin_mixins/validator_support/field_reference_validation_adapter_spec.rb
|
98
|
+
- spec/logstash/plugin_mixins/validator_support_spec.rb
|