diff --git a/.rubocop.yml b/.rubocop.yml index 231c3fe51f..51d78bc158 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -5,6 +5,7 @@ AllCops: TargetRubyVersion: 2.3 Exclude: - acceptance/**/* + - vendor/**/* require: - rubocop-performance diff --git a/acceptance/tests/external_facts/block_external_facts.rb b/acceptance/tests/external_facts/block_external_facts.rb new file mode 100644 index 0000000000..786d81b356 --- /dev/null +++ b/acceptance/tests/external_facts/block_external_facts.rb @@ -0,0 +1,37 @@ +test_name 'custom facts included in blocklist will not be displayed' do + tag 'risk:high' + + require 'facter/acceptance/user_fact_utils' + extend Facter::Acceptance::UserFactUtils + + agents.each do |agent| + ext = get_external_fact_script_extension(agent['platform']) + facts_dir = agent.tmpdir('facts.d') + fact_file = File.join(facts_dir, "external_fact_1#{ext}") + content = external_fact_content(agent['platform'], 'external_fact', 'external_value') + + config_dir = agent.tmpdir("config_dir") + config_file = File.join(config_dir, "facter.conf") + + teardown do + agent.rm_rf(facts_dir) + end + + create_remote_file(agent, config_file, <<-FILE) + facts : { blocklist : [ "external_fact_1#{ext}" ] } + FILE + + step "Agent #{agent}: setup default external facts directory and fact" do + agent.mkdir_p(facts_dir) + create_remote_file(agent, fact_file, content) + agent.chmod('+x', fact_file) + end + + step "agent #{agent}: resolve the external fact" do + on(agent, facter("--debug --external-dir \"#{facts_dir}\" --config \"#{config_file}\"")) do |facter_output| + assert_match(/External fact file external_fact_1#{ext} blocked./, facter_output.stderr.chomp, 'Expected to block the external_fact') + assert_no_match(/external_fact => external_value/, stdout, 'Expected fact not to match fact') + end + end + end +end diff --git a/lib/facter/custom_facts/util/directory_loader.rb b/lib/facter/custom_facts/util/directory_loader.rb index a8bdb8a3a8..83a6e2b617 100644 --- a/lib/facter/custom_facts/util/directory_loader.rb +++ b/lib/facter/custom_facts/util/directory_loader.rb @@ -56,6 +56,8 @@ def load_directory_entries(_collection) facts = [] entries.each do |file| basename = File.basename(file) + next if file_blocked?(basename) + if facts.find { |f| f.name == basename } && cm.group_cached?(basename) Facter.log_exception(Exception.new("Caching is enabled for group \"#{basename}\" while "\ 'there are at least two external facts files with the same filename')) @@ -107,6 +109,14 @@ def entries def should_parse?(file) File.basename(file) !~ /^\./ end + + def file_blocked?(file) + if Facter::Options[:blocked_facts].include? file + Facter.debug("External fact file #{file} blocked.") + return true + end + false + end end end end diff --git a/spec/custom_facts/util/directory_loader_spec.rb b/spec/custom_facts/util/directory_loader_spec.rb index d4c1226e09..5ff46cecbb 100755 --- a/spec/custom_facts/util/directory_loader_spec.rb +++ b/spec/custom_facts/util/directory_loader_spec.rb @@ -94,6 +94,21 @@ expect(collection.value('f1')).to eq 'higher_weight_fact' end end + + context 'when blocking external facts' do + before do + Facter::Options[:blocked_facts] = ['data.yaml'] + end + + it 'is not loading blocked file' do + data = { 'f1' => 'one', 'f2' => 'two' } + write_to_file('data.yaml', YAML.dump(data)) + + dir_loader.load(collection) + + expect(collection_double).not_to have_received(:add) + end + end end def write_to_file(file_name, to_write)