1

I'm looking to create a role based on host name prefix and I'm running into some problems. Ruby is new to me and although I've done extensive searching for a solution, I'm still confused.

Host names look like this:

  • work-server-01
  • home-server-01

Here's what I've written:

require 'facter'
Facter.add('host_role') do
setcode do
    hostname_array = Facter.value(:hostname).split('-')
    first_in_array = hostname_array.first
    first_in_array.each do |x|
      if x =~ /^(home|work)/
        role = '"#{x}" server'
    end
    role
end
end

I'd like to use variable interpolation within my role assignment, but I feel like using a case statement along with 'when' is incorrect. Please keep in mind that I'm new to Ruby.

Would anybody have any ideas on how I might achieve my goal?

Todd A. Jacobs
  • 81,402
  • 15
  • 141
  • 199
Mike Reed
  • 13
  • 4
  • You should likely not be doing this in a fact - definitely not if security is an issue to you. You can perform the matching in your `site.pp` and declare the `$::host_role` variable right there. – Felix Frank Sep 04 '14 at 10:51

1 Answers1

2

Pattern-Matching the Hostname Fact

The following is a relatively DRY refactoring of your code:

require 'facter'

Facter.add :host_role do
  setcode do
    location = case Facter.value(:hostname)
               when /home/ then $&
               when /work/ then $&
               else 'unknown'
               end
    '%s server' % location
  end
end

Mostly, it just looks for a regex match, and assigns the value of the match to location which is then returned as part of a formatted string.

On my system the hostname doesn't match either "home" or "work", so I correctly get:

Facter.value :host_role
#=> "unknown server"
Todd A. Jacobs
  • 81,402
  • 15
  • 141
  • 199
  • that seems much more elegant than my solution. I'm assuming that the "'%s server' % location" is interpolating based on the '$&' from the location case statement? – Mike Reed Sep 04 '14 at 15:44
  • `'%s server' % location` is roughly equivalent to `"#{location} server"`, and in this specific instance the two are interchangeable. The *location* variable is set to the return value of the case expression. – Todd A. Jacobs Sep 04 '14 at 15:50
  • ah, thank you for clarifying. can you briefly explain what the "$&" is doing at the end of the 'when' statements? Thank you very much for your help. – Mike Reed Sep 04 '14 at 16:15
  • @MikeReed `$&` holds the last successful match, or nil if the match failed. See http://ruby.wikia.com/wiki/Special_variable or http://www.zenspider.com/Languages/Ruby/QuickRef.html#pre-defined-variables for a more complete list of such variables. – Todd A. Jacobs Sep 04 '14 at 18:11