Skip to content
This repository has been archived by the owner on Jun 19, 2020. It is now read-only.

Commit

Permalink
(FACT-2515) Define custom fact groups in facter.conf
Browse files Browse the repository at this point in the history
  • Loading branch information
florindragos committed May 6, 2020
1 parent 9933642 commit fee408b
Show file tree
Hide file tree
Showing 12 changed files with 95 additions and 43 deletions.
4 changes: 4 additions & 0 deletions facter.conf
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,7 @@ cli : {
verbose : false,
log-level : "warn"
}

fact-groups : {
cached-custom-facts : ["my_custom_fact"],
}
3 changes: 1 addition & 2 deletions lib/facter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,6 @@ def to_user_output(cli_options, *args)
Facter::Options.init_from_cli(cli_options, args)
@logger.info("executed with command line: #{ARGV.drop(1).join(' ')}")
log_blocked_facts

resolved_facts = Facter::FactManager.instance.resolve_facts(args)
SessionCache.invalidate_all_caches
fact_formatter = Facter::FormatterFactory.build(Facter::Options.get)
Expand Down Expand Up @@ -324,7 +323,7 @@ def error_check(args, resolved_facts)
#
# @api private
def log_blocked_facts
block_list = Facter::FactGroups.new(Facter::Options[:config]).block_list
block_list = Options[:block_list]
return unless block_list.any? && Facter::Options[:block]

@logger.debug("blocking collection of #{block_list.join("\s")} facts")
Expand Down
4 changes: 4 additions & 0 deletions lib/framework/config/config_reader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ def cli
@conf['cli']
end

def fact_groups
@conf['fact-groups']
end

def refresh_config(config_path)
@conf = File.readable?(config_path) ? Hocon.load(config_path) : {}
end
Expand Down
3 changes: 2 additions & 1 deletion lib/framework/config/fact_groups.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ def get_group_ttls(group_name)
def load_groups
config = ConfigReader.init(Options[:config])
@block_list = config.block_list || {}
@groups_ttls = ConfigReader.init(Options[:config]).ttls || {}
@groups_ttls = config.ttls || {}
@groups.merge!(config.fact_groups) if config.fact_groups
end

def ttls_to_seconds(ttls)
Expand Down
32 changes: 15 additions & 17 deletions lib/framework/core/cache_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,11 @@ def initialize
@groups = {}
@log = Log.new(self)
@fact_groups = Facter::FactGroups.new
end

def cache_dir
LegacyFacter::Util::Config.facts_cache_dir
@cache_dir = LegacyFacter::Util::Config.facts_cache_dir
end

def resolve_facts(searched_facts)
return searched_facts, [] if !File.directory?(cache_dir) || !Options[:cache]
return searched_facts, [] if !File.directory?(@cache_dir) || !Options[:cache]

facts = []
searched_facts.each do |fact|
Expand Down Expand Up @@ -73,24 +70,24 @@ def cache_fact(fact)
end

def write_cache
unless File.directory?(cache_dir)
unless File.directory?(@cache_dir)
require 'fileutils'
FileUtils.mkdir_p(cache_dir)
FileUtils.mkdir_p(@cache_dir)
end

@groups.each do |group_name, data|
next if check_ttls(group_name).zero?

@log.debug("caching values for #{group_name} facts")
cache_file_name = File.join(cache_dir, group_name)
cache_file_name = File.join(@cache_dir, group_name)
File.write(cache_file_name, JSON.pretty_generate(data))
end
end

def read_group_json(group_name)
return @groups[group_name] if @groups.key?(group_name)

cache_file_name = File.join(cache_dir, group_name)
cache_file_name = File.join(@cache_dir, group_name)
data = nil
file = Util::FileHelper.safe_read(cache_file_name)
begin
Expand All @@ -111,20 +108,21 @@ def check_ttls(group_name)
ttls = @fact_groups.get_group_ttls(group_name)
return 0 unless ttls

cache_file_name = File.join(cache_dir, group_name)
return ttls unless File.readable?(cache_file_name)
cache_file_name = File.join(@cache_dir, group_name)
if File.readable?(cache_file_name)
file_time = File.mtime(cache_file_name)
expire_date = file_time + ttls
return expire_date.to_i unless expire_date < Time.now

file_time = File.mtime(cache_file_name)
expire_date = file_time + ttls
if expire_date < Time.now
File.delete(cache_file_name)
return ttls
end
expire_date.to_i

@log.debug("#{group_name} facts cache file expired/missing")
ttls
end

def delete_cache(group_name)
cache_file_name = File.join(cache_dir, group_name)
cache_file_name = File.join(@cache_dir, group_name)
File.delete(cache_file_name) if File.readable?(cache_file_name)
end
end
Expand Down
29 changes: 19 additions & 10 deletions lib/framework/core/options/config_file_options.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,26 @@ def init(config_path = nil)

augment_config_path(config_path)

augment_all
end

def get
@options || {}
end

private

def augment_all
if Options.cli?
augment_cli(Facter::ConfigReader.cli)
augment_ruby(Facter::ConfigReader.global)
end
augment_custom(Facter::ConfigReader.global)
augment_external(Facter::ConfigReader.global)
augment_show_legacy(Facter::ConfigReader.global)
augment_facts(Facter::ConfigReader.ttls)
augment_facts(Facter::ConfigReader.ttls, Facter::ConfigReader.fact_groups)
end

def get
@options || {}
end

private

def augment_config_path(config_path)
@options[:config] = config_path
end
Expand Down Expand Up @@ -72,11 +76,16 @@ def augment_show_legacy(global_conf)
@options[:show_legacy] = global_conf['show-legacy'] unless global_conf['show-legacy'].nil?
end

def augment_facts(ttls)
blocked_facts = Facter::FactGroups.new.blocked_facts
@options[:blocked_facts] = blocked_facts unless blocked_facts.nil?
def augment_facts(ttls, groups)
fact_groups = Facter::FactGroups.new

@options[:blocked_facts] = fact_groups.blocked_facts unless fact_groups.blocked_facts.nil?
@options[:block_list] = fact_groups.block_list
@options[:ttls] = ttls unless ttls.nil?

f_groups = fact_groups.groups || {}
f_groups = groups.merge(f_groups) unless groups.nil?
@options[:fact_groups] = f_groups
end
end
end
Expand Down
19 changes: 14 additions & 5 deletions lib/framework/core/options/option_store.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,17 @@ class OptionStore
@cache = true
@blocked_facts = []
@user_query = []
@block_list = {}
@fact_groups = {}

class << self
attr_reader :debug, :verbose, :log_level, :show_legacy, :trace, :ruby,
:custom_facts, :blocked_facts

attr_accessor :config, :user_query, :strict, :json, :haml, :external_facts,
:cache, :yaml, :puppet, :ttls, :block, :cli, :config_file_custom_dir,
:config_file_external_dir, :default_external_dir
:config_file_external_dir, :default_external_dir, :fact_groups,
:block_list

attr_writer :external_dir

Expand Down Expand Up @@ -152,16 +155,22 @@ def reset
@log_level = :warn
@show_legacy = true
@block = true
@ruby = true
@user_query = []
@cli = nil
@cache = true
reset_config
end

def reset_config
@custom_dir = []
@custom_facts = true
@external_dir = []
@default_external_dir = []
@external_facts = true
@ruby = true
@blocked_facts = []
@user_query = []
@cli = nil
@cache = true
@fact_groups = {}
@block_list = {}
end

def fallback_external_dir
Expand Down
9 changes: 4 additions & 5 deletions spec/facter/facter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,17 @@
let(:fact_collection_spy) { instance_spy(Facter::FactCollection) }
let(:key_error) { KeyError.new('key error') }
let(:config_reader_double) { double(Facter::ConfigReader) }
let(:block_list_double) { instance_spy(Facter::FactGroups) }

before do
allow(Facter::ConfigReader).to receive(:init).and_return(config_reader_double)
allow(config_reader_double).to receive(:cli).and_return(nil)
allow(config_reader_double).to receive(:global).and_return(nil)
allow(config_reader_double).to receive(:ttls).and_return([])
allow(config_reader_double).to receive(:block_list).and_return([])
allow(config_reader_double).to receive(:fact_groups).and_return({})

allow(Facter::FactGroups).to receive(:instance).and_return(block_list_double)
allow(block_list_double).to receive(:blocked_facts).and_return([])
allow(block_list_double).to receive(:block_list).and_return([])
allow(Facter::Options).to receive(:[]).and_call_original
allow(Facter::Options).to receive(:[]).with(:block_list).and_return([])

Facter.instance_variable_set(:@logger, logger)
Facter.clear
Expand Down Expand Up @@ -99,7 +98,6 @@ def mock_collection(method, os_name = nil, error = nil)
it 'returns no fact and status 1', resolved_fact: false do
user_query = ['os.name', 'missing_fact']
expected_json_output = '{}'
allow(Facter::Options).to receive(:[]).and_call_original
allow(Facter::Options).to receive(:[]).with(:strict).and_return(true)
allow(OsDetector).to receive(:detect).and_return(:solaris)

Expand All @@ -112,6 +110,7 @@ def mock_collection(method, os_name = nil, error = nil)
user_query = 'os.name'
expected_json_output = '{"os" : {"name": "ubuntu"}'
allow(Facter::Options).to receive(:[]).with(anything)
allow(Facter::Options).to receive(:[]).with(:block_list).and_return([])
allow(Facter::Options).to receive(:[]).with(:strict).and_return(true)

formated_facts = Facter.to_user_output({}, user_query)
Expand Down
3 changes: 0 additions & 3 deletions spec/facter/resolvers/utils/windows/network_utils_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@
let(:address) { double(FFI::MemoryPointer) }
let(:error) { 0 }

before do
end

it 'returns an address' do
expect(NetworkUtils.address_to_string(addr)).to eql('10.123.0.2')
end
Expand Down
29 changes: 29 additions & 0 deletions spec/framework/config/config_reader_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -159,4 +159,33 @@
end
end
end

describe '#fact-groups' do
let(:os) { :linux }

before do
allow(File).to receive(:readable?).and_return(true)
allow(Hocon).to receive(:load).and_return(config)
end

context 'with empty config file' do
let(:config) { {} }

it 'returns nil' do
config_reader.init

expect(config_reader.fact_groups).to eq(nil)
end
end

context 'with fact-groups in config file' do
let(:config) { { 'fact-groups' => { 'cached-custom-facts' => ['my_custom_fact'] } } }

it 'returns fact-groups' do
config_reader.init

expect(config_reader.fact_groups).to eq('cached-custom-facts' => ['my_custom_fact'])
end
end
end
end
1 change: 1 addition & 0 deletions spec/framework/config/fact_groups_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
allow(Facter::ConfigReader).to receive(:init).and_return(config_reader)
allow(config_reader).to receive(:block_list).and_return([])
allow(config_reader).to receive(:ttls).and_return([])
allow(config_reader).to receive(:fact_groups).and_return({})
end

describe '#initialize' do
Expand Down
2 changes: 2 additions & 0 deletions spec/framework/core/options/option_store_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
it 'returns default values' do
expect(option_store.all).to eq(
block: true,
block_list: {},
blocked_facts: [],
cli: nil,
custom_dir: [],
Expand All @@ -25,6 +26,7 @@
config_file_external_dir: [],
default_external_dir: [],
external_facts: true,
fact_groups: {},
log_level: :warn,
ruby: true,
show_legacy: true,
Expand Down

0 comments on commit fee408b

Please sign in to comment.