logstash-mixin-validator_support 1.0.1-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +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
|