From 0a9b4ecbd29473bf3a425e1052d7ccb66c739540 Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Wed, 12 Mar 2025 22:29:26 +1100 Subject: [PATCH] feat: change enc_* fact to read direct from cobbler - change enc_role and enc_env to read direct from cobbler - cleanup profiles::base::facts --- .reek.yml | 5 ++ modules/libs/lib/facter/enc_direct_facts.rb | 74 +++++++++++++++++++ modules/libs/lib/facter/enc_env.rb | 13 ---- modules/libs/lib/facter/enc_role.rb | 13 ---- site/profiles/manifests/base.pp | 1 - site/profiles/manifests/base/facts.pp | 39 ---------- site/profiles/manifests/firstrun/init.pp | 3 +- .../base/facts/custom_facts.yaml.erb | 3 - .../profiles/templates/base/facts/enc_env.erb | 1 - .../templates/base/facts/enc_role.erb | 1 - 10 files changed, 80 insertions(+), 73 deletions(-) create mode 100644 modules/libs/lib/facter/enc_direct_facts.rb delete mode 100644 modules/libs/lib/facter/enc_env.rb delete mode 100644 modules/libs/lib/facter/enc_role.rb delete mode 100644 site/profiles/manifests/base/facts.pp delete mode 100644 site/profiles/templates/base/facts/custom_facts.yaml.erb delete mode 100644 site/profiles/templates/base/facts/enc_env.erb delete mode 100644 site/profiles/templates/base/facts/enc_role.erb diff --git a/.reek.yml b/.reek.yml index 5d9b3c5..26c981b 100644 --- a/.reek.yml +++ b/.reek.yml @@ -3,3 +3,8 @@ detectors: FeatureEnvy: enabled: false + TooManyStatements: + enabled: false + UncommunicativeVariableName: + accept: + - e diff --git a/modules/libs/lib/facter/enc_direct_facts.rb b/modules/libs/lib/facter/enc_direct_facts.rb new file mode 100644 index 0000000..3aec01b --- /dev/null +++ b/modules/libs/lib/facter/enc_direct_facts.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +require 'facter' +require 'yaml' +require 'net/http' +require 'uri' +require 'fileutils' + +# CobblerENC module: Fetches ENC data from Cobbler, caches it, and provides structured facts. +module CobblerENC + CACHE_FILE = '/var/cache/puppet_enc.yaml' + CACHE_TTL = 7 * 24 * 60 * 60 # 7 days in seconds + @enc_data = nil # In-memory cache for the ENC response + + def self.read_cache + return {} unless File.exist?(CACHE_FILE) + + cache_data = YAML.safe_load(File.read(CACHE_FILE)) || {} + timestamp = cache_data.fetch('timestamp', 0) + + return cache_data if Time.now.to_i - timestamp < CACHE_TTL + + {} + end + + def self.write_cache(enc_data) + FileUtils.mkdir_p(File.dirname(CACHE_FILE)) + cache_data = enc_data.merge({ 'timestamp' => Time.now.to_i }) + File.write(CACHE_FILE, cache_data.to_yaml) + end + + def self.fetch_from_cobbler + uri = URI("http://cobbler.main.unkin.net/cblr/svc/op/puppet/hostname/#{Facter.value(:fqdn) || Facter.value(:hostname)}") + response = Net::HTTP.get_response(uri) + + raise "Failed to fetch ENC data. HTTP #{response.code}" unless response.is_a?(Net::HTTPSuccess) + + YAML.safe_load(response.body) || {} + end + + def self.retrieve_enc_data + return @enc_data if @enc_data + + @enc_data = fetch_from_cobbler + write_cache(@enc_data) + @enc_data + end + + def self.fetch_enc_data + retrieve_enc_data + rescue StandardError => e + Facter.warn("Error retrieving Cobbler ENC data: #{e.message}") + @enc_data = read_cache + return @enc_data unless @enc_data.empty? + + raise 'No cached ENC data available and Cobbler is down.' + end + + def self.enc_role + fetch_enc_data.fetch('classes', {}).keys.first || raise('ENC Role not found in Cobbler ENC response') + end + + def self.enc_env + fetch_enc_data.fetch('environment', nil) || raise('ENC Environment not found in Cobbler ENC response') + end +end + +Facter.add('enc_role') do + setcode { CobblerENC.enc_role } +end + +Facter.add('enc_env') do + setcode { CobblerENC.enc_env } +end diff --git a/modules/libs/lib/facter/enc_env.rb b/modules/libs/lib/facter/enc_env.rb deleted file mode 100644 index 2975c45..0000000 --- a/modules/libs/lib/facter/enc_env.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -Facter.add('enc_env') do - setcode do - require 'yaml' - # Check if the YAML file exists - if File.exist?('/root/.cache/custom_facts.yaml') - data = YAML.load_file('/root/.cache/custom_facts.yaml') - # Use safe navigation to return 'enc_env' or nil - data&.dig('enc_env') - end - end -end diff --git a/modules/libs/lib/facter/enc_role.rb b/modules/libs/lib/facter/enc_role.rb deleted file mode 100644 index 979b4bf..0000000 --- a/modules/libs/lib/facter/enc_role.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -Facter.add('enc_role') do - setcode do - require 'yaml' - # Check if the YAML file exists - if File.exist?('/root/.cache/custom_facts.yaml') - data = YAML.load_file('/root/.cache/custom_facts.yaml') - # Use safe navigation to return 'enc_role' or nil - data&.dig('enc_role') - end - end -end diff --git a/site/profiles/manifests/base.pp b/site/profiles/manifests/base.pp index 7eec9ab..fd4188e 100644 --- a/site/profiles/manifests/base.pp +++ b/site/profiles/manifests/base.pp @@ -22,7 +22,6 @@ class profiles::base ( # include the base profiles include profiles::base::repos include profiles::packages - include profiles::base::facts include profiles::base::motd include profiles::base::scripts include profiles::base::hosts diff --git a/site/profiles/manifests/base/facts.pp b/site/profiles/manifests/base/facts.pp deleted file mode 100644 index 5344d19..0000000 --- a/site/profiles/manifests/base/facts.pp +++ /dev/null @@ -1,39 +0,0 @@ -# a class to define some global facts -class profiles::base::facts { - - # The path where external facts are stored - $facts_d_path = '/opt/puppetlabs/facter/facts.d' - - # Ensure the directory exists - file { $facts_d_path: - ensure => directory, - owner => 'root', - group => 'root', - mode => '0755', - } - - # cleanup old facts files - $fact_list = [ 'enc_role', 'enc_env' ] - $fact_list.each | String $item | { - file { "${facts_d_path}/${item}.txt": - ensure => absent, - } - } - - # ensure the path to the custom store exists - file { '/root/.cache': - ensure => directory, - owner => 'root', - group => 'root', - mode => '0750', - } - - # create the file that will be read - file { '/root/.cache/custom_facts.yaml': - ensure => file, - owner => 'root', - group => 'root', - mode => '0644', - content => template('profiles/base/facts/custom_facts.yaml.erb'), - } -} diff --git a/site/profiles/manifests/firstrun/init.pp b/site/profiles/manifests/firstrun/init.pp index 3b33622..cdb70e7 100644 --- a/site/profiles/manifests/firstrun/init.pp +++ b/site/profiles/manifests/firstrun/init.pp @@ -8,8 +8,7 @@ class profiles::firstrun::init { include profiles::base::repos include profiles::firstrun::packages - # set the motd and base facts - include profiles::base::facts + # set the motd include profiles::base::motd # create the sysadmin account diff --git a/site/profiles/templates/base/facts/custom_facts.yaml.erb b/site/profiles/templates/base/facts/custom_facts.yaml.erb deleted file mode 100644 index e4b3895..0000000 --- a/site/profiles/templates/base/facts/custom_facts.yaml.erb +++ /dev/null @@ -1,3 +0,0 @@ ---- -enc_role: <%= @enc_role[0] %> -enc_env: <%= @enc_env %> diff --git a/site/profiles/templates/base/facts/enc_env.erb b/site/profiles/templates/base/facts/enc_env.erb deleted file mode 100644 index 7695e4d..0000000 --- a/site/profiles/templates/base/facts/enc_env.erb +++ /dev/null @@ -1 +0,0 @@ -enc_env=<%= @enc_env %> diff --git a/site/profiles/templates/base/facts/enc_role.erb b/site/profiles/templates/base/facts/enc_role.erb deleted file mode 100644 index d59acdf..0000000 --- a/site/profiles/templates/base/facts/enc_role.erb +++ /dev/null @@ -1 +0,0 @@ -enc_role=<%= @enc_role[0] %> -- 2.47.3