in logstash-core/lib/logstash/config/mixin.rb [61:624]
def config_init(params)
original_params = params.clone
@plugin_type = self.class.ancestors.find { |a| a.name =~ /::Base$/ }.config_name
self.class.get_config.each do |name, opts|
next if params.include?(name.to_s)
if opts.include?(:default) and (name.is_a?(Symbol) or name.is_a?(String))
case opts[:default]
when FalseClass, TrueClass, NilClass, Numeric
params[name.to_s] = opts[:default]
else
params[name.to_s] = opts[:default].clone
end
end
if self.class.default?(name)
params[name.to_s] = self.class.get_default(name)
end
end
params.each do |name, value|
params[name.to_s] = deep_replace(value, true)
end
params.each do |name, value|
validator = self.class.validator_find(name)
next unless validator && validator[:validate] == :codec && value.kind_of?(String)
codec_klass = LogStash::Plugin.lookup("codec", value)
codec_instance = LogStash::Plugins::Contextualizer.initialize_plugin(execution_context, codec_klass)
params[name.to_s] = LogStash::Codecs::Delegator.new(codec_instance)
end
if !self.class.validate(params)
raise LogStash::ConfigurationError,
I18n.t("logstash.runner.configuration.invalid_plugin_settings")
end
self.class.secure_params!(original_params)
@original_params = original_params
original_params.each do |name, value|
opts = self.class.get_config[name]
if opts && opts[:deprecated]
extra = opts[:deprecated].is_a?(String) ? opts[:deprecated] : ""
extra.gsub!("%PLUGIN%", self.class.config_name)
self.deprecation_logger.deprecated(
"You are using a deprecated config setting #{name.inspect} set in " \
"#{self.class.config_name}. Deprecated settings will continue to work, " \
"but are scheduled for removal from logstash in the future. #{extra} " \
"If you have any questions about this, please ask it on the " \
"https://discuss.elastic.co/c/logstash discussion forum",
{}
)
end
if opts && opts[:obsolete]
extra = opts[:obsolete].is_a?(String) ? opts[:obsolete] : ""
extra.gsub!("%PLUGIN%", self.class.config_name)
raise LogStash::ConfigurationError,
I18n.t("logstash.runner.configuration.obsolete", :name => name,
:plugin => self.class.config_name, :extra => extra)
end
end
params.reject! do |name, value|
opts = self.class.get_config[name]
opts.include?(:obsolete)
end
params.each do |key, value|
next if key[0, 1] == "@"
self.logger.debug("config #{self.class.name}/@#{key} = #{value.inspect}")
instance_variable_set("@#{key}", value)
end
@config = params
end
module DSL
include LogStash::Util::SubstitutionVariables
attr_accessor :flags
def config_name(name = nil)
@config_name = name if !name.nil?
@config_name
end
alias_method :config_plugin, :config_name
def plugin_status(status = nil)
milestone(status)
end
def milestone(m = nil)
self.logger.debug(I18n.t('logstash.plugin.deprecated_milestone', :plugin => config_name))
end
def config(name, opts = {})
@config ||= Hash.new
name = name.to_s if name.is_a?(Symbol)
@config[name] = opts
if name.is_a?(String) && opts.fetch(:attr_accessor, true)
define_method(name) { instance_variable_get("@#{name}") }
define_method("#{name}=") { |v| instance_variable_set("@#{name}", v) }
end
end
def default(name, value)
@defaults ||= {}
@defaults[name.to_s] = value
end
def get_config
return @config
end
def get_default(name)
return @defaults && @defaults[name]
end
def default?(name)
return @defaults && @defaults.include?(name)
end
def options(opts)
prefix = self.name.split("::").last.downcase
@flags.each do |flag|
flagpart = flag[:args].first.gsub(/^--/, "")
opts.on("--#{prefix}-#{flagpart}", *flag[:args][1..-1], &flag[:block])
end
end
def inherited(subclass)
subconfig = Hash.new
if !@config.nil?
@config.each do |key, val|
subconfig[key] = val
end
end
subclass.instance_variable_set("@config", subconfig)
end
def validate(params)
@plugin_name = config_name
@plugin_type = ancestors.find { |a| a.name =~ /::Base$/ }.config_name
is_valid = true
is_valid &&= validate_check_invalid_parameter_names(params)
is_valid &&= validate_check_required_parameter_names(params)
is_valid &&= validate_check_parameter_values(params)
return is_valid
end
def validate_check_invalid_parameter_names(params)
invalid_params = params.keys
@config.each_key do |config_key|
if config_key.is_a?(Regexp)
invalid_params.reject! { |k| k =~ config_key }
elsif config_key.is_a?(String)
invalid_params.reject! { |k| k == config_key }
end
end
if invalid_params.size > 0
invalid_params.each do |name|
self.logger.error("Unknown setting '#{name}' for #{@plugin_name}")
end
return false
end
return true
end
def validate_check_required_parameter(config_key, config_opts, k, v)
if config_key.is_a?(Regexp)
(k =~ config_key && v)
elsif config_key.is_a?(String)
k && v
end
end
def validate_check_required_parameter_names(params)
is_valid = true
@config.each do |config_key, config|
next unless config[:required]
if config_key.is_a?(Regexp) && !params.keys.any? { |k| k =~ config_key }
is_valid = false
end
value = params[config_key]
if value.nil? || (config[:list] && Array(value).empty?)
self.logger.error(I18n.t("logstash.runner.configuration.setting_missing",
:setting => config_key, :plugin => @plugin_name,
:type => @plugin_type))
is_valid = false
end
end
return is_valid
end
def process_parameter_value(value, config_settings)
config_val = config_settings[:validate]
if config_settings[:list]
value = Array(value)
return true, [] if value.empty?
return validate_value(value, :uri_list) if config_val == :uri
validated_items = value.map {|v| validate_value(v, config_val)}
is_valid = validated_items.all? {|sr| sr[0] }
processed_value = validated_items.map {|sr| sr[1]}
else
is_valid, processed_value = validate_value(value, config_val)
end
return [is_valid, processed_value]
end
def validate_check_parameter_values(params)
all_params_valid = true
params.each do |key, value|
@config.keys.each do |config_key|
next unless (config_key.is_a?(Regexp) && key =~ config_key) \
|| (config_key.is_a?(String) && key == config_key)
config_settings = @config[config_key]
is_valid, processed_value = process_parameter_value(value, config_settings)
if is_valid
params[key] = processed_value
else
self.logger.error(I18n.t("logstash.runner.configuration.setting_invalid",
:plugin => @plugin_name, :type => @plugin_type,
:setting => key, :value => value.inspect,
:value_type => config_settings[:validate],
:note => processed_value))
end
all_params_valid &&= is_valid
break
end
end
return all_params_valid
end
def validator_find(key)
@config.each do |config_key, config_val|
if (config_key.is_a?(Regexp) && key =~ config_key) \
|| (config_key.is_a?(String) && key == config_key)
return config_val
end
end
return nil
end
def validate_value(value, validator)
result = nil
value = deep_replace(value)
if validator.nil?
return true, value
elsif validator.is_a?(Array)
value = [*value]
if value.size > 1
return false, "Expected one of #{validator.inspect}, got #{value.inspect}"
end
if !validator.include?(value.first)
return false, "Expected one of #{validator.inspect}, got #{value.inspect}"
end
result = value.first
elsif validator.is_a?(Symbol)
value = hash_or_array(value)
case validator
when :codec
if value.first.is_a?(String)
self.deprecation_logger.deprecated("Codec instantiated by `Config::Mixin::DSL::validate_value(String, :codec)` which cannot propagate parent plugin's execution context or metrics. ",
self.logger.debug? ? {:backtrace => caller} : {})
value = LogStash::Codecs::Delegator.new LogStash::Plugin.lookup("codec", value.first).new
return true, value
else
value = value.first
return true, value
end
when :hash
if value.is_a?(Hash)
return true, value
end
if value.size % 2 == 1
return false, "This field must contain an even number of items, got #{value.size}"
end
result = {}
value.each_slice(2) do |key, value|
entry = result[key]
if entry.nil?
result[key] = value
else
if entry.is_a?(Array)
entry << value
else
result[key] = [entry, value]
end
end
end
when :array
result = value
when :string
if value.size > 1
return false, "Expected string, got #{value.inspect}"
end
result = value.first
when :number
if value.size > 1
return false, "Expected number, got #{value.inspect} (type #{value.class})"
end
v = value.first
case v
when Numeric
result = v
when String
if v.to_s.to_f.to_s != v.to_s \
&& v.to_s.to_i.to_s != v.to_s
return false, "Expected number, got #{v.inspect} (type #{v})"
end
if v.include?(".")
result = v.to_f
else
result = v.to_i
end
end
when :boolean
if value.size > 1
return false, "Expected boolean, got #{value.inspect}"
end
bool_value = value.first
if !!bool_value == bool_value
result = bool_value
else
if bool_value !~ /^(true|false)$/
return false, "Expected boolean 'true' or 'false', got #{bool_value.inspect}"
end
result = (bool_value == "true")
end
when :ipaddr
if value.size > 1
return false, "Expected IPaddr, got #{value.inspect}"
end
octets = value.split(".")
if octets.length != 4
return false, "Expected IPaddr, got #{value.inspect}"
end
octets.each do |o|
if o.to_i < 0 or o.to_i > 255
return false, "Expected IPaddr, got #{value.inspect}"
end
end
result = value.first
when :password
if value.size > 1
return false, "Expected password (one value), got #{value.size} values?"
end
result = value.first.is_a?(::LogStash::Util::Password) ? value.first : ::LogStash::Util::Password.new(value.first)
when :uri
if value.size > 1
return false, "Expected uri (one value), got #{value.size} values?"
end
result = value.first.is_a?(::LogStash::Util::SafeURI) ? value.first : ::LogStash::Util::SafeURI.new(value.first)
when :uri_list
result = value.flat_map do |entry|
entry.kind_of?(String) ? entry.split(' ') : entry
end.map do |expanded_entry|
::LogStash::Util::SafeURI.from(expanded_entry)
end
when :path
if value.size > 1
return false, "Expected path (one value), got #{value.size} values?"
end
if !File.exist?(value.first)
return false, "File does not exist or cannot be opened #{value.first}"
end
result = value.first
when :bytes
begin
bytes = Integer(value.first) rescue nil
result = bytes || Filesize.from(value.first).to_i
rescue ArgumentError
return false, "Unparseable filesize: #{value.first}. possible units (KiB, MiB, ...) e.g. '10 KiB'. doc reference: http://www.elastic.co/guide/en/logstash/current/configuration.html#bytes"
end
when :field_reference
return [false, "Expected exactly one field reference, got `#{value.inspect}`"] unless value.kind_of?(Array) && value.size <= 1
return [true, nil] if value.empty? || value.first.nil? || value.first.empty?
candidate = value.first
return [false, "Expected a valid field reference, got `#{candidate.inspect}`"] unless org.logstash.FieldReference.isValid(candidate)
return [true, candidate]
when :sha_256_hex
return [false, "Expected exactly one hex-encoded SHA-256 fingerprint, got `#{value.inspect}`"] unless value.kind_of?(Array) && value.size <= 1
return [true, nil] if value.empty? || value.first.nil? || value.first.empty?
candidate = value.first
return [false, "Expected a hex-encoded SHA-256 fingerprint, got `#{candidate.inspect}`"] unless candidate.kind_of?(String) && candidate =~ /\A(?:[[:xdigit:]]{2}:?){32}\z/
return [true, candidate.upcase.tr('^0-9A-F', '')]
else
return false, "Unknown validator symbol #{validator}"
end
else
return false, "Unknown validator #{validator.class}"
end
return true, result
end
def secure_params!(params)
params.each do |key, value|
if [:uri, :password].include? @config[key][:validate]
is_valid, processed_value = process_parameter_value(value, @config[key])
params[key] = processed_value
end
end
end
def hash_or_array(value)
if !value.is_a?(Hash)
value = [*value]
end
return value
end
end
end