facter 4.0.15 → 4.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/.rubocop.yml +1 -0
 - data/.rubocop_todo.yml +5 -7
 - data/CHANGELOG.md +33 -0
 - data/VERSION +1 -1
 - data/lib/custom_facts/util/parser.rb +1 -1
 - data/lib/custom_facts/version.rb +1 -1
 - data/lib/facter.rb +13 -17
 - data/lib/facts/aix/partitions.rb +15 -0
 - data/lib/facts/windows/ssh.rb +27 -0
 - data/lib/facts_utils/uptime_parser.rb +3 -3
 - data/lib/framework/cli/cli.rb +1 -1
 - data/lib/framework/config/block_list.rb +1 -4
 - data/lib/framework/config/config_reader.rb +29 -26
 - data/lib/framework/core/fact_filter.rb +2 -2
 - data/lib/framework/core/file_loader.rb +3 -3
 - data/lib/framework/core/options.rb +57 -64
 - data/lib/framework/core/options/config_file_options.rb +58 -48
 - data/lib/framework/core/options/option_store.rb +156 -0
 - data/lib/framework/core/options/options_validator.rb +42 -2
 - data/lib/framework/logging/logger.rb +2 -0
 - data/lib/framework/parsers/query_parser.rb +1 -1
 - data/lib/models/fact_collection.rb +1 -1
 - data/lib/resolvers/aix/filesystem_resolver.rb +3 -2
 - data/lib/resolvers/aix/partitions.rb +86 -0
 - data/lib/resolvers/aix/utils/odm_query.rb +2 -2
 - data/lib/resolvers/debian_version.rb +2 -5
 - data/lib/resolvers/disk_resolver.rb +2 -3
 - data/lib/resolvers/dmi_resolver.rb +3 -3
 - data/lib/resolvers/filesystems_resolver.rb +3 -3
 - data/lib/resolvers/fips_enabled_resolver.rb +1 -4
 - data/lib/resolvers/hostname_resolver.rb +4 -4
 - data/lib/resolvers/load_averages_resolver.rb +1 -3
 - data/lib/resolvers/memory_resolver.rb +2 -2
 - data/lib/resolvers/mountpoints_resolver.rb +1 -3
 - data/lib/resolvers/os_release_resolver.rb +3 -6
 - data/lib/resolvers/partitions.rb +11 -6
 - data/lib/resolvers/processors_resolver.rb +3 -3
 - data/lib/resolvers/selinux_resolver.rb +9 -9
 - data/lib/resolvers/solaris/filesystems_resolver.rb +1 -1
 - data/lib/resolvers/ssh_resolver.rb +4 -43
 - data/lib/resolvers/utils/ssh_helper.rb +27 -0
 - data/lib/resolvers/windows/ssh.rb +47 -0
 - data/lib/util/file_helper.rb +24 -0
 - metadata +9 -6
 - data/lib/framework/core/options/default_options.rb +0 -35
 - data/lib/framework/core/options/helper_options.rb +0 -52
 - data/lib/framework/core/options/priority_options.rb +0 -12
 - data/lib/framework/core/options/validate_options.rb +0 -49
 
| 
         @@ -27,9 +27,9 @@ module Facter 
     | 
|
| 
       27 
27 
     | 
    
         
             
                def execute
         
     | 
| 
       28 
28 
     | 
    
         
             
                  result = nil
         
     | 
| 
       29 
29 
     | 
    
         
             
                  REPOS.each do |repo|
         
     | 
| 
       30 
     | 
    
         
            -
                    break if result
         
     | 
| 
      
 30 
     | 
    
         
            +
                    break if result && !result.empty?
         
     | 
| 
       31 
31 
     | 
    
         | 
| 
       32 
     | 
    
         
            -
                    result, _s = Open3. 
     | 
| 
      
 32 
     | 
    
         
            +
                    result, _stderr, _s = Open3.capture3("#{query} #{repo}")
         
     | 
| 
       33 
33 
     | 
    
         
             
                  end
         
     | 
| 
       34 
34 
     | 
    
         
             
                  result
         
     | 
| 
       35 
35 
     | 
    
         
             
                end
         
     | 
| 
         @@ -18,11 +18,8 @@ module Facter 
     | 
|
| 
       18 
18 
     | 
    
         
             
                    end
         
     | 
| 
       19 
19 
     | 
    
         | 
| 
       20 
20 
     | 
    
         
             
                    def read_debian_version(fact_name)
         
     | 
| 
       21 
     | 
    
         
            -
                       
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
                      verion = File.read('/etc/debian_version')
         
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
                      @fact_list[:version] = verion.strip
         
     | 
| 
      
 21 
     | 
    
         
            +
                      file_content = Util::FileHelper.safe_read('/etc/debian_version')
         
     | 
| 
      
 22 
     | 
    
         
            +
                      @fact_list[:version] = file_content.strip unless file_content.empty?
         
     | 
| 
       26 
23 
     | 
    
         | 
| 
       27 
24 
     | 
    
         
             
                      @fact_list[fact_name]
         
     | 
| 
       28 
25 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -23,9 +23,8 @@ module Facter 
     | 
|
| 
       23 
23 
     | 
    
         
             
                          @fact_list[:disks].each do |disk, value|
         
     | 
| 
       24 
24 
     | 
    
         
             
                            file_path = File.join(DIR, disk, file)
         
     | 
| 
       25 
25 
     | 
    
         | 
| 
       26 
     | 
    
         
            -
                             
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
                            result = File.read(file_path).strip
         
     | 
| 
      
 26 
     | 
    
         
            +
                            result = Util::FileHelper.safe_read(file_path).strip
         
     | 
| 
      
 27 
     | 
    
         
            +
                            next if result.empty?
         
     | 
| 
       29 
28 
     | 
    
         | 
| 
       30 
29 
     | 
    
         
             
                            # Linux always considers sectors to be 512 bytes long independently of the devices real block size.
         
     | 
| 
       31 
30 
     | 
    
         
             
                            value[key] = file =~ /size/ ? construct_size(value, result) : result
         
     | 
| 
         @@ -28,15 +28,15 @@ module Facter 
     | 
|
| 
       28 
28 
     | 
    
         
             
                        @fact_list.fetch(fact_name) { read_facts(fact_name) }
         
     | 
| 
       29 
29 
     | 
    
         
             
                      end
         
     | 
| 
       30 
30 
     | 
    
         | 
| 
       31 
     | 
    
         
            -
                      # File.read("/sys/class/dmi/id/#{file}")
         
     | 
| 
       32 
31 
     | 
    
         
             
                      def read_facts(fact_name)
         
     | 
| 
       33 
32 
     | 
    
         
             
                        files = %w[bios_date bios_vendor bios_version board_vendor board_name board_serial
         
     | 
| 
       34 
33 
     | 
    
         
             
                                   chassis_asset_tag chassis_type sys_vendor product_name product_serial
         
     | 
| 
       35 
34 
     | 
    
         
             
                                   product_uuid]
         
     | 
| 
       36 
35 
     | 
    
         
             
                        return unless File.directory?('/sys/class/dmi')
         
     | 
| 
       37 
36 
     | 
    
         | 
| 
       38 
     | 
    
         
            -
                         
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
      
 37 
     | 
    
         
            +
                        file_content = Util::FileHelper.safe_read("/sys/class/dmi/id/#{fact_name}", nil)
         
     | 
| 
      
 38 
     | 
    
         
            +
                        if files.include?(fact_name.to_s) && file_content
         
     | 
| 
      
 39 
     | 
    
         
            +
                          @fact_list[fact_name] = file_content.strip
         
     | 
| 
       40 
40 
     | 
    
         
             
                          chassis_to_name(@fact_list[fact_name]) if fact_name == :chassis_type
         
     | 
| 
       41 
41 
     | 
    
         | 
| 
       42 
42 
     | 
    
         
             
                        end
         
     | 
| 
         @@ -16,11 +16,11 @@ module Facter 
     | 
|
| 
       16 
16 
     | 
    
         
             
                      end
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
       18 
18 
     | 
    
         
             
                      def read_filesystems(fact_name)
         
     | 
| 
       19 
     | 
    
         
            -
                         
     | 
| 
      
 19 
     | 
    
         
            +
                        output = Util::FileHelper.safe_readlines('/proc/filesystems', nil)
         
     | 
| 
      
 20 
     | 
    
         
            +
                        return unless output
         
     | 
| 
       20 
21 
     | 
    
         | 
| 
       21 
     | 
    
         
            -
                        output = File.read('/proc/filesystems')
         
     | 
| 
       22 
22 
     | 
    
         
             
                        filesystems = []
         
     | 
| 
       23 
     | 
    
         
            -
                        output. 
     | 
| 
      
 23 
     | 
    
         
            +
                        output.each do |line|
         
     | 
| 
       24 
24 
     | 
    
         
             
                          tokens = line.split(' ')
         
     | 
| 
       25 
25 
     | 
    
         
             
                          filesystems << tokens if tokens.size == 1
         
     | 
| 
       26 
26 
     | 
    
         
             
                        end
         
     | 
| 
         @@ -16,10 +16,7 @@ module Facter 
     | 
|
| 
       16 
16 
     | 
    
         
             
                      end
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
       18 
18 
     | 
    
         
             
                      def read_fips_file(fact_name)
         
     | 
| 
       19 
     | 
    
         
            -
                         
     | 
| 
       20 
     | 
    
         
            -
                                                                    File.readable?('/proc/sys/crypto/fips_enabled')
         
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
                        file_output = File.read('/proc/sys/crypto/fips_enabled')
         
     | 
| 
      
 19 
     | 
    
         
            +
                        file_output = Util::FileHelper.safe_read('/proc/sys/crypto/fips_enabled')
         
     | 
| 
       23 
20 
     | 
    
         
             
                        @fact_list[:fips_enabled] = file_output.strip == '1'
         
     | 
| 
       24 
21 
     | 
    
         
             
                        @fact_list[fact_name]
         
     | 
| 
       25 
22 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -30,11 +30,11 @@ module Facter 
     | 
|
| 
       30 
30 
     | 
    
         
             
                    def read_domain(output)
         
     | 
| 
       31 
31 
     | 
    
         
             
                      if output =~ /.*?\.(.+$)/
         
     | 
| 
       32 
32 
     | 
    
         
             
                        domain = Regexp.last_match(1)
         
     | 
| 
       33 
     | 
    
         
            -
                       
     | 
| 
       34 
     | 
    
         
            -
                         
     | 
| 
       35 
     | 
    
         
            -
                        if  
     | 
| 
      
 33 
     | 
    
         
            +
                      else
         
     | 
| 
      
 34 
     | 
    
         
            +
                        file_content = Util::FileHelper.safe_read('/etc/resolv.conf')
         
     | 
| 
      
 35 
     | 
    
         
            +
                        if file_content =~ /^search\s+(\S+)/
         
     | 
| 
       36 
36 
     | 
    
         
             
                          domain = Regexp.last_match(1)
         
     | 
| 
       37 
     | 
    
         
            -
                        elsif  
     | 
| 
      
 37 
     | 
    
         
            +
                        elsif file_content =~ /^domain\s+(\S+)/
         
     | 
| 
       38 
38 
     | 
    
         
             
                          domain = Regexp.last_match(1)
         
     | 
| 
       39 
39 
     | 
    
         
             
                        end
         
     | 
| 
       40 
40 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -15,9 +15,7 @@ module Facter 
     | 
|
| 
       15 
15 
     | 
    
         
             
                      end
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
       17 
17 
     | 
    
         
             
                      def read_load_averages_file(fact_name)
         
     | 
| 
       18 
     | 
    
         
            -
                         
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
                        output = File.read('/proc/loadavg')
         
     | 
| 
      
 18 
     | 
    
         
            +
                        output = Util::FileHelper.safe_read('/proc/loadavg')
         
     | 
| 
       21 
19 
     | 
    
         
             
                        @fact_list[:load_averages] = {}.tap { |h| h['1m'], h['5m'], h['15m'], = output.split.map(&:to_f) }
         
     | 
| 
       22 
20 
     | 
    
         | 
| 
       23 
21 
     | 
    
         
             
                        @fact_list[fact_name]
         
     | 
| 
         @@ -15,9 +15,9 @@ module Facter 
     | 
|
| 
       15 
15 
     | 
    
         
             
                      end
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
       17 
17 
     | 
    
         
             
                      def read_meminfo_file(fact_name)
         
     | 
| 
       18 
     | 
    
         
            -
                         
     | 
| 
      
 18 
     | 
    
         
            +
                        meminfo_output = Util::FileHelper.safe_read('/proc/meminfo', nil)
         
     | 
| 
      
 19 
     | 
    
         
            +
                        return unless meminfo_output
         
     | 
| 
       19 
20 
     | 
    
         | 
| 
       20 
     | 
    
         
            -
                        meminfo_output = File.read('/proc/meminfo')
         
     | 
| 
       21 
21 
     | 
    
         
             
                        read_system(meminfo_output)
         
     | 
| 
       22 
22 
     | 
    
         
             
                        read_swap(meminfo_output)
         
     | 
| 
       23 
23 
     | 
    
         | 
| 
         @@ -16,9 +16,7 @@ module Facter 
     | 
|
| 
       16 
16 
     | 
    
         
             
                      end
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
       18 
18 
     | 
    
         
             
                      def root_device
         
     | 
| 
       19 
     | 
    
         
            -
                         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
                        cmdline = File.read('/proc/cmdline')
         
     | 
| 
      
 19 
     | 
    
         
            +
                        cmdline = Util::FileHelper.safe_read('/proc/cmdline')
         
     | 
| 
       22 
20 
     | 
    
         
             
                        match = cmdline.match(/root=([^\s]+)/)
         
     | 
| 
       23 
21 
     | 
    
         
             
                        match&.captures&.first
         
     | 
| 
       24 
22 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -25,15 +25,12 @@ module Facter 
     | 
|
| 
       25 
25 
     | 
    
         
             
                    end
         
     | 
| 
       26 
26 
     | 
    
         | 
| 
       27 
27 
     | 
    
         
             
                    def read_os_release_file(fact_name)
         
     | 
| 
       28 
     | 
    
         
            -
                       
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
                        return
         
     | 
| 
       31 
     | 
    
         
            -
                      end
         
     | 
| 
      
 28 
     | 
    
         
            +
                      output = Util::FileHelper.safe_readlines('/etc/os-release')
         
     | 
| 
      
 29 
     | 
    
         
            +
                      return @fact_list[:name] = nil if output.empty?
         
     | 
| 
       32 
30 
     | 
    
         | 
| 
       33 
     | 
    
         
            -
                      output = File.read('/etc/os-release')
         
     | 
| 
       34 
31 
     | 
    
         
             
                      pairs = []
         
     | 
| 
       35 
32 
     | 
    
         | 
| 
       36 
     | 
    
         
            -
                      output. 
     | 
| 
      
 33 
     | 
    
         
            +
                      output.each do |line|
         
     | 
| 
       37 
34 
     | 
    
         
             
                        pairs << line.strip.delete('"').split('=', 2)
         
     | 
| 
       38 
35 
     | 
    
         
             
                      end
         
     | 
| 
       39 
36 
     | 
    
         | 
    
        data/lib/resolvers/partitions.rb
    CHANGED
    
    | 
         @@ -6,6 +6,7 @@ module Facter 
     | 
|
| 
       6 
6 
     | 
    
         
             
                  @semaphore = Mutex.new
         
     | 
| 
       7 
7 
     | 
    
         
             
                  @fact_list ||= {}
         
     | 
| 
       8 
8 
     | 
    
         
             
                  BLOCK_PATH = '/sys/block'
         
     | 
| 
      
 9 
     | 
    
         
            +
                  BLOCK_SIZE = 512
         
     | 
| 
       9 
10 
     | 
    
         | 
| 
       10 
11 
     | 
    
         
             
                  class << self
         
     | 
| 
       11 
12 
     | 
    
         
             
                    private
         
     | 
| 
         @@ -41,23 +42,27 @@ module Facter 
     | 
|
| 
       41 
42 
     | 
    
         
             
                    end
         
     | 
| 
       42 
43 
     | 
    
         | 
| 
       43 
44 
     | 
    
         
             
                    def extract_from_dm(block_path)
         
     | 
| 
       44 
     | 
    
         
            -
                      map_name =  
     | 
| 
      
 45 
     | 
    
         
            +
                      map_name = Util::FileHelper.safe_read("#{block_path}/dm/name").chomp
         
     | 
| 
       45 
46 
     | 
    
         
             
                      if map_name.empty?
         
     | 
| 
       46 
     | 
    
         
            -
                        populate_partitions("/dev 
     | 
| 
      
 47 
     | 
    
         
            +
                        populate_partitions("/dev#{block_path}", block_path)
         
     | 
| 
       47 
48 
     | 
    
         
             
                      else
         
     | 
| 
       48 
49 
     | 
    
         
             
                        populate_partitions("/dev/mapper/#{map_name}", block_path)
         
     | 
| 
       49 
50 
     | 
    
         
             
                      end
         
     | 
| 
       50 
51 
     | 
    
         
             
                    end
         
     | 
| 
       51 
52 
     | 
    
         | 
| 
       52 
53 
     | 
    
         
             
                    def extract_from_loop(block_path)
         
     | 
| 
       53 
     | 
    
         
            -
                       
     | 
| 
       54 
     | 
    
         
            -
                       
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
      
 54 
     | 
    
         
            +
                      backing_file = Util::FileHelper.safe_read("#{block_path}/loop/backing_file").chomp
         
     | 
| 
      
 55 
     | 
    
         
            +
                      if backing_file.empty?
         
     | 
| 
      
 56 
     | 
    
         
            +
                        populate_partitions("/dev#{block_path}", block_path)
         
     | 
| 
      
 57 
     | 
    
         
            +
                      else
         
     | 
| 
      
 58 
     | 
    
         
            +
                        populate_partitions("/dev#{block_path}", block_path, backing_file)
         
     | 
| 
      
 59 
     | 
    
         
            +
                      end
         
     | 
| 
       56 
60 
     | 
    
         
             
                    end
         
     | 
| 
       57 
61 
     | 
    
         | 
| 
       58 
62 
     | 
    
         
             
                    def populate_partitions(partition_name, block_path, backing_file = nil)
         
     | 
| 
       59 
63 
     | 
    
         
             
                      @fact_list[:partitions][partition_name] = {}
         
     | 
| 
       60 
     | 
    
         
            -
                      size_bytes =  
     | 
| 
      
 64 
     | 
    
         
            +
                      size_bytes = Util::FileHelper.safe_read("#{block_path}/size", '0')
         
     | 
| 
      
 65 
     | 
    
         
            +
                                                   .chomp.to_i * BLOCK_SIZE
         
     | 
| 
       61 
66 
     | 
    
         
             
                      info_hash = { size_bytes: size_bytes,
         
     | 
| 
       62 
67 
     | 
    
         
             
                                    size: Facter::BytesToHumanReadable.convert(size_bytes), backing_file: backing_file }
         
     | 
| 
       63 
68 
     | 
    
         
             
                      info_hash.merge!(populate_from_blkid(partition_name))
         
     | 
| 
         @@ -19,9 +19,9 @@ module Facter 
     | 
|
| 
       19 
19 
     | 
    
         
             
                      end
         
     | 
| 
       20 
20 
     | 
    
         | 
| 
       21 
21 
     | 
    
         
             
                      def read_cpuinfo(fact_name)
         
     | 
| 
       22 
     | 
    
         
            -
                         
     | 
| 
      
 22 
     | 
    
         
            +
                        cpuinfo_output = Util::FileHelper.safe_readlines('/proc/cpuinfo')
         
     | 
| 
      
 23 
     | 
    
         
            +
                        return if cpuinfo_output.empty?
         
     | 
| 
       23 
24 
     | 
    
         | 
| 
       24 
     | 
    
         
            -
                        cpuinfo_output = File.read('/proc/cpuinfo')
         
     | 
| 
       25 
25 
     | 
    
         
             
                        read_processors(cpuinfo_output) # + model names
         
     | 
| 
       26 
26 
     | 
    
         | 
| 
       27 
27 
     | 
    
         
             
                        @fact_list[:physical_count] = @fact_list[:physical_processors].uniq.length
         
     | 
| 
         @@ -32,7 +32,7 @@ module Facter 
     | 
|
| 
       32 
32 
     | 
    
         
             
                        @fact_list[:processors] = 0
         
     | 
| 
       33 
33 
     | 
    
         
             
                        @fact_list[:models] = []
         
     | 
| 
       34 
34 
     | 
    
         
             
                        @fact_list[:physical_processors] = []
         
     | 
| 
       35 
     | 
    
         
            -
                        cpuinfo_output. 
     | 
| 
      
 35 
     | 
    
         
            +
                        cpuinfo_output.each do |line|
         
     | 
| 
       36 
36 
     | 
    
         
             
                          tokens = line.split(':')
         
     | 
| 
       37 
37 
     | 
    
         
             
                          count_processors(tokens)
         
     | 
| 
       38 
38 
     | 
    
         
             
                          construct_models_list(tokens)
         
     | 
| 
         @@ -3,10 +3,6 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            module Facter
         
     | 
| 
       4 
4 
     | 
    
         
             
              module Resolvers
         
     | 
| 
       5 
5 
     | 
    
         
             
                class SELinux < BaseResolver
         
     | 
| 
       6 
     | 
    
         
            -
                  # :name
         
     | 
| 
       7 
     | 
    
         
            -
                  # :version
         
     | 
| 
       8 
     | 
    
         
            -
                  # :codename
         
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
6 
     | 
    
         
             
                  @semaphore = Mutex.new
         
     | 
| 
       11 
7 
     | 
    
         
             
                  @fact_list ||= {}
         
     | 
| 
       12 
8 
     | 
    
         | 
| 
         @@ -19,7 +15,7 @@ module Facter 
     | 
|
| 
       19 
15 
     | 
    
         | 
| 
       20 
16 
     | 
    
         
             
                    def retrieve_facts(fact_name)
         
     | 
| 
       21 
17 
     | 
    
         
             
                      mountpoint = read_mounts_file if @fact_list[:enabled].nil?
         
     | 
| 
       22 
     | 
    
         
            -
                      read_other_selinux_facts(mountpoint) if @fact_list[:enabled] 
     | 
| 
      
 18 
     | 
    
         
            +
                      read_other_selinux_facts(mountpoint) if @fact_list[:enabled]
         
     | 
| 
       23 
19 
     | 
    
         | 
| 
       24 
20 
     | 
    
         
             
                      @fact_list[fact_name]
         
     | 
| 
       25 
21 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -40,14 +36,14 @@ module Facter 
     | 
|
| 
       40 
36 
     | 
    
         
             
                    end
         
     | 
| 
       41 
37 
     | 
    
         | 
| 
       42 
38 
     | 
    
         
             
                    def read_other_selinux_facts(mountpoint)
         
     | 
| 
       43 
     | 
    
         
            -
                      read_selinux_config
         
     | 
| 
      
 39 
     | 
    
         
            +
                      return unless read_selinux_config
         
     | 
| 
       44 
40 
     | 
    
         | 
| 
       45 
41 
     | 
    
         
             
                      enforce_file = "#{mountpoint}/enforce"
         
     | 
| 
       46 
42 
     | 
    
         
             
                      policy_file = "#{mountpoint}/policyvers"
         
     | 
| 
       47 
43 
     | 
    
         | 
| 
       48 
     | 
    
         
            -
                      @fact_list[:policy_version] =  
     | 
| 
      
 44 
     | 
    
         
            +
                      @fact_list[:policy_version] = Util::FileHelper.safe_read(policy_file, nil)
         
     | 
| 
       49 
45 
     | 
    
         | 
| 
       50 
     | 
    
         
            -
                      enforce =  
     | 
| 
      
 46 
     | 
    
         
            +
                      enforce = Util::FileHelper.safe_read(enforce_file)
         
     | 
| 
       51 
47 
     | 
    
         
             
                      if enforce.eql?('1')
         
     | 
| 
       52 
48 
     | 
    
         
             
                        @fact_list[:enforced] = true
         
     | 
| 
       53 
49 
     | 
    
         
             
                        @fact_list[:current_mode] = 'enforcing'
         
     | 
| 
         @@ -58,10 +54,14 @@ module Facter 
     | 
|
| 
       58 
54 
     | 
    
         
             
                    end
         
     | 
| 
       59 
55 
     | 
    
         | 
| 
       60 
56 
     | 
    
         
             
                    def read_selinux_config
         
     | 
| 
       61 
     | 
    
         
            -
                       
     | 
| 
      
 57 
     | 
    
         
            +
                      file_lines = Util::FileHelper.safe_readlines('/etc/selinux/config')
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                      file_lines.map do |line|
         
     | 
| 
       62 
60 
     | 
    
         
             
                        @fact_list[:config_mode] = line.split('=').last.strip if line =~ /^SELINUX=/
         
     | 
| 
       63 
61 
     | 
    
         
             
                        @fact_list[:config_policy] = line.split('=').last.strip if line =~ /^SELINUXTYPE=/
         
     | 
| 
       64 
62 
     | 
    
         
             
                      end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                      true unless file_lines.empty?
         
     | 
| 
       65 
65 
     | 
    
         
             
                    end
         
     | 
| 
       66 
66 
     | 
    
         
             
                  end
         
     | 
| 
       67 
67 
     | 
    
         
             
                end
         
     | 
| 
         @@ -15,7 +15,7 @@ module Facter 
     | 
|
| 
       15 
15 
     | 
    
         
             
                      end
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
       17 
17 
     | 
    
         
             
                      def read_sysdef_file(fact_name)
         
     | 
| 
       18 
     | 
    
         
            -
                        return unless File. 
     | 
| 
      
 18 
     | 
    
         
            +
                        return unless File.executable?('/usr/sbin/sysdef')
         
     | 
| 
       19 
19 
     | 
    
         | 
| 
       20 
20 
     | 
    
         
             
                        file_content, _status = Open3.capture2('/usr/sbin/sysdef')
         
     | 
| 
       21 
21 
     | 
    
         
             
                        files = file_content.split("\n").map do |line|
         
     | 
| 
         @@ -1,8 +1,5 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            require 'base64'
         
     | 
| 
       4 
     | 
    
         
            -
            require 'digest/sha1'
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
3 
     | 
    
         
             
            module Facter
         
     | 
| 
       7 
4 
     | 
    
         
             
              module Resolvers
         
     | 
| 
       8 
5 
     | 
    
         
             
                class SshResolver < BaseResolver
         
     | 
| 
         @@ -24,52 +21,16 @@ module Facter 
     | 
|
| 
       24 
21 
     | 
    
         
             
                        next unless File.directory?(file_path)
         
     | 
| 
       25 
22 
     | 
    
         | 
| 
       26 
23 
     | 
    
         
             
                        @file_names.each do |file_name|
         
     | 
| 
       27 
     | 
    
         
            -
                           
     | 
| 
      
 24 
     | 
    
         
            +
                          file_content = Util::FileHelper.safe_read(File.join(file_path, file_name), nil)
         
     | 
| 
      
 25 
     | 
    
         
            +
                          next unless file_content
         
     | 
| 
       28 
26 
     | 
    
         | 
| 
       29 
     | 
    
         
            -
                          key_type, key =  
     | 
| 
       30 
     | 
    
         
            -
                           
     | 
| 
       31 
     | 
    
         
            -
                          ssh_list << create_ssh(key_name, key_type, key)
         
     | 
| 
      
 27 
     | 
    
         
            +
                          key_type, key = file_content.split(' ')
         
     | 
| 
      
 28 
     | 
    
         
            +
                          ssh_list << ::Resolvers::Utils::SshHelper.create_ssh(key_type, key)
         
     | 
| 
       32 
29 
     | 
    
         
             
                        end
         
     | 
| 
       33 
30 
     | 
    
         
             
                      end
         
     | 
| 
       34 
31 
     | 
    
         
             
                      @fact_list[:ssh] = ssh_list
         
     | 
| 
       35 
32 
     | 
    
         
             
                      @fact_list[fact_name]
         
     | 
| 
       36 
33 
     | 
    
         
             
                    end
         
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
                    def create_ssh(key_name, key_type, key)
         
     | 
| 
       39 
     | 
    
         
            -
                      decoded_key = Base64.decode64(key)
         
     | 
| 
       40 
     | 
    
         
            -
                      ssh_fa = determine_ssh_fingerprint(key_name)
         
     | 
| 
       41 
     | 
    
         
            -
                      sha1 = "SSHFP #{ssh_fa} 1 #{Digest::SHA1.new.update(decoded_key)}"
         
     | 
| 
       42 
     | 
    
         
            -
                      sha256 = "SSHFP #{ssh_fa} 2 #{Digest::SHA2.new.update(decoded_key)}"
         
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
                      fingerprint = FingerPrint.new(sha1, sha256)
         
     | 
| 
       45 
     | 
    
         
            -
                      Ssh.new(fingerprint, key_type, key, key_name)
         
     | 
| 
       46 
     | 
    
         
            -
                    end
         
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
                    def determine_ssh_key_name(key)
         
     | 
| 
       49 
     | 
    
         
            -
                      case key
         
     | 
| 
       50 
     | 
    
         
            -
                      when 'ssh-dss'
         
     | 
| 
       51 
     | 
    
         
            -
                        'dsa'
         
     | 
| 
       52 
     | 
    
         
            -
                      when 'ecdsa-sha2-nistp256'
         
     | 
| 
       53 
     | 
    
         
            -
                        'ecdsa'
         
     | 
| 
       54 
     | 
    
         
            -
                      when 'ssh-ed25519'
         
     | 
| 
       55 
     | 
    
         
            -
                        'ed25519'
         
     | 
| 
       56 
     | 
    
         
            -
                      when 'ssh-rsa'
         
     | 
| 
       57 
     | 
    
         
            -
                        'rsa'
         
     | 
| 
       58 
     | 
    
         
            -
                      end
         
     | 
| 
       59 
     | 
    
         
            -
                    end
         
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
     | 
    
         
            -
                    def determine_ssh_fingerprint(key_name)
         
     | 
| 
       62 
     | 
    
         
            -
                      case key_name
         
     | 
| 
       63 
     | 
    
         
            -
                      when 'rsa'
         
     | 
| 
       64 
     | 
    
         
            -
                        1
         
     | 
| 
       65 
     | 
    
         
            -
                      when 'dsa'
         
     | 
| 
       66 
     | 
    
         
            -
                        2
         
     | 
| 
       67 
     | 
    
         
            -
                      when 'ecdsa'
         
     | 
| 
       68 
     | 
    
         
            -
                        3
         
     | 
| 
       69 
     | 
    
         
            -
                      when 'ed25519'
         
     | 
| 
       70 
     | 
    
         
            -
                        4
         
     | 
| 
       71 
     | 
    
         
            -
                      end
         
     | 
| 
       72 
     | 
    
         
            -
                    end
         
     | 
| 
       73 
34 
     | 
    
         
             
                  end
         
     | 
| 
       74 
35 
     | 
    
         
             
                end
         
     | 
| 
       75 
36 
     | 
    
         
             
              end
         
     | 
| 
         @@ -0,0 +1,27 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'base64'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'digest/sha1'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            module Resolvers
         
     | 
| 
      
 7 
     | 
    
         
            +
              module Utils
         
     | 
| 
      
 8 
     | 
    
         
            +
                class SshHelper
         
     | 
| 
      
 9 
     | 
    
         
            +
                  class << self
         
     | 
| 
      
 10 
     | 
    
         
            +
                    SSH_NAME = { 'ssh-dss' => 'dsa', 'ecdsa-sha2-nistp256' => 'ecdsa',
         
     | 
| 
      
 11 
     | 
    
         
            +
                                 'ssh-ed25519' => 'ed25519', 'ssh-rsa' => 'rsa' }.freeze
         
     | 
| 
      
 12 
     | 
    
         
            +
                    SSH_FINGERPRINT = { 'rsa' => 1, 'dsa' => 2, 'ecdsa' => 3, 'ed25519' => 4 }.freeze
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                    def create_ssh(key_type, key)
         
     | 
| 
      
 15 
     | 
    
         
            +
                      key_name = SSH_NAME[key_type]
         
     | 
| 
      
 16 
     | 
    
         
            +
                      decoded_key = Base64.decode64(key)
         
     | 
| 
      
 17 
     | 
    
         
            +
                      ssh_fp = SSH_FINGERPRINT[key_name]
         
     | 
| 
      
 18 
     | 
    
         
            +
                      sha1 = "SSHFP #{ssh_fp} 1 #{Digest::SHA1.new.update(decoded_key)}"
         
     | 
| 
      
 19 
     | 
    
         
            +
                      sha256 = "SSHFP #{ssh_fp} 2 #{Digest::SHA2.new.update(decoded_key)}"
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                      fingerprint = Facter::FingerPrint.new(sha1, sha256)
         
     | 
| 
      
 22 
     | 
    
         
            +
                      Facter::Ssh.new(fingerprint, key_type, key, key_name)
         
     | 
| 
      
 23 
     | 
    
         
            +
                    end
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,47 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Facter
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Resolvers
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Windows
         
     | 
| 
      
 6 
     | 
    
         
            +
                  class Ssh < BaseResolver
         
     | 
| 
      
 7 
     | 
    
         
            +
                    @log = Facter::Log.new(self)
         
     | 
| 
      
 8 
     | 
    
         
            +
                    @semaphore = Mutex.new
         
     | 
| 
      
 9 
     | 
    
         
            +
                    @fact_list ||= {}
         
     | 
| 
      
 10 
     | 
    
         
            +
                    FILE_NAMES = %w[ssh_host_rsa_key.pub ssh_host_dsa_key.pub
         
     | 
| 
      
 11 
     | 
    
         
            +
                                    ssh_host_ecdsa_key.pub ssh_host_ed25519_key.pub].freeze
         
     | 
| 
      
 12 
     | 
    
         
            +
                    class << self
         
     | 
| 
      
 13 
     | 
    
         
            +
                      private
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                      def post_resolve(fact_name)
         
     | 
| 
      
 16 
     | 
    
         
            +
                        @fact_list.fetch(fact_name) { retrieve_info(fact_name) }
         
     | 
| 
      
 17 
     | 
    
         
            +
                      end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                      def retrieve_info(fact_name)
         
     | 
| 
      
 20 
     | 
    
         
            +
                        ssh_dir = determine_ssh_dir
         
     | 
| 
      
 21 
     | 
    
         
            +
                        return unless ssh_dir && File.directory?(ssh_dir)
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                        ssh_list = []
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                        FILE_NAMES.each do |file_name|
         
     | 
| 
      
 26 
     | 
    
         
            +
                          output = Util::FileHelper.safe_read(File.join(ssh_dir, file_name))
         
     | 
| 
      
 27 
     | 
    
         
            +
                          next if output.empty?
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                          key_type, key = output.split(' ')
         
     | 
| 
      
 30 
     | 
    
         
            +
                          ssh_list << ::Resolvers::Utils::SshHelper.create_ssh(key_type, key)
         
     | 
| 
      
 31 
     | 
    
         
            +
                        end
         
     | 
| 
      
 32 
     | 
    
         
            +
                        @fact_list[:ssh] = ssh_list.empty? ? nil : ssh_list
         
     | 
| 
      
 33 
     | 
    
         
            +
                        @fact_list[fact_name]
         
     | 
| 
      
 34 
     | 
    
         
            +
                      end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                      def determine_ssh_dir
         
     | 
| 
      
 37 
     | 
    
         
            +
                        progdata_dir = ENV['programdata']
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                        return if !progdata_dir || progdata_dir.empty?
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                        File.join(progdata_dir, 'ssh')
         
     | 
| 
      
 42 
     | 
    
         
            +
                      end
         
     | 
| 
      
 43 
     | 
    
         
            +
                    end
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
              end
         
     | 
| 
      
 47 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Facter
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Util
         
     | 
| 
      
 5 
     | 
    
         
            +
                class FileHelper
         
     | 
| 
      
 6 
     | 
    
         
            +
                  @log = Log.new(self)
         
     | 
| 
      
 7 
     | 
    
         
            +
                  class << self
         
     | 
| 
      
 8 
     | 
    
         
            +
                    DEBUG_MESSAGE = 'File at: %s is not accessible.'
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                    def safe_read(path, result_if_not_readable = '')
         
     | 
| 
      
 11 
     | 
    
         
            +
                      return File.read(path) if File.readable?(path)
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                      result_if_not_readable
         
     | 
| 
      
 14 
     | 
    
         
            +
                    end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                    def safe_readlines(path, result_if_not_readable = [])
         
     | 
| 
      
 17 
     | 
    
         
            +
                      return File.readlines(path) if File.readable?(path)
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                      result_if_not_readable
         
     | 
| 
      
 20 
     | 
    
         
            +
                    end
         
     | 
| 
      
 21 
     | 
    
         
            +
                  end
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     |