Current File : //opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/settings/base_setting.rb |
require 'set'
require_relative '../../puppet/settings/errors'
# The base setting type
class Puppet::Settings::BaseSetting
attr_writer :default
attr_accessor :name, :desc, :section
attr_reader :short, :deprecated, :call_hook
# Hooks are called during different parts of the settings lifecycle:
#
# * :on_write_only - This is the default hook type. The hook will be called
# if its value is set in `main` or programmatically. If its value is set in
# a section that doesn't match the application's run mode, it will be
# ignored entirely. If the section does match the run mode, the value will
# be used, but the hook will not be called!
#
# * :on_define_and_write - The hook behaves the same as above, except it is
# also called immediately when the setting is defined in
# {Puppet::Settings.define_settings}. In that case, the hook receives the
# default value as specified.
#
# * :on_initialize_and_write - The hook will be called if the value is set in
# `main`, the section that matches the run mode, or programmatically.
#
HOOK_TYPES = Set.new([:on_define_and_write, :on_initialize_and_write, :on_write_only]).freeze
def self.available_call_hook_values
HOOK_TYPES.to_a
end
# Registers a hook to be called later based on the type of hook specified in `value`.
#
# @param value [Symbol] One of {HOOK_TYPES}
def call_hook=(value)
if value.nil?
#TRANSLATORS ':%{name}', ':call_hook', and ':on_write_only' should not be translated
Puppet.warning _("Setting :%{name} :call_hook is nil, defaulting to :on_write_only") % { name: name }
value = :on_write_only
end
unless HOOK_TYPES.include?(value)
#TRANSLATORS 'call_hook' is a Puppet option name and should not be translated
raise ArgumentError, _("Invalid option %{value} for call_hook") % { value: value }
end
@call_hook = value
end
# @see {HOOK_TYPES}
def call_hook_on_define?
call_hook == :on_define_and_write
end
# @see {HOOK_TYPES}
def call_hook_on_initialize?
call_hook == :on_initialize_and_write
end
# get the arguments in getopt format
def getopt_args
if short
[["--#{name}", "-#{short}", GetoptLong::REQUIRED_ARGUMENT]]
else
[["--#{name}", GetoptLong::REQUIRED_ARGUMENT]]
end
end
# get the arguments in OptionParser format
def optparse_args
if short
["--#{name}", "-#{short}", desc, :REQUIRED]
else
["--#{name}", desc, :REQUIRED]
end
end
def hook=(block)
@has_hook = true
meta_def :handle, &block
end
def has_hook?
@has_hook
end
# Create the new element. Pretty much just sets the name.
def initialize(args = {})
@settings = args.delete(:settings)
unless @settings
raise ArgumentError.new("You must refer to a settings object")
end
# explicitly set name prior to calling other param= methods to provide meaningful feedback during
# other warnings
@name = args[:name] if args.include? :name
#set the default value for call_hook
@call_hook = :on_write_only if args[:hook] and not args[:call_hook]
@has_hook = false
if args[:call_hook] and not args[:hook]
#TRANSLATORS ':call_hook' and ':hook' are specific setting names and should not be translated
raise ArgumentError, _("Cannot reference :call_hook for :%{name} if no :hook is defined") % { name: @name }
end
args.each do |param, value|
method = param.to_s + "="
unless self.respond_to? method
raise ArgumentError, _("%{class_name} (setting '%{setting}') does not accept %{parameter}") %
{ class_name: self.class, setting: args[:name], parameter: param }
end
self.send(method, value)
end
unless self.desc
raise ArgumentError, _("You must provide a description for the %{class_name} config option") % { class_name: self.name }
end
end
def iscreated
@iscreated = true
end
def iscreated?
@iscreated
end
# short name for the element
def short=(value)
raise ArgumentError, _("Short names can only be one character.") if value.to_s.length != 1
@short = value.to_s
end
def default(check_application_defaults_first = false)
if @default.is_a? Proc
# Give unit tests a chance to reevaluate the call by removing the instance variable
unless instance_variable_defined?(:@evaluated_default)
@evaluated_default = @default.call
end
default_value = @evaluated_default
else
default_value = @default
end
return default_value unless check_application_defaults_first
return @settings.value(name, :application_defaults, true) || default_value
end
# Convert the object to a config statement.
def to_config
require_relative '../../puppet/util/docs'
# Scrub any funky indentation; comment out description.
str = Puppet::Util::Docs.scrub(@desc).gsub(/^/, "# ") + "\n"
# Add in a statement about the default.
str << "# The default value is '#{default(true)}'.\n" if default(true)
# If the value has not been overridden, then print it out commented
# and unconverted, so it's clear that that's the default and how it
# works.
value = @settings.value(self.name)
if value != @default
line = "#{@name} = #{value}"
else
line = "# #{@name} = #{@default}"
end
str << (line + "\n")
# Indent
str.gsub(/^/, " ")
end
# @param bypass_interpolation [Boolean] Set this true to skip the
# interpolation step, returning the raw setting value. Defaults to false.
# @return [String] Retrieves the value, or if it's not set, retrieves the default.
# @api public
def value(bypass_interpolation = false)
@settings.value(self.name, nil, bypass_interpolation)
end
# Modify the value when it is first evaluated
def munge(value)
value
end
# Print the value for the user in a config compatible format
def print(value)
munge(value)
end
def set_meta(meta)
Puppet.notice("#{name} does not support meta data. Ignoring.")
end
def deprecated=(deprecation)
unless [:completely, :allowed_on_commandline].include?(deprecation)
#TRANSLATORS 'deprecated' is a Puppet setting and ':completely' and ':allowed_on_commandline' are possible values and should not be translated
raise ArgumentError, _("Unsupported deprecated value '%{deprecation}'.") % { deprecation: deprecation } +
' ' + _("Supported values for deprecated are ':completely' or ':allowed_on_commandline'")
end
@deprecated = deprecation
end
def deprecated?
!!@deprecated
end
# True if we should raise a deprecation_warning if the setting is submitted
# on the commandline or is set in puppet.conf.
def completely_deprecated?
@deprecated == :completely
end
# True if we should raise a deprecation_warning if the setting is found in
# puppet.conf, but not if the user sets it on the commandline
def allowed_on_commandline?
@deprecated == :allowed_on_commandline
end
def inspect
%Q{<#{self.class}:#{self.object_id} @name="#{@name}" @section="#{@section}" @default="#{@default}" @call_hook="#{@call_hook}">}
end
end