Project

fqdn_facts

0.0
No commit activity in last 3 years
No release in over 3 years
FqdnFacts allows you to create fact handlers for different FQDN formats. This is primarily intended for use with Puppet/Facter to facilitate dynamic fact generation based on FQDNs.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 4.6.4
~> 0.10.3
~> 0.2.4
~> 1.6.4
~> 10.5.0
~> 3.4.0
~> 1.2.0
 Project Readme

FqdnFacts

FqdnFacts allows you to create fact handlers for different FQDN formats. This is primarily intended for use with Puppet/Facter to facilitate dynamic fact generation based on FQDNs.

Status

Installation

Add this line to your application's Gemfile:

gem 'fqdn_facts'

And then execute:

$ bundle

Or install it yourself as:

$ gem install fqdn_facts

Usage

An example is (hopefully) worth a thousand words:

%w[
  facter 
  fqdn_facts 
  awesome_print
].each do |lib|
  begin
    require lib
  rescue LoadError
    puts "Unable to find lib '#{lib}' - try installing it: gem install #{lib}"
    exit 1
  end
end

# setup a baseline handler that we can use as a "catch-all"
# as well as a foundation to derive from with other handlers.
FqdnFacts.register(:baseline) do
  priority 1000 # we want this to be used last as a catch-all

  # this defines the order of the components
  components :host, :sub, :tld

  # if a component is not listed in 'components' it is
  # assumed that the validation for it is :any. However,
  # all sub-components /must/ have a validation defined.
  component :host, {
    # order of sub-components is important!
    type:    %r'^([a-z][a-z-]*[a-z])',
    id:      %r'(\d{2,})',
    subtype: %r'([ms]?)'
  }
  component :sub, /.+/
  component :tld, /.+/

  # conversions happen during fact retrieval and
  # prior to dynamic fact generation.
  convert :host, {
    subtype: ->(v) {
      case v
        when 'm' then 'master'
        when 's' then 'slave'
      end
    },
    id: ->(v) { v.to_i }
  }

  # facts generated dynamically using procs/lambdas are calculated
  # after all conversions, and in order order of assignment. If you
  # use a lambda/proc, it is expected to receive at most one parameter.
  # If you receive for one, then that parameter will contain a hash of
  # facts generated up until that point.
  add_fact :hostname, ->(f) { f[:host] }
  add_fact :domain, ->(f) { [f[:sub], f[:tld]].join('.') }
end # this essentially matches ([a-z][a-z-]*[a-z])(\d{2,})([ms]?)\.([^\.]+)\.bar\.com

# copy baseline to create the qa handler. This means
# that the :qa handler will contain all the settings
# that we defined in :baseline aside from any settings
# that we override in :qa.
FqdnFacts.register(:qa, copy: :baseline) do
  priority 10
  component :sub, %r:qa\d*:
  add_fact :env, 'qa'
end # this matches ([a-z][a-z-]*[a-z])(\d{2,})([ms]?)\.qa\d+\.bar\.com

# let's say you don't have a server that conforms to your previously
# defined :host component (e.g., it doesn't use id/subtype), but is instead
# a static value.
FqdnFacts.register(:qa_foo_server, copy: :baseline) do
  # we can set this to the same priority as the :qa handler because
  # the :qa handler will fail on the :host component for foo-server
  # which will allow this handler to pick it up.
  priority 10
  component :host, 'foo-server'
  add_fact :nifty, 'data'
end # this matches foo-server\.qa\d+\.bar\.com

# Now we gather our facts:
begin
  facts = FqdnFacts.handler(ARGV.first || Facter['fqdn'].value).retrieve_facts
  facts.each do |fact, value|
    Facter.add(fact) { setcode { value } }
  end
  ap facts
rescue FqdnFacts::Error::UnresolveableHandler => e
  puts e.message
end

=begin

Now given a FQDN of foo-server.qa3.bar.com, we would get the following facts:

{
  :fqdn         => "foo-server.qa3.bar.com",
  :handler_name => "qa_foo_server",
  :hostname     => "foo-server",
  :domain       => "qa3.bar.com",
  :nifty        => "data",
  :host         => "foo-server",
  :sub          => "qa3",
  :tld          => "bar.com"
}

And, for foobaz01.qa1.bar.com:

{
  :fqdn         => "foobaz01.qa1.bar.com",
  :handler_name => "qa",
  :hostname     => "foobaz01",
  :domain       => "qa1.bar.com",
  :env          => "qa",
  :host         => "foobaz01",
  :sub          => "qa1",
  :tld          => "bar.com",
  :host_type    => "foobaz",
  :host_id      => 1
}

And, now one that baseline should catch, www01.abc.com:

{
  :fqdn         => "www01.abc.com",
  :handler_name => "baseline",
  :hostname     => "www01",
  :domain       => "abc.com",
  :host         => "www01",
  :sub          => "abc",
  :tld          => "com",
  :host_type    => "www",
  :host_id      => 1
}
=end

Contributing

  1. Fork it ( https://github.com/[my-github-username]/fqdn_facts/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request