From 7f66dfd5930d04da3a2502049e46da1472ebb717 Mon Sep 17 00:00:00 2001 From: unkin-agent Date: Sun, 20 Sep 2026 23:20:15 +1000 Subject: [PATCH] Trust the estate CA when fetching ENC data from encapi Facter runs under Puppet's vendored ruby, whose OpenSSL trusts only /opt/puppetlabs/puppet/ssl/cert.pem, not the system trust store, so every node failed encapi TLS with 'unable to get local issuer certificate'. Point Net::HTTP at the CA anchor profiles::pki::vaultca installs and keep VERIFY_PEER on. --- modules/libs/lib/facter/enc_direct_facts.rb | 23 ++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/modules/libs/lib/facter/enc_direct_facts.rb b/modules/libs/lib/facter/enc_direct_facts.rb index bf0fed4..7fde380 100644 --- a/modules/libs/lib/facter/enc_direct_facts.rb +++ b/modules/libs/lib/facter/enc_direct_facts.rb @@ -3,6 +3,7 @@ require 'facter' require 'yaml' require 'net/http' +require 'openssl' require 'uri' require 'fileutils' @@ -10,6 +11,13 @@ require 'fileutils' module EncapiENC CACHE_FILE = '/var/cache/puppet_enc.yaml' CACHE_TTL = 7 * 24 * 60 * 60 # 7 days in seconds + # Facter runs under Puppet's vendored ruby, whose OpenSSL trusts only + # /opt/puppetlabs/puppet/ssl/cert.pem and never the system trust store, so the + # estate CA anchor profiles::pki::vaultca installs has to be named explicitly. + CA_BUNDLE_PATHS = [ + '/etc/pki/ca-trust/source/anchors/vaultcaroot.pem', + '/usr/local/share/ca-certificates/vaultcaroot.pem' + ].freeze @enc_data = nil # In-memory cache for the ENC response def self.read_cache @@ -29,9 +37,22 @@ module EncapiENC File.write(CACHE_FILE, cache_data.to_yaml) end + def self.ca_bundle + CA_BUNDLE_PATHS.find { |path| File.exist?(path) } + end + + def self.http_client(uri) + client = Net::HTTP.new(uri.host, uri.port) + client.use_ssl = true + client.verify_mode = OpenSSL::SSL::VERIFY_PEER + bundle = ca_bundle + client.ca_file = bundle if bundle + client + end + def self.fetch_from_encapi uri = URI("https://encapi.k8s.syd1.au.unkin.net/cblr/svc/op/puppet/hostname/#{Facter.value(:fqdn) || Facter.value(:hostname)}") - response = Net::HTTP.get_response(uri) + response = http_client(uri).request(Net::HTTP::Get.new(uri)) raise "Failed to fetch ENC data. HTTP #{response.code}" unless response.is_a?(Net::HTTPSuccess) -- 2.47.3