diff options
author | Mike Gabriel <mike.gabriel@das-netzwerkteam.de> | 2018-09-20 14:49:52 +0200 |
---|---|---|
committer | Mike Gabriel <mike.gabriel@das-netzwerkteam.de> | 2018-09-20 14:49:52 +0200 |
commit | 774cf89157a6c5af2566d98607a8b9aa655e33b0 (patch) | |
tree | cc7a73cb9e941b0338771653bdc301c80f2e61c7 /code/environments/production/modules/stdlib/lib/facter | |
parent | 9513b93a992470e21e387db1451fa4fd21ffc5d6 (diff) | |
download | puppet.OvG-774cf89157a6c5af2566d98607a8b9aa655e33b0.tar.gz puppet.OvG-774cf89157a6c5af2566d98607a8b9aa655e33b0.tar.bz2 puppet.OvG-774cf89157a6c5af2566d98607a8b9aa655e33b0.zip |
Bundle puppetlabs-stdlib 4.25.1.
Diffstat (limited to 'code/environments/production/modules/stdlib/lib/facter')
7 files changed, 395 insertions, 0 deletions
diff --git a/code/environments/production/modules/stdlib/lib/facter/facter_dot_d.rb b/code/environments/production/modules/stdlib/lib/facter/facter_dot_d.rb new file mode 100644 index 0000000..5025ed9 --- /dev/null +++ b/code/environments/production/modules/stdlib/lib/facter/facter_dot_d.rb @@ -0,0 +1,194 @@ +# A Facter plugin that loads facts from /etc/facter/facts.d +# and /etc/puppetlabs/facter/facts.d. +# +# Facts can be in the form of JSON, YAML or Text files +# and any executable that returns key=value pairs. +# +# In the case of scripts you can also create a file that +# contains a cache TTL. For foo.sh store the ttl as just +# a number in foo.sh.ttl +# +# The cache is stored in $libdir/facts_dot_d.cache as a mode +# 600 file and will have the end result of not calling your +# fact scripts more often than is needed +class Facter::Util::DotD + require 'yaml' + + def initialize(dir = '/etc/facts.d', cache_file = File.join(Puppet[:libdir], 'facts_dot_d.cache')) + @dir = dir + @cache_file = cache_file + @cache = nil + @types = { '.txt' => :txt, '.json' => :json, '.yaml' => :yaml } + end + + def entries + Dir.entries(@dir).reject { |f| f =~ %r{^\.|\.ttl$} }.sort.map { |f| File.join(@dir, f) } + rescue + [] + end + + def fact_type(file) + extension = File.extname(file) + + type = @types[extension] || :unknown + + type = :script if type == :unknown && File.executable?(file) + + type + end + + def txt_parser(file) + File.readlines(file).each do |line| + next unless line =~ %r{^([^=]+)=(.+)$} + var = Regexp.last_match(1) + val = Regexp.last_match(2) + + Facter.add(var) do + setcode { val } + end + end + rescue StandardError => e + Facter.warn("Failed to handle #{file} as text facts: #{e.class}: #{e}") + end + + def json_parser(file) + begin + require 'json' + rescue LoadError + retry if require 'rubygems' + raise + end + + JSON.parse(File.read(file)).each_pair do |f, v| + Facter.add(f) do + setcode { v } + end + end + rescue StandardError => e + Facter.warn("Failed to handle #{file} as json facts: #{e.class}: #{e}") + end + + def yaml_parser(file) + require 'yaml' + + YAML.load_file(file).each_pair do |f, v| + Facter.add(f) do + setcode { v } + end + end + rescue StandardError => e + Facter.warn("Failed to handle #{file} as yaml facts: #{e.class}: #{e}") + end + + def script_parser(file) + result = cache_lookup(file) + ttl = cache_time(file) + + if result + Facter.debug("Using cached data for #{file}") + else + result = Facter::Util::Resolution.exec(file) + + if ttl > 0 + Facter.debug("Updating cache for #{file}") + cache_store(file, result) + cache_save! + end + end + + result.split("\n").each do |line| + next unless line =~ %r{^(.+)=(.+)$} + var = Regexp.last_match(1) + val = Regexp.last_match(2) + + Facter.add(var) do + setcode { val } + end + end + rescue StandardError => e + Facter.warn("Failed to handle #{file} as script facts: #{e.class}: #{e}") + Facter.debug(e.backtrace.join("\n\t")) + end + + def cache_save! + cache = load_cache + File.open(@cache_file, 'w', 0o600) { |f| f.write(YAML.dump(cache)) } + rescue # rubocop:disable Lint/HandleExceptions + end + + def cache_store(file, data) + load_cache + + @cache[file] = { :data => data, :stored => Time.now.to_i } + rescue # rubocop:disable Lint/HandleExceptions + end + + def cache_lookup(file) + cache = load_cache + + return nil if cache.empty? + + ttl = cache_time(file) + + return nil unless cache[file] + now = Time.now.to_i + + return cache[file][:data] if ttl == -1 + return cache[file][:data] if (now - cache[file][:stored]) <= ttl + return nil + rescue + return nil + end + + def cache_time(file) + meta = file + '.ttl' + + return File.read(meta).chomp.to_i + rescue + return 0 + end + + def load_cache + @cache ||= if File.exist?(@cache_file) + YAML.load_file(@cache_file) + else + {} + end + + return @cache + rescue + @cache = {} + return @cache + end + + def create + entries.each do |fact| + type = fact_type(fact) + parser = "#{type}_parser" + + next unless respond_to?("#{type}_parser") + Facter.debug("Parsing #{fact} using #{parser}") + + send(parser, fact) + end + end +end + +mdata = Facter.version.match(%r{(\d+)\.(\d+)\.(\d+)}) +if mdata + (major, minor, _patch) = mdata.captures.map { |v| v.to_i } + if major < 2 + # Facter 1.7 introduced external facts support directly + unless major == 1 && minor > 6 + Facter::Util::DotD.new('/etc/facter/facts.d').create + Facter::Util::DotD.new('/etc/puppetlabs/facter/facts.d').create + + # Windows has a different configuration directory that defaults to a vendor + # specific sub directory of the %COMMON_APPDATA% directory. + if Dir.const_defined? 'COMMON_APPDATA' # rubocop:disable Metrics/BlockNesting : Any attempt to alter this breaks it + windows_facts_dot_d = File.join(Dir::COMMON_APPDATA, 'PuppetLabs', 'facter', 'facts.d') + Facter::Util::DotD.new(windows_facts_dot_d).create + end + end + end +end diff --git a/code/environments/production/modules/stdlib/lib/facter/package_provider.rb b/code/environments/production/modules/stdlib/lib/facter/package_provider.rb new file mode 100644 index 0000000..0aec171 --- /dev/null +++ b/code/environments/production/modules/stdlib/lib/facter/package_provider.rb @@ -0,0 +1,21 @@ +# Fact: package_provider +# +# Purpose: Returns the default provider Puppet will choose to manage packages +# on this system +# +# Resolution: Instantiates a dummy package resource and return the provider +# +# Caveats: +# +require 'puppet/type' +require 'puppet/type/package' + +Facter.add(:package_provider) do + setcode do + if defined? Gem && Gem::Version.new(Facter.value(:puppetversion).split(' ')[0]) >= Gem::Version.new('3.6') + Puppet::Type.type(:package).newpackage(:name => 'dummy', :allow_virtual => 'true')[:provider].to_s + else + Puppet::Type.type(:package).newpackage(:name => 'dummy')[:provider].to_s + end + end +end diff --git a/code/environments/production/modules/stdlib/lib/facter/pe_version.rb b/code/environments/production/modules/stdlib/lib/facter/pe_version.rb new file mode 100644 index 0000000..594f9dc --- /dev/null +++ b/code/environments/production/modules/stdlib/lib/facter/pe_version.rb @@ -0,0 +1,61 @@ +# Fact: is_pe, pe_version, pe_major_version, pe_minor_version, pe_patch_version +# +# Purpose: Return various facts about the PE state of the system +# +# Resolution: Uses a regex match against puppetversion to determine whether the +# machine has Puppet Enterprise installed, and what version (overall, major, +# minor, patch) is installed. +# +# Caveats: +# +Facter.add('pe_version') do + setcode do + puppet_ver = Facter.value('puppetversion') + if !puppet_ver.nil? + pe_ver = puppet_ver.match(%r{Puppet Enterprise (\d+\.\d+\.\d+)}) + pe_ver[1] if pe_ver + else + nil + end + end +end + +Facter.add('is_pe') do + setcode do + if Facter.value(:pe_version).to_s.empty? + false + else + true + end + end +end + +Facter.add('pe_major_version') do + confine :is_pe => true + setcode do + pe_version = Facter.value(:pe_version) + if pe_version + pe_version.to_s.split('.')[0] + end + end +end + +Facter.add('pe_minor_version') do + confine :is_pe => true + setcode do + pe_version = Facter.value(:pe_version) + if pe_version + pe_version.to_s.split('.')[1] + end + end +end + +Facter.add('pe_patch_version') do + confine :is_pe => true + setcode do + pe_version = Facter.value(:pe_version) + if pe_version + pe_version.to_s.split('.')[2] + end + end +end diff --git a/code/environments/production/modules/stdlib/lib/facter/puppet_settings.rb b/code/environments/production/modules/stdlib/lib/facter/puppet_settings.rb new file mode 100644 index 0000000..b932189 --- /dev/null +++ b/code/environments/production/modules/stdlib/lib/facter/puppet_settings.rb @@ -0,0 +1,42 @@ +# These facter facts return the value of the Puppet vardir and environment path +# settings for the node running puppet or puppet agent. The intent is to +# enable Puppet modules to automatically have insight into a place where they +# can place variable data, or for modules running on the puppet master to know +# where environments are stored. +# +# The values should be directly usable in a File resource path attribute. +# +begin + require 'facter/util/puppet_settings' +rescue LoadError => e + # puppet apply does not add module lib directories to the $LOAD_PATH (See + # #4248). It should (in the future) but for the time being we need to be + # defensive which is what this rescue block is doing. + rb_file = File.join(File.dirname(__FILE__), 'util', 'puppet_settings.rb') + load rb_file if File.exist?(rb_file) || raise(e) +end + +# These will be nil if Puppet is not available. +Facter.add(:puppet_vardir) do + setcode do + Facter::Util::PuppetSettings.with_puppet do + Puppet[:vardir] + end + end +end + +Facter.add(:puppet_environmentpath) do + setcode do + Facter::Util::PuppetSettings.with_puppet do + Puppet[:environmentpath] + end + end +end + +Facter.add(:puppet_server) do + setcode do + Facter::Util::PuppetSettings.with_puppet do + Puppet[:server] + end + end +end diff --git a/code/environments/production/modules/stdlib/lib/facter/root_home.rb b/code/environments/production/modules/stdlib/lib/facter/root_home.rb new file mode 100644 index 0000000..d4add7b --- /dev/null +++ b/code/environments/production/modules/stdlib/lib/facter/root_home.rb @@ -0,0 +1,44 @@ +# A facter fact to determine the root home directory. +# This varies on PE supported platforms and may be +# reconfigured by the end user. +module Facter::Util::RootHome + class << self + def returnt_root_home + root_ent = Facter::Util::Resolution.exec('getent passwd root') + # The home directory is the sixth element in the passwd entry + # If the platform doesn't have getent, root_ent will be nil and we should + # return it straight away. + root_ent && root_ent.split(':')[5] + end + end +end + +Facter.add(:root_home) do + setcode { Facter::Util::RootHome.returnt_root_home } +end + +Facter.add(:root_home) do + confine :kernel => :darwin + setcode do + str = Facter::Util::Resolution.exec('dscacheutil -q user -a name root') + hash = {} + str.split("\n").each do |pair| + key, value = pair.split(%r{:}) + hash[key] = value + end + hash['dir'].strip + end +end + +Facter.add(:root_home) do + confine :kernel => :aix + root_home = nil + setcode do + str = Facter::Util::Resolution.exec('lsuser -c -a home root') + str && str.split("\n").each do |line| + next if line =~ %r{^#} + root_home = line.split(%r{:})[1] + end + root_home + end +end diff --git a/code/environments/production/modules/stdlib/lib/facter/service_provider.rb b/code/environments/production/modules/stdlib/lib/facter/service_provider.rb new file mode 100644 index 0000000..a117921 --- /dev/null +++ b/code/environments/production/modules/stdlib/lib/facter/service_provider.rb @@ -0,0 +1,17 @@ +# Fact: service_provider +# +# Purpose: Returns the default provider Puppet will choose to manage services +# on this system +# +# Resolution: Instantiates a dummy service resource and return the provider +# +# Caveats: +# +require 'puppet/type' +require 'puppet/type/service' + +Facter.add(:service_provider) do + setcode do + Puppet::Type.type(:service).newservice(:name => 'dummy')[:provider].to_s + end +end diff --git a/code/environments/production/modules/stdlib/lib/facter/util/puppet_settings.rb b/code/environments/production/modules/stdlib/lib/facter/util/puppet_settings.rb new file mode 100644 index 0000000..d12e92c --- /dev/null +++ b/code/environments/production/modules/stdlib/lib/facter/util/puppet_settings.rb @@ -0,0 +1,16 @@ +# A method to evaluate a Facter code block if puppet is loaded. +module Facter::Util::PuppetSettings + # This method is intended to provide a convenient way to evaluate a + # Facter code block only if Puppet is loaded. This is to account for the + # situation where the fact happens to be in the load path, but Puppet is + # not loaded for whatever reason. Perhaps the user is simply running + # facter without the --puppet flag and they happen to be working in a lib + # directory of a module. + def self.with_puppet + Module.const_get('Puppet') + rescue NameError + nil + else + yield + end +end |