diff --git a/lib/puppet/node/facts.rb b/lib/puppet/node/facts.rb index 1d7e221eb..577b62b62 100755 --- a/lib/puppet/node/facts.rb +++ b/lib/puppet/node/facts.rb @@ -1,99 +1,99 @@ require 'time' require 'puppet/node' require 'puppet/indirector' require 'puppet/util/pson' # Manage a given node's facts. This either accepts facts and stores them, or # returns facts for a given node. class Puppet::Node::Facts # Set up indirection, so that nodes can be looked for in # the node sources. extend Puppet::Indirector extend Puppet::Util::Pson # We want to expire any cached nodes if the facts are saved. module NodeExpirer def save(instance, key = nil) - Puppet::Node.indirection.expire(key, instance) + Puppet::Node.indirection.expire(instance.name) super end end indirects :facts, :terminus_setting => :facts_terminus, :extend => NodeExpirer attr_accessor :name, :values def add_local_facts values["clientcert"] = Puppet.settings[:certname] values["clientversion"] = Puppet.version.to_s values["environment"] ||= Puppet.settings[:environment] end def initialize(name, values = {}) @name = name @values = values add_timestamp end def downcase_if_necessary return unless Puppet.settings[:downcasefacts] Puppet.warning "DEPRECATION NOTICE: Fact downcasing is deprecated; please disable (20080122)" values.each do |fact, value| values[fact] = value.downcase if value.is_a?(String) end end # Convert all fact values into strings. def stringify values.each do |fact, value| values[fact] = value.to_s end end def ==(other) return false unless self.name == other.name strip_internal == other.send(:strip_internal) end def self.from_pson(data) result = new(data['name'], data['values']) result.timestamp = Time.parse(data['timestamp']) result.expiration = Time.parse(data['expiration']) result end def to_pson(*args) { 'expiration' => expiration, 'name' => name, 'timestamp' => timestamp, 'values' => strip_internal, }.to_pson(*args) end # Add internal data to the facts for storage. def add_timestamp self.timestamp = Time.now end def timestamp=(time) self.values[:_timestamp] = time end def timestamp self.values[:_timestamp] end private # Strip out that internal data. def strip_internal newvals = values.dup newvals.find_all { |name, value| name.to_s =~ /^_/ }.each { |name, value| newvals.delete(name) } newvals end end diff --git a/spec/integration/node/facts_spec.rb b/spec/integration/node/facts_spec.rb index 689f6bfdf..78bdabce1 100755 --- a/spec/integration/node/facts_spec.rb +++ b/spec/integration/node/facts_spec.rb @@ -1,42 +1,41 @@ #!/usr/bin/env rspec require 'spec_helper' describe Puppet::Node::Facts do describe "when using the indirector" do it "should expire any cached node instances when it is saved" do Puppet::Node::Facts.indirection.stubs(:terminus_class).returns :yaml Puppet::Node::Facts.indirection.terminus(:yaml).should equal(Puppet::Node::Facts.indirection.terminus(:yaml)) terminus = Puppet::Node::Facts.indirection.terminus(:yaml) terminus.stubs :save - facts = Puppet::Node::Facts.new("me") - - Puppet::Node.indirection.expects(:expire).with(nil, facts) + Puppet::Node.indirection.expects(:expire).with("me") + facts = Puppet::Node::Facts.new("me") Puppet::Node::Facts.indirection.save(facts) end it "should be able to delegate to the :yaml terminus" do Puppet::Node::Facts.indirection.stubs(:terminus_class).returns :yaml # Load now, before we stub the exists? method. terminus = Puppet::Node::Facts.indirection.terminus(:yaml) terminus.expects(:path).with("me").returns "/my/yaml/file" FileTest.expects(:exist?).with("/my/yaml/file").returns false Puppet::Node::Facts.indirection.find("me").should be_nil end it "should be able to delegate to the :facter terminus" do Puppet::Node::Facts.indirection.stubs(:terminus_class).returns :facter Facter.expects(:to_hash).returns "facter_hash" facts = Puppet::Node::Facts.new("me") Puppet::Node::Facts.expects(:new).with("me", "facter_hash").returns facts Puppet::Node::Facts.indirection.find("me").should equal(facts) end end end