Uploaded image for project: 'Facter'
  1. Facter
  2. FACT-2930

Inconsistent handling of Date types in custom facts

    XMLWordPrintable

Details

    • Bug
    • Status: Resolved
    • Normal
    • Resolution: Fixed
    • None
    • FACT 4.1.0
    • None
    • Night's Watch
    • 1
    • NW - 2021-03-17, NW - 2021-03-31
    • Needs Assessment
    • Enhancement
    • Add Date and Time as supported values for custom facts.
    • Needs Assessment

    Description

      If a custom fact returns a Time value, then facter will report:

      $ mkdir facts
      $ cat > facts/time.rb <<END
      Facter.add(:now) do
        setcode { Time.now }
      end
      END
      $ bx facter --custom-dir /Users/josh/work/facter/facts --trace
      [2021-01-29 11:59:02.519014 ] ERROR Facter - Fact resolution fact='now', resolution='<anonymous>' resolved to an invalid value: Expected 2021-01-29 11:59:02 -0800 to be one of [Integer, Float, TrueClass, FalseClass, NilClass, Symbol, String, Array, Hash], but was Time
      backtrace:
      /Users/josh/work/facter/lib/facter/custom_facts/util/normalization.rb:29:in `normalize'
      /Users/josh/work/facter/lib/facter/custom_facts/core/resolvable.rb:71:in `value'
      /Users/josh/work/facter/lib/facter/custom_facts/util/fact.rb:209:in `block in find_first_real_value'
      /Users/josh/work/facter/lib/facter/custom_facts/util/fact.rb:207:in `each'
      /Users/josh/work/facter/lib/facter/custom_facts/util/fact.rb:207:in `find_first_real_value'
      /Users/josh/work/facter/lib/facter/custom_facts/util/fact.rb:133:in `block (2 levels) in value'
      

      Note the error message contains:

      [Integer, Float, TrueClass, FalseClass, NilClass, Symbol, String, Array, Hash], but was Time
      

      Note Date is missing from the list of valid types, but facter does accept Date: https://github.com/puppetlabs/facter/blob/0654f8f6858ca0163680b3d8dfc53d90345f0f35/lib/facter/custom_facts/util/normalization.rb#L19.

      So we probably need to add Date to VALID_TYPES...

      However, if facter serializes a Date, it does so using Date#to_s which will be different for different locales. I would expect facter to always serialize using a well known format like ISO 8601. Facter calls Date#to_s which serializes as ISO 8601. It might be better to make that explicit #Date#iso8601.

      Facter 3 did not emit core facts as date or time (https://github.com/puppetlabs/facter/blob/3.x/lib/schema/facter.yaml#L5-L14), however, it didn't restrict custom facts from doing so. In those cases the fact was serialized as to_s:

      # mkdir -p /etc/puppetlabs/code/environments/production/modules/customfacts/lib/facter
      # cat <<END > /etc/puppetlabs/code/environments/production/modules/customfacts/lib/facter/types.rb
      require 'date'
       
      Facter.add(:custom_date) do
        setcode { Date.new(2020) }
      end
       
      Facter.add(:custom_time) do
        setcode { Time.now }
      end
      END
      # chown -R puppet:puppet /etc/puppetlabs/code/environments/production/modules
      # puppet agent -t
      ...
      # cat /opt/puppetlabs/server/data/puppetserver/server_data/facts/<name>.json | jq . | grep -E '(custom_(date|time))|puppetversion'
          "custom_date": "2020-01-01",
          "custom_time": "2021-03-11 17:58:55 +0000",
          "puppetversion": "6.22.0",
      

      Attachments

        Activity

          People

            gheorghe.popescu Gheorghe Popescu
            josh Josh Cooper
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Zendesk Support