rubypuppetfacter

Get array of strings from Facter into Puppet


In a module I'm working on, I need to check if specific users exist on a machine. The idea was to create a custom fact that contains an array of all users. In the module, it should iterate through the array and check if a specific user is part of the array.

My Custom Fact:

Facter.add("users") do
  setcode do
    IO.readlines("/etc/passwd").collect do |line|
      line.split(":").first
    end
  end
end

The output of the fact is a String like this: ["user1", "user2", "user3"]

Because it is just a string and no array, I'm unable to iterate through it in my puppet module.

I then tried

  shell_split($::users).each |String $user| {
    notify { "$user":}
  }

But now, each user contains a comma after the username.

Do you have an idea for a working and better solution?


Solution

  • The output of the fact is a String like this: ["user1", "user2", "user3"]

    No, it isn't. The Ruby code you presented in the fact's setcode block evaluates to an array. That expression provides the value of the fact. It is an array.

    It is possible, however, that Puppet converts that array to a string after receiving it from Facter. Puppet 3 did this by default, but had a boolean stringify_facts configuration setting that could prevent that behavior. Puppet 4 retained that setting but deprecated it and reversed its default value (to false). Puppet 5 removed the setting, and never stringifies fact values.

    Therefore, if you are using (obsolete) Puppet 3 then you can avoid fact stringification by setting

    stringify_facts = false
    

    in the [main] section of your puppet.conf files on the master and all agents. You can do the same on Puppet 4, but there you can also just ensure that the stringify_facts setting is not explicitly set at all.