4

I'm trying to get multiple structured custom facts to append to my root key (called rag here), but instead they always replace the current value.

Q1: Is this the expected behavior of Facter.add ?

So to get it to work i created two external facts, and on the custom fact i just read their results and append to the root with type => :aggregate

I do get the expected result, which is:

:~# facter -p rag

{
  role => "win-mbox",
  ambiente => "producao",
  enabled_services => [
    "auditd",
    "lvm2-monitor",
    "mdmonitor",
    "rhsmcertd",
    "rsyslog",
    "sshd",
    "syslog",
    "sysstat",
  ]
}

I'm breaking it in multiple files for better maintenance (each script outputs 1 key), but i feel like there should be a better way.

Q2: Is there a better way? I mean, not having to use a custom fact just to read the external facts values and append.

Below, details about the code:

/opt/puppetlabs/puppet/cache/facts.d/rag_system_services.rb

#!/usr/bin/env ruby

require 'facter'
require 'json'

retorno   = Hash.new { |h,k| h[k] = Hash.new(&h.default_proc) }
os_family = Facter.value(:osfamily)

if os_family == 'RedHat'
    retorno[:rag_system_services] = `systemctl list-unit-files --no-legend --no-pager -t service --state=enabled`.scan(/(^.+?)\.service\s+enabled/i).flatten
else
    retorno[:rag_system_services] = `rcconf --list | sort`.scan(/(^.+?)\s+on/i).flatten
end

puts JSON.pretty_generate(retorno)

/opt/puppetlabs/puppet/cache/facts.d/rag_role.rb

#!/usr/bin/env ruby

require 'facter'
require 'json'

retorno = Hash.new { |h,k| h[k] = Hash.new(&h.default_proc) }
fqdn    = Facter.value(:fqdn)

retorno[:rag_role] = if fqdn.start_with? 'win-'
    case fqdn
        when /-aio/    then 'win-aio'
        when /-ldap/   then 'win-ldap'
        when /-logger/ then 'win-logger'
        when /-mbox/   then 'win-mbox'
        when /-mta/    then 'win-mta'
        when /-proxy/  then 'win-proxy'
    end
elsif fqdn.include? 'lnx-'
    case fqdn
        when /balancer/ then 'lnx-balancer'
        when /database/ then 'lnx-database'
        when /nfs/      then 'lnx-nfs'
        when /server/   then 'lnx-server'
    end
else
    case fqdn
        when /^dns-/         then 'dns'
        when /^elastic-/     then 'elastic'
        when /^pre-auth/     then 'pre-auth'
        when /^puppetserver/ then 'puppetserver'
    end
end

puts JSON.pretty_generate(retorno)

/opt/puppetlabs/puppet/cache/lib/facter/rag.rb

Facter.add(:rag, :type => :aggregate) do

    chunk(:ambiente) do
        rag = {}
        rag['ambiente'] = (Facter.value(:fqdn).include? 'hom-') ? 'homologacao' : 'producao'
        rag
    end

    chunk(:enabled_services) do
        rag = {}
        rag['enabled_services'] = Facter.value(:rag_system_services)
        rag
    end

    chunk(:role) do
        rag = {}
        rag['role'] = Facter.value(:rag_role)
        rag
    end

end
RASG
  • 5,988
  • 4
  • 26
  • 47
  • 1
    "*I'm trying to get multiple structured custom facts to append to my root key (called rag here), but instead they always replace the current value.*" -- it's unclear to me exactly what you're describing here. If you want us to analyze code that is not behaving as you expect, then we need to see the code -- that is, a [mre] demonstrating the issue. – John Bollinger Jul 10 '19 at 16:27
  • 1
    "*I'm breaking it in multiple files for better maintenance (each script outputs 1 key), but i feel like there should be a better way*" -- this is really broad, and it seems pretty opinion-based. "Better" in what sense? – John Bollinger Jul 10 '19 at 16:29
  • @JohnBollinger 'better' in a sense of not having to use a custom fact just to read the external facts values and append. if you replace the line that ouputs the json `puts JSON.pretty_generate(retorno)` with `Facter.add(:rag, :type => :aggregate)` and move the script to where `rag.rb` is, the key `rag.` will have only the value for the last executed file. let me know if its not clear yet, and i will edit the question. – RASG Jul 10 '19 at 16:56
  • 1
    Do you mean you make such a substitution and move for *each* external fact file? Please, the details matter, and presenting the actual code that manifests the problem is much better than describing it. – John Bollinger Jul 10 '19 at 17:02
  • Also, with the question as it is presented, I do not understand why external facts are involved at all. – Matthew Schuchard Jul 11 '19 at 16:57
  • @MattSchuchard i will work on editing the question and making it more clear. – RASG Jul 11 '19 at 17:10

0 Answers0