class ChefHandlerForeman::ForemanFacts

Attributes

blacklist[RW]
cache_expired[RW]
cache_file[RW]
uploader[RW]
whitelist[RW]

Public Instance Methods

report() click to toggle source
# File lib/chef_handler_foreman/foreman_facts.rb, line 25
def report
  send_attributes(prepare_facts)
end

Private Instance Methods

array_to_hash(array) click to toggle source
# File lib/chef_handler_foreman/foreman_facts.rb, line 96
def array_to_hash(array)
  new = {}
  array.each_with_index { |v, index| new[index.to_s] = v }
  new
end
get_key(key, prefix) click to toggle source
# File lib/chef_handler_foreman/foreman_facts.rb, line 102
def get_key(key, prefix)
  [prefix, key].compact.join('::')
end
normalize(os) click to toggle source

if node['id'] fails and we use platform instead, normalize os names

# File lib/chef_handler_foreman/foreman_facts.rb, line 57
def normalize(os)
  case os
  when 'redhat'
    'RedHat'
  when 'centos'
    'CentOS'
  else
    os.capitalize
  end
end
plain_attributes() click to toggle source
# File lib/chef_handler_foreman/foreman_facts.rb, line 68
def plain_attributes
  # chef 10 attributes can be access by to_hash directly, chef 11 uses attributes method
  attributes = node.respond_to?(:attributes) ? node.attributes : node.to_hash
  attributes = attributes.select { |key, value| @whitelist.include?(key) } if @whitelist
  attrs = plainify(attributes.to_hash).flatten.inject(&:merge)
  verify_checksum(attrs) if @cache_file
  attrs
end
plainify(hash, prefix = nil) click to toggle source
# File lib/chef_handler_foreman/foreman_facts.rb, line 77
def plainify(hash, prefix = nil)
  result = []
  hash.each_pair do |key, value|
    if value.is_a?(Hash)
      result.push plainify(value, get_key(key, prefix))
    elsif value.is_a?(Array)
      result.push plainify(array_to_hash(value), get_key(key, prefix))
    else
      new                       = {}
      full_key = get_key(key, prefix)
      if @blacklist.nil? || !@blacklist.any? { |black_key| full_key.include?(black_key) }
        new[full_key] = value
        result.push new
      end
    end
  end
  result
end
prepare_facts() click to toggle source
# File lib/chef_handler_foreman/foreman_facts.rb, line 32
def prepare_facts
  return false if node.nil?

  os, release = nil
  if node.respond_to?(:lsb)
    os = node['lsb']['id']
    release = node['lsb']['release']
  end
  os ||= node['platform']
  release ||= node['platform_version']

  # operatingsystem and operatingsystemrelase are not needed since foreman_chef 0.1.3
  { :name  => node.name.downcase,
    :facts => plain_attributes.merge({
                                         :environment            => node.chef_environment,
                                         :chef_node_name         => node.name,
                                         :operatingsystem        => normalize(os),
                                         :operatingsystemrelease => release,
                                         :_timestamp             => Time.now,
                                         :_type                  => 'foreman_chef'
                                     })
  }
end
send_attributes(attributes) click to toggle source
# File lib/chef_handler_foreman/foreman_facts.rb, line 106
def send_attributes(attributes)
  if @cache_file and !@cache_expired
    Chef::Log.info "No attributes have changed - not uploading to foreman"
  elsif !attributes
    Chef::Log.info "No attributes received, failed run - not uploading to foreman"
  else
    if uploader
      Chef::Log.info 'Sending attributes to foreman'
      Chef::Log.debug attributes.inspect
      uploader.foreman_request('/api/hosts/facts', attributes, node.name)
    else
      Chef::Log.error "No uploader registered for foreman facts, skipping facts upload"
    end
  end
end
verify_checksum(attributes) click to toggle source
# File lib/chef_handler_foreman/foreman_facts.rb, line 122
def verify_checksum(attributes)
  @cache_expired = true
  attrs_checksum = Digest::MD5.hexdigest(attributes.to_s)
  if File.exist?(@cache_file)
    contents = File.read(@cache_file)
    if attrs_checksum == contents
      @cache_expired = false
    end
  end
  File.open(@cache_file, 'w') { |f| f.write(attrs_checksum) }
rescue => e
  @cache_expired = true
  Chef::Log.info "unable to verify cache checksum - #{e.message}, facts will be sent"
  Chef::Log.debug e.backtrace.join("\n")
end