class Facter::Util::Fact

Attributes

ldapname[RW]

@return [String] @deprecated

name[R]

The name of the fact @return [String]

options[RW]

Fact options e.g. fact_type

used_resolution_weight[RW]

Weight of the resolution that was used to obtain the fact value

Public Class Methods

new(name, options = {}) click to toggle source

Creates a new fact, with no resolution mechanisms. See {Facter.add} for the public API for creating facts. @param name [String] the fact name @param options [Hash] optional parameters @option options [String] :ldapname set the ldapname property on the fact

@api private

# File lib/facter/custom_facts/util/fact.rb, line 32
def initialize(name, options = {})
  @name = name.to_s.downcase.intern

  @options = Facter::Utils.deep_copy(options)
  extract_ldapname_option!(options)

  @ldapname ||= @name.to_s

  @resolves = []
  @searching = false
  @used_resolution_weight = 0

  @value = nil
end

Public Instance Methods

add(options = {}, &block) click to toggle source

Adds a new {Facter::Util::Resolution resolution}. This requires a block, which will then be evaluated in the context of the new resolution.

@param options [Hash] A hash of options to set on the resolution

@return [Facter::Util::Resolution]

@api private

# File lib/facter/custom_facts/util/fact.rb, line 56
def add(options = {}, &block)
  @options = Facter::Utils.deep_copy(@options.merge(options))
  define_resolution(nil, options, &block)
end
define_resolution(resolution_name, options = {}, &block) click to toggle source

Define a new named resolution or return an existing resolution with the given name.

@param resolution_name [String] The name of the resolve to define or look up @param options [Hash] A hash of options to set on the resolution @return [Facter::Util::Resolution]

@api public

# File lib/facter/custom_facts/util/fact.rb, line 69
def define_resolution(resolution_name, options = {}, &block)
  resolution_type = options.delete(:type) || :simple

  resolve = create_or_return_resolution(resolution_name, resolution_type)

  resolve.options(options) unless options.empty?
  resolve.evaluate(&block) if block

  resolve
rescue StandardError => e
  LegacyFacter
    .log_exception(e, "Unable to add resolve #{resolution_name.inspect} for fact #{@name}: #{e.message}")
end
extract_ldapname_option!(options) click to toggle source

@api private @deprecated

# File lib/facter/custom_facts/util/fact.rb, line 136
def extract_ldapname_option!(options)
  return unless options[:ldapname]

  LegacyFacter.warnonce('ldapname is deprecated and will be removed in a future version')
  self.ldapname = options.delete(:ldapname)
end
flush() click to toggle source

Flushes any cached values.

@return [void]

@api private

# File lib/facter/custom_facts/util/fact.rb, line 100
def flush
  @resolves.each(&:flush)
  @value = nil
end
resolution(name) click to toggle source

Retrieve an existing resolution by name

@param name [String]

@return [Facter::Util::Resolution, nil] The resolution if exists, nil if

it doesn't exist or name is nil
# File lib/facter/custom_facts/util/fact.rb, line 89
def resolution(name)
  return nil if name.nil?

  @resolves.find { |resolve| resolve.name == name }
end
value() click to toggle source

Returns the value for this fact. This searches all resolutions by suitability and weight (see {Facter::Util::Resolution}). If no suitable resolution is found, it returns nil.

@api public

# File lib/facter/custom_facts/util/fact.rb, line 110
def value
  return @value if @value

  if @resolves.empty?
    LegacyFacter.debug format('No resolves for %<name>s', name: @name)
    return nil
  end

  searching do
    suitable_resolutions = sort_by_weight(find_suitable_resolutions(@resolves))

    Facter::Framework::Benchmarking::Timer.measure(@name) do
      @value = find_first_real_value(suitable_resolutions)
    end

    announce_when_no_suitable_resolution(suitable_resolutions)
    announce_when_no_value_found(@value)

    @value = resolve_value
  end

  @value
end

Private Instance Methods

announce_when_no_suitable_resolution(resolutions) click to toggle source
# File lib/facter/custom_facts/util/fact.rb, line 191
def announce_when_no_suitable_resolution(resolutions)
  return unless resolutions.empty?

  LegacyFacter.debug format('Found no suitable resolves of %<resolver_length> for %<name>s',
                            resolver_length: @resolves.length, name: @name)
end
announce_when_no_value_found(value) click to toggle source
# File lib/facter/custom_facts/util/fact.rb, line 198
def announce_when_no_value_found(value)
  LegacyFacter.debug(format('value for %<name>s is still nil', name: @name)) if value.nil?
end
create_or_return_resolution(resolution_name, resolution_type) click to toggle source
# File lib/facter/custom_facts/util/fact.rb, line 202
def create_or_return_resolution(resolution_name, resolution_type)
  resolve = resolution(resolution_name)

  if resolve
    if resolution_type != resolve.resolution_type
      raise ArgumentError, "Cannot return resolution #{resolution_name} with type" \
                           " #{resolution_type}; already defined as #{resolve.resolution_type}"
    end
  else
    case resolution_type
    when :simple
      resolve = Facter::Util::Resolution.new(resolution_name, self)
    when :aggregate
      resolve = Facter::Core::Aggregate.new(resolution_name, self)
    else
      raise ArgumentError,
            "Expected resolution type to be one of (:simple, :aggregate) but was #{resolution_type}"
    end

    @resolves << resolve
  end

  resolve
end
find_first_real_value(resolutions) click to toggle source
# File lib/facter/custom_facts/util/fact.rb, line 178
def find_first_real_value(resolutions)
  resolutions.each do |resolve|
    begin
      value = resolve.value
    rescue Facter::ResolveCustomFactError
      break
    end
    @used_resolution_weight = resolve.weight
    return value unless value.nil?
  end
  nil
end
find_suitable_resolutions(resolutions) click to toggle source
# File lib/facter/custom_facts/util/fact.rb, line 170
def find_suitable_resolutions(resolutions)
  resolutions.find_all(&:suitable?)
end
resolve_value() click to toggle source
# File lib/facter/custom_facts/util/fact.rb, line 145
def resolve_value
  return Facter.core_value(name) if @value.nil?

  core_value = Facter.core_value(name) if @used_resolution_weight <= 0
  core_value.nil? ? @value : core_value
end
searching() { || ... } click to toggle source

Lock our searching process, so we never get stuck in recursion.

# File lib/facter/custom_facts/util/fact.rb, line 158
def searching
  raise "Caught recursion on #{@name}" if searching?

  # If we've gotten this far, we're not already searching, so go ahead and do so.
  @searching = true
  begin
    yield
  ensure
    @searching = false
  end
end
searching?() click to toggle source

Are we in the midst of a search?

# File lib/facter/custom_facts/util/fact.rb, line 153
def searching?
  @searching
end
sort_by_weight(resolutions) click to toggle source
# File lib/facter/custom_facts/util/fact.rb, line 174
def sort_by_weight(resolutions)
  resolutions.sort { |a, b| b <=> a }
end