From 24426f92ff4606d97a973abf2dbee1e34dcc9515 Mon Sep 17 00:00:00 2001 From: Karol Bucek Date: Mon, 7 Jun 2021 12:29:47 +0200 Subject: [PATCH] Feat: introduce a target check helper (#6) Co-authored-by: Ry Biesemeyer --- CHANGELOG.md | 3 + .../ecs_compatibility_support/target_check.rb | 58 ++++++++++++++++ ...sh-mixin-ecs_compatibility_support.gemspec | 2 +- .../target_check_spec.rb | 67 +++++++++++++++++++ 4 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 lib/logstash/plugin_mixins/ecs_compatibility_support/target_check.rb create mode 100644 spec/logstash/plugin_mixins/ecs_compatibility_support/target_check_spec.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 679a410..48624dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +# 1.3.0 + - Feat: introduce a target check helper [#6](https://github.com/logstash-plugins/logstash-mixin-ecs_compatibility_support/pull/6) + # 1.2.0 - Added support for resolution aliases, allowing a plugin that uses `ecs_select` to support multiple ECS versions with a single declaration. diff --git a/lib/logstash/plugin_mixins/ecs_compatibility_support/target_check.rb b/lib/logstash/plugin_mixins/ecs_compatibility_support/target_check.rb new file mode 100644 index 0000000..ea9c744 --- /dev/null +++ b/lib/logstash/plugin_mixins/ecs_compatibility_support/target_check.rb @@ -0,0 +1,58 @@ +# encoding: utf-8 + +require_relative '../ecs_compatibility_support' + +module LogStash + module PluginMixins + module ECSCompatibilitySupport + # A target option check that can be included into any `LogStash::Plugin`. + # + # @see ECSCompatibilitySupport() + module TargetCheck + ## + # @api internal (use: `LogStash::Plugin::include`) + # @param base [Class]: a class that inherits `LogStash::Plugin`, typically one + # descending from one of the four plugin base classes + # (e.g., `LogStash::Inputs::Base`) + # @return [void] + def self.included(base) + fail(ArgumentError, "`#{base}` must inherit LogStash::Plugin") unless base < LogStash::Plugin + fail(ArgumentError, "`#{base}` must include #{ECSCompatibilitySupport}") unless base < ECSCompatibilitySupport + base.prepend(RegisterDecorator) + end + + TARGET_NOT_SET_MESSAGE = ("ECS compatibility is enabled but `target` option was not specified. " + + "This may cause fields to be set at the top-level of the event where they are likely to clash with the Elastic Common Schema. " + + "It is recommended to set the `target` option to avoid potential schema conflicts (if your data is ECS compliant " + + "or non-conflicting, feel free to ignore this message)").freeze + + private + + ## + # Check whether `target` is specified. + # + # @return [nil] if target is unspecified and ECS compatibility is disabled + # @return [true, false] + def target_set? + return true unless target.nil? + return nil if ecs_compatibility == :disabled + false # target isn't set + end + + module RegisterDecorator + + ## + # Logs an info message when ecs_compatibility is enabled but plugin has no `target` configuration specified. + # @override + def register + super.tap do + logger.info(TARGET_NOT_SET_MESSAGE) if target_set? == false + end + end + + end + private_constant :RegisterDecorator + end + end + end +end diff --git a/logstash-mixin-ecs_compatibility_support.gemspec b/logstash-mixin-ecs_compatibility_support.gemspec index eda4378..a89a640 100644 --- a/logstash-mixin-ecs_compatibility_support.gemspec +++ b/logstash-mixin-ecs_compatibility_support.gemspec @@ -1,6 +1,6 @@ Gem::Specification.new do |s| s.name = 'logstash-mixin-ecs_compatibility_support' - s.version = '1.2.0' + s.version = '1.3.0' s.licenses = %w(Apache-2.0) s.summary = "Support for the ECS-Compatibility mode introduced in Logstash 7.x, for plugins wishing to use this API on older Logstashes" s.description = "This gem is meant to be a dependency of any Logstash plugin that wishes to use the ECS-Compatibility mode introduced in Logstash 7.x while maintaining backward-compatibility with earlier Logstash releases. When used on older Logstash versions, this adapter provides an implementation of ECS-Compatibility mode that can be controlled at the plugin instance level." diff --git a/spec/logstash/plugin_mixins/ecs_compatibility_support/target_check_spec.rb b/spec/logstash/plugin_mixins/ecs_compatibility_support/target_check_spec.rb new file mode 100644 index 0000000..85d2ba3 --- /dev/null +++ b/spec/logstash/plugin_mixins/ecs_compatibility_support/target_check_spec.rb @@ -0,0 +1,67 @@ +# encoding: utf-8 + +require "logstash-core" + +require 'logstash/inputs/base' +require 'logstash/filters/base' +require 'logstash/codecs/base' +require 'logstash/outputs/base' + +require "logstash/plugin_mixins/ecs_compatibility_support/target_check" + +describe LogStash::PluginMixins::ECSCompatibilitySupport::TargetCheck do + + describe "check_target_set_in_ecs_mode" do + + context 'with a plugin' do + + subject(:plugin_class) do + Class.new(LogStash::Filters::Base) do + include LogStash::PluginMixins::ECSCompatibilitySupport + include LogStash::PluginMixins::ECSCompatibilitySupport::TargetCheck + + config :target, :validate => :string + + def register; 42 end + + end + end + + it 'skips check when ECS disabled' do + plugin = plugin_class.new('ecs_compatibility' => 'disabled') + allow( plugin.logger ).to receive(:info) + expect( plugin.register ).to eql 42 + expect( plugin.logger ).to_not have_received(:info).with(a_string_including "`target` option") + end + + it 'warns when target is not set in ECS mode' do + plugin = plugin_class.new('ecs_compatibility' => 'v1') + allow( plugin.logger ).to receive(:info) + expect( plugin.register ).to eql 42 + expect( plugin.logger ).to have_received(:info).with(a_string_including "ECS compatibility is enabled but `target` option was not specified.") + end + + it 'does not warn when target is set' do + plugin = plugin_class.new('ecs_compatibility' => 'v1', 'target' => 'foo') + allow( plugin.logger ).to receive(:info) + expect( plugin.register ).to eql 42 + expect( plugin.logger ).to_not have_received(:info).with(a_string_including "`target` option") + end + + end + + it 'fails check when no target config' do + plugin_class = Class.new(LogStash::Filters::Base) do + include LogStash::PluginMixins::ECSCompatibilitySupport + include LogStash::PluginMixins::ECSCompatibilitySupport::TargetCheck + + def register; end + + end + plugin = plugin_class.new('ecs_compatibility' => 'v1') + expect { plugin.register }.to raise_error NameError, /\btarget\b/ + end + + end + +end