LEFT | RIGHT |
(no file at all) | |
| 1 #!/usr/bin/env ruby |
| 2 # This script is a node classifier for Puppet that operates on top of Hiera |
| 3 # and uses a custom hosts.yaml config to map host roles. |
| 4 |
| 5 require 'getoptlong' |
| 6 require 'hiera' |
| 7 require 'socket' |
| 8 require 'yaml' |
| 9 |
| 10 # Where to search for the Hiera configuration |
| 11 HIERA_CONFIG = ENV.fetch('PUPPET_HIERA_CONFIG', '/etc/puppet/hiera.yaml') |
| 12 # Where to search for the Hosts configuration |
| 13 HOSTS_CONFIG = ENV.fetch('PUPPET_HOSTS_CONFIG', '/etc/puppet/infrastructure/hier
a/private/hosts.yaml') |
| 14 |
| 15 # For logging and usage hints |
| 16 BASENAME = File.basename($0) |
| 17 |
| 18 # There's no need for any options beside the commonly exepected ones yet |
| 19 GetoptLong.new( |
| 20 ['--help', '-h', GetoptLong::NO_ARGUMENT] |
| 21 ).each do |opt, arg| |
| 22 case opt |
| 23 |
| 24 when '--help' |
| 25 puts <<-END |
| 26 Usage: #{BASENAME} [hostname] |
| 27 #{BASENAME} example.com |
| 28 #{BASENAME} --help |
| 29 |
| 30 Options: |
| 31 |
| 32 --help, -h |
| 33 Display this help message and exit gracefully. |
| 34 |
| 35 Environment: |
| 36 |
| 37 PUPPET_HIERA_CONFIG=#{HIERA_CONFIG} |
| 38 Where to find the hiera configuration file. |
| 39 PUPPET_HOSTS_CONFIG=#{HOSTS_CONFIG} |
| 40 Where to find the hosts configuration file. |
| 41 |
| 42 END |
| 43 exit 0 |
| 44 |
| 45 end |
| 46 end |
| 47 |
| 48 # Only one additional non-option argument is allowed, in order to explicitly |
| 49 # specify a hostname to use instead of the default: |
| 50 case ARGV.length |
| 51 when 0 |
| 52 hostname = Socket.gethostname |
| 53 when 1 |
| 54 hostname = ARGV[0][/^[^.]+/] |
| 55 else |
| 56 STDERR.puts <<-END |
| 57 #{BASENAME}: unknown option: #{ARGV[0]} |
| 58 #{BASENAME}: try #{BASENAME} --help |
| 59 END |
| 60 exit 1 |
| 61 end |
| 62 |
| 63 # Extract the server -> hostname -> role information from the hosts |
| 64 # configuration file: |
| 65 begin |
| 66 config = YAML.load_file(HOSTS_CONFIG) |
| 67 servers = config.fetch("servers", {}) |
| 68 host = servers.fetch(hostname, {}) |
| 69 role = host.fetch("role", "default") |
| 70 rescue Exception => error |
| 71 STDERR.puts "#{BASENAME}: #{error.message}: #{HOSTS_CONFIG}" |
| 72 exit 1 |
| 73 end |
| 74 |
| 75 # Map Hiera data into the structure Puppet expects an ENC to generate (see |
| 76 # https://docs.puppetlabs.com/guides/external_nodes.html for more info): |
| 77 begin |
| 78 hiera = Hiera.new(:config => HIERA_CONFIG) |
| 79 scope = {'::hostname' => hostname, '::role' => role} |
| 80 classes = hiera.lookup('classes', {}, scope, nil, :hash) |
| 81 parameters = hiera.lookup('parameters', {}, scope, nil, :hash) |
| 82 parameters['role'] = role |
| 83 result = { 'classes' => classes, 'parameters' => parameters } |
| 84 rescue Exception => error |
| 85 STDERR.puts "#{BASENAME}: #{error.message}: #{HIERA_CONFIG}" |
| 86 exit 1 |
| 87 end |
| 88 |
| 89 puts result.to_yaml |
| 90 |
LEFT | RIGHT |