summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xbin/puppet8
-rw-r--r--lib/puppet/defaults.rb9
-rw-r--r--lib/puppet/indirector/configuration/compiler.rb6
-rw-r--r--lib/puppet/indirector/indirection.rb22
-rw-r--r--lib/puppet/network/handler/configuration.rb4
-rw-r--r--lib/puppet/node.rb84
-rw-r--r--lib/puppet/node/searching.rb106
-rw-r--r--lib/puppet/reference/node_source.rb (renamed from lib/puppet/reference/node_sources.rb)6
-rwxr-xr-xspec/unit/indirector/configuration/compiler.rb16
-rwxr-xr-xspec/unit/indirector/indirection.rb35
-rwxr-xr-xspec/unit/node.rb66
-rwxr-xr-xspec/unit/node/searching.rb79
-rwxr-xr-xtest/network/handler/configuration.rb2
13 files changed, 220 insertions, 223 deletions
diff --git a/bin/puppet b/bin/puppet
index 140976ffd..409c23259 100755
--- a/bin/puppet
+++ b/bin/puppet
@@ -172,12 +172,11 @@ else
end
# Collect our facts.
-Puppet::Node::Facts.terminus_class = :facter
facts = Puppet::Node::Facts.find("me")
facts.name = facts.values["hostname"]
-# Create our Node
-node = Puppet::Node.new(facts.name)
+# Find our Node
+node = Puppet::Node.find_by_any_name(facts.name)
# Merge in the facts.
node.merge(facts.values)
@@ -195,9 +194,6 @@ if options[:loadclasses]
end
end
-# Compile and apply the configuration
-Puppet::Node::Configuration.terminus_class = :compiler
-
begin
# Compile our configuration
config = Puppet::Node::Configuration.find(node)
diff --git a/lib/puppet/defaults.rb b/lib/puppet/defaults.rb
index 33f3eda91..2e0daf60f 100644
--- a/lib/puppet/defaults.rb
+++ b/lib/puppet/defaults.rb
@@ -152,7 +152,8 @@ module Puppet
:maximum_uid => [4294967290, "The maximum allowed UID. Some platforms use negative UIDs
but then ship with tools that do not know how to handle signed ints, so the UIDs show up as
huge numbers that can then not be fed back into the system. This is a hackish way to fail in a
- slightly more useful way when that happens."]
+ slightly more useful way when that happens."],
+ :node_terminus => ["null", "Where to find information about nodes."]
)
hostname = Facter["hostname"].value
@@ -578,11 +579,7 @@ module Puppet
setdefaults(:parser,
:typecheck => [true, "Whether to validate types during parsing."],
- :paramcheck => [true, "Whether to validate parameters during parsing."],
- :node_terminus => ["null", "Where to look for node configuration information.
- The default node source, ``none``, just returns a node with its facts
- filled in, which is required for normal functionality.
- See the `NodeSourceReference`:trac: for more information."]
+ :paramcheck => [true, "Whether to validate parameters during parsing."]
)
setdefaults(:main,
diff --git a/lib/puppet/indirector/configuration/compiler.rb b/lib/puppet/indirector/configuration/compiler.rb
index 9fc8a7939..598f50451 100644
--- a/lib/puppet/indirector/configuration/compiler.rb
+++ b/lib/puppet/indirector/configuration/compiler.rb
@@ -55,7 +55,7 @@ class Puppet::Node::Configuration::Compiler < Puppet::Indirector::Code
# use timestamps; once one of them moves to using real versions,
# the comparison stops working.
def version(key)
- if node = Puppet::Node.search(key)
+ if node = Puppet::Node.find_by_any_name(key)
return [Puppet::Node.version(key).to_f, Puppet::Node::Facts.version(key).to_f, interpreter.configuration_version(node).to_f].sort[-1]
else
# This is the standard for "got nothing for ya".
@@ -108,9 +108,9 @@ class Puppet::Node::Configuration::Compiler < Puppet::Indirector::Code
#end
# Note that this is reasonable, because either their node source should actually
- # know about the node, or they should be using the ``none`` node source, which
+ # know about the node, or they should be using the ``null`` node source, which
# will always return data.
- unless node = Puppet::Node.search(key)
+ unless node = Puppet::Node.find_by_any_name(key)
raise Puppet::Error, "Could not find node '%s'" % key
end
diff --git a/lib/puppet/indirector/indirection.rb b/lib/puppet/indirector/indirection.rb
index 816b4ffc5..f6f867a5f 100644
--- a/lib/puppet/indirector/indirection.rb
+++ b/lib/puppet/indirector/indirection.rb
@@ -59,6 +59,7 @@ class Puppet::Indirector::Indirection
@termini = {}
@cache_class = nil
+ @terminus_class = nil
raise(ArgumentError, "Indirection %s is already defined" % @name) if @@indirections.find { |i| i.name == @name }
@@indirections << self
@@ -88,12 +89,25 @@ class Puppet::Indirector::Indirection
return @termini[terminus_name] ||= make_terminus(terminus_name)
end
- attr_reader :terminus_class
+ # This can be used to select the terminus class.
+ attr_accessor :terminus_setting
+
+ # Determine the terminus class.
+ def terminus_class
+ unless @terminus_class
+ if setting = self.terminus_setting
+ self.terminus_class = Puppet.settings[setting].to_sym
+ else
+ raise Puppet::DevError, "No terminus class nor terminus setting was provided for indirection %s" % self.name
+ end
+ end
+ @terminus_class
+ end
# Specify the terminus class to use.
- def terminus_class=(terminus_class)
- validate_terminus_class(terminus_class)
- @terminus_class = terminus_class
+ def terminus_class=(klass)
+ validate_terminus_class(klass)
+ @terminus_class = klass
end
# This is used by terminus_class= and cache=.
diff --git a/lib/puppet/network/handler/configuration.rb b/lib/puppet/network/handler/configuration.rb
index 680304e2a..8168ce1d5 100644
--- a/lib/puppet/network/handler/configuration.rb
+++ b/lib/puppet/network/handler/configuration.rb
@@ -30,7 +30,7 @@ class Puppet::Network::Handler
# Note that this is reasonable, because either their node source should actually
# know about the node, or they should be using the ``none`` node source, which
# will always return data.
- unless node = Puppet::Node.search(key)
+ unless node = Puppet::Node.find_by_any_name(key)
raise Puppet::Error, "Could not find node '%s'" % key
end
@@ -62,7 +62,7 @@ class Puppet::Network::Handler
# Return the configuration version.
def version(client = nil, clientip = nil)
- if client and node = Puppet::Node.search(client)
+ if client and node = Puppet::Node.find_by_any_name(client)
update_node_check(node)
return interpreter.configuration_version(node)
else
diff --git a/lib/puppet/node.rb b/lib/puppet/node.rb
index 2d87b6515..4b3a8e9c9 100644
--- a/lib/puppet/node.rb
+++ b/lib/puppet/node.rb
@@ -10,13 +10,85 @@ class Puppet::Node
extend Puppet::Indirector
# Use the node source as the indirection terminus.
- indirects :node, :terminus_class => :null
+ indirects :node, :terminus_setting => :node_terminus
- # Add the node-searching methods. This is what people will actually
- # interact with that will find the node with the list of names or
- # will search for a default node.
- require 'puppet/node/searching'
- extend Puppet::Node::Searching
+ # Retrieve a node from the node source, with some additional munging
+ # thrown in for kicks.
+ def self.find_by_any_name(key)
+ return nil unless key
+
+ facts = node_facts(key)
+ node = nil
+ names = node_names(key, facts)
+ names.each do |name|
+ name = name.to_s if name.is_a?(Symbol)
+ break if node = find(name)
+ end
+
+ # If they made it this far, we haven't found anything, so look for a
+ # default node.
+ unless node or names.include?("default")
+ if node = find("default")
+ Puppet.notice "Using default node for %s" % key
+ end
+ end
+
+ if node
+ node.names = names
+
+ return node
+ else
+ return nil
+ end
+ end
+
+ private
+
+ # Look up the node facts from our fact handler.
+ def self.node_facts(key)
+ if facts = Puppet::Node::Facts.find(key)
+ facts.values
+ else
+ {}
+ end
+ end
+
+ # Calculate the list of node names we should use for looking
+ # up our node.
+ def self.node_names(key, facts = nil)
+ facts ||= node_facts(key)
+ names = []
+
+ if hostname = facts["hostname"]
+ unless hostname == key
+ names << hostname
+ end
+ else
+ hostname = key
+ end
+
+ if fqdn = facts["fqdn"]
+ hostname = fqdn
+ names << fqdn
+ end
+
+ # Make sure both the fqdn and the short name of the
+ # host can be used in the manifest
+ if hostname =~ /\./
+ names << hostname.sub(/\..+/,'')
+ elsif domain = facts['domain']
+ names << hostname + "." + domain
+ end
+
+ # Sort the names inversely by name length.
+ names.sort! { |a,b| b.length <=> a.length }
+
+ # And make sure the key is first, since that's the most
+ # likely usage.
+ ([key] + names).uniq
+ end
+
+ public
attr_accessor :name, :classes, :parameters, :source, :ipaddress, :names
attr_reader :time
diff --git a/lib/puppet/node/searching.rb b/lib/puppet/node/searching.rb
deleted file mode 100644
index 10dd588ab..000000000
--- a/lib/puppet/node/searching.rb
+++ /dev/null
@@ -1,106 +0,0 @@
-# The module that handles actually searching for nodes. This is only included
-# in the Node class, but it's completely stand-alone functionality, so it's
-# worth making it a separate module to simplify testing.
-module Puppet::Node::Searching
- # Retrieve a node from the node source, with some additional munging
- # thrown in for kicks.
- def search(key)
- return nil unless key
- if node = cached?(key)
- return node
- end
- facts = node_facts(key)
- node = nil
- names = node_names(key, facts)
- names.each do |name|
- name = name.to_s if name.is_a?(Symbol)
- if node = find(name)
- #Puppet.info "Found %s in %s" % [name, @source]
- break
- end
- end
-
- # If they made it this far, we haven't found anything, so look for a
- # default node.
- unless node or names.include?("default")
- if node = find("default")
- Puppet.notice "Using default node for %s" % key
- end
- end
-
- if node
- node.names = names
-
- cache(node)
-
- return node
- else
- return nil
- end
- end
-
- private
-
- # Store the node to make things a bit faster.
- def cache(node)
- @node_cache ||= {}
- @node_cache[node.name] = node
- end
-
- # If the node is cached, return it.
- def cached?(name)
- # Don't use cache when the filetimeout is set to 0
- return false if [0, "0"].include?(Puppet[:filetimeout])
- @node_cache ||= {}
-
- if node = @node_cache[name] and Time.now - node.time < Puppet[:filetimeout]
- return node
- else
- return false
- end
- end
-
- # Look up the node facts from our fact handler.
- def node_facts(key)
- if facts = Puppet::Node::Facts.find(key)
- facts.values
- else
- {}
- end
- end
-
- # Calculate the list of node names we should use for looking
- # up our node.
- def node_names(key, facts = nil)
- facts ||= node_facts(key)
- names = []
-
- if hostname = facts["hostname"]
- unless hostname == key
- names << hostname
- end
- else
- hostname = key
- end
-
- if fqdn = facts["fqdn"]
- hostname = fqdn
- names << fqdn
- end
-
- # Make sure both the fqdn and the short name of the
- # host can be used in the manifest
- if hostname =~ /\./
- names << hostname.sub(/\..+/,'')
- elsif domain = facts['domain']
- names << hostname + "." + domain
- end
-
- # Sort the names inversely by name length.
- names.sort! { |a,b| b.length <=> a.length }
-
- # And make sure the key is first, since that's the most
- # likely usage.
- ([key] + names).uniq
- end
-end
diff --git a/lib/puppet/reference/node_sources.rb b/lib/puppet/reference/node_source.rb
index 33a4c539c..29a01f850 100644
--- a/lib/puppet/reference/node_sources.rb
+++ b/lib/puppet/reference/node_source.rb
@@ -1,7 +1,9 @@
+require 'puppet/node'
+
noderef = Puppet::Util::Reference.newreference :node_source, :doc => "Sources of node configuration information" do
- Puppet::Network::Handler.node.sourcedocs
+ Puppet::Network::Handler.node.docs
end
-nodref.header = "
+noderef.header = "
Nodes can be searched for in different locations. This document describes those different locations.
"
diff --git a/spec/unit/indirector/configuration/compiler.rb b/spec/unit/indirector/configuration/compiler.rb
index c024fe995..d949a28a5 100755
--- a/spec/unit/indirector/configuration/compiler.rb
+++ b/spec/unit/indirector/configuration/compiler.rb
@@ -23,8 +23,8 @@ describe Puppet::Node::Configuration::Compiler do
node1 = stub 'node1', :merge => nil
node2 = stub 'node2', :merge => nil
compiler.stubs(:compile)
- Puppet::Node.stubs(:search).with('node1').returns(node1)
- Puppet::Node.stubs(:search).with('node2').returns(node2)
+ Puppet::Node.stubs(:find_by_any_name).with('node1').returns(node1)
+ Puppet::Node.stubs(:find_by_any_name).with('node2').returns(node2)
compiler.find('node1')
compiler.find('node2')
@@ -68,13 +68,13 @@ describe Puppet::Node::Configuration::Compiler, " when finding nodes" do
it "should look node information up via the Node class with the provided key" do
@node.stubs :merge
- Puppet::Node.expects(:search).with(@name).returns(@node)
+ Puppet::Node.expects(:find_by_any_name).with(@name).returns(@node)
@compiler.find(@name)
end
it "should fail if it cannot find the node" do
@node.stubs :merge
- Puppet::Node.expects(:search).with(@name).returns(nil)
+ Puppet::Node.expects(:find_by_any_name).with(@name).returns(nil)
proc { @compiler.find(@name) }.should raise_error(Puppet::Error)
end
end
@@ -89,7 +89,7 @@ describe Puppet::Node::Configuration::Compiler, " after finding nodes" do
@name = "me"
@node = mock 'node'
@compiler.stubs(:compile)
- Puppet::Node.stubs(:search).with(@name).returns(@node)
+ Puppet::Node.stubs(:find_by_any_name).with(@name).returns(@node)
end
it "should add the server's Puppet version to the node's parameters as 'serverversion'" do
@@ -125,11 +125,11 @@ describe Puppet::Node::Configuration::Compiler, " when creating configurations"
@name = "me"
@node = Puppet::Node.new @name
@node.stubs(:merge)
- Puppet::Node.stubs(:search).with(@name).returns(@node)
+ Puppet::Node.stubs(:find_by_any_name).with(@name).returns(@node)
end
it "should directly use provided nodes" do
- Puppet::Node.expects(:search).never
+ Puppet::Node.expects(:find_by_any_name).never
@compiler.interpreter.expects(:compile).with(@node)
@compiler.find(@node)
end
@@ -195,7 +195,7 @@ describe Puppet::Node::Configuration::Compiler, " when determining a client's av
end
it "should return a version of 0 if no information on the node can be found" do
- Puppet::Node.stubs(:search).returns(nil)
+ Puppet::Node.stubs(:find_by_any_name).returns(nil)
@configuration.version(@name).should == 0
end
diff --git a/spec/unit/indirector/indirection.rb b/spec/unit/indirector/indirection.rb
index 5d8453905..36192b8e5 100755
--- a/spec/unit/indirector/indirection.rb
+++ b/spec/unit/indirector/indirection.rb
@@ -9,6 +9,7 @@ module IndirectionTesting
@indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
@terminus = stub 'terminus', :has_most_recent? => false
@indirection.stubs(:terminus).returns(@terminus)
+ @indirection.stubs(:terminus_class).returns(:whatever)
@instance = stub 'instance', :version => nil, :version= => nil, :name => "whatever"
@name = :mything
end
@@ -176,6 +177,40 @@ describe Puppet::Indirector::Indirection, " when managing indirection instances"
end
end
+describe Puppet::Indirector::Indirection, " when choosing the terminus class" do
+ before do
+ @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
+ @terminus = mock 'terminus'
+ @terminus_class = stub 'terminus class', :new => @terminus
+ Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :default).returns(@terminus_class)
+ end
+
+ it "should choose the default terminus class if one is specified and no specific terminus class is provided" do
+ @indirection.terminus_class = :default
+ @indirection.terminus_class.should equal(:default)
+ end
+
+ it "should use the provided Puppet setting if told to do so" do
+ Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :my_terminus).returns(mock("terminus_class2"))
+ Puppet.settings.expects(:value).with(:my_setting).returns("my_terminus")
+ @indirection.terminus_setting = :my_setting
+ @indirection.terminus_class.should equal(:my_terminus)
+ end
+
+ it "should fail if the provided terminus class is not valid" do
+ Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :nosuchclass).returns(nil)
+ proc { @indirection.terminus_class = :nosuchclass }.should raise_error(ArgumentError)
+ end
+
+ it "should fail if no terminus class is picked" do
+ proc { @indirection.terminus_class }.should raise_error(Puppet::DevError)
+ end
+
+ after do
+ @indirection.delete if defined? @indirection
+ end
+end
+
describe Puppet::Indirector::Indirection, " when specifying the terminus class to use" do
before do
@indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
diff --git a/spec/unit/node.rb b/spec/unit/node.rb
index 26aec4196..8aea6ef0b 100755
--- a/spec/unit/node.rb
+++ b/spec/unit/node.rb
@@ -138,3 +138,69 @@ describe Puppet::Node do
# central server.
it "should provide a method for noting that the node has connected"
end
+
+describe Puppet::Node, " when searching for nodes" do
+ before do
+ @searcher = Puppet::Node
+ @facts = Puppet::Node::Facts.new("foo", "hostname" => "yay", "domain" => "domain.com")
+ @node = Puppet::Node.new("foo")
+ Puppet::Node::Facts.stubs(:find).with("foo").returns(@facts)
+ end
+
+ it "should return the first node found using the generated list of names" do
+ @searcher.expects(:find).with("foo").returns(nil)
+ @searcher.expects(:find).with("yay.domain.com").returns(@node)
+ @searcher.find_by_any_name("foo").should equal(@node)
+ end
+
+ it "should search for the node by its key first" do
+ names = []
+ @searcher.expects(:find).with do |name|
+ names << name
+ names == %w{foo}
+ end.returns(@node)
+ @searcher.find_by_any_name("foo").should equal(@node)
+ end
+
+ it "should search for the rest of the names inversely by length" do
+ names = []
+ @facts.values["fqdn"] = "longer.than.the.normal.fqdn.com"
+ @searcher.stubs(:find).with do |name|
+ names << name
+ end
+ @searcher.find_by_any_name("foo")
+ # Strip off the key
+ names.shift
+
+ # And the 'default'
+ names.pop
+
+ length = 100
+ names.each do |name|
+ (name.length < length).should be_true
+ length = name.length
+ end
+ end
+
+ it "should attempt to find a default node if no names are found" do
+ names = []
+ @searcher.stubs(:find).with do |name|
+ names << name
+ end.returns(nil)
+ @searcher.find_by_any_name("foo")
+ names[-1].should == "default"
+ end
+
+ it "should flush the node cache using the :filetimeout parameter" do
+ node2 = Puppet::Node.new("foo2")
+ Puppet[:filetimeout] = -1
+ # I couldn't get this to work with :expects
+ @searcher.stubs(:find).returns(@node, node2).then.raises(ArgumentError)
+ @searcher.find_by_any_name("foo").should equal(@node)
+ @searcher.find_by_any_name("foo").should equal(node2)
+ end
+
+ after do
+ Puppet.settings.clear
+ end
+end
diff --git a/spec/unit/node/searching.rb b/spec/unit/node/searching.rb
deleted file mode 100755
index e747996e4..000000000
--- a/spec/unit/node/searching.rb
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/usr/bin/env ruby
-
-require File.dirname(__FILE__) + '/../../spec_helper'
-require 'puppet/node/searching'
-require 'puppet/node/facts'
-
-describe Puppet::Node::Searching, " when searching for nodes" do
- before do
- @searcher = Object.new
- @searcher.extend(Puppet::Node::Searching)
- @facts = Puppet::Node::Facts.new("foo", "hostname" => "yay", "domain" => "domain.com")
- @node = Puppet::Node.new("foo")
- Puppet::Node::Facts.stubs(:find).with("foo").returns(@facts)
- end
-
- it "should search for the node by its key first" do
- names = []
- @searcher.expects(:find).with do |name|
- names << name
- names == %w{foo}
- end.returns(@node)
- @searcher.search("foo").should equal(@node)
- end
-
- it "should return the first node found using the generated list of names" do
- names = []
- @searcher.expects(:find).with("foo").returns(nil)
- @searcher.expects(:find).with("yay.domain.com").returns(@node)
- @searcher.search("foo").should equal(@node)
- end
-
- it "should search for the rest of the names inversely by length" do
- names = []
- @facts.values["fqdn"] = "longer.than.the.normal.fqdn.com"
- @searcher.stubs(:find).with do |name|
- names << name
- end
- @searcher.search("foo")
- # Strip off the key
- names.shift
-
- # And the 'default'
- names.pop
-
- length = 100
- names.each do |name|
- (name.length < length).should be_true
- length = name.length
- end
- end
-
- it "should attempt to find a default node if no names are found" do
- names = []
- @searcher.stubs(:find).with do |name|
- names << name
- end.returns(nil)
- @searcher.search("foo")
- names[-1].should == "default"
- end
-
- it "should cache the nodes" do
- @searcher.expects(:find).with("foo").returns(@node)
- @searcher.search("foo").should equal(@node)
- @searcher.search("foo").should equal(@node)
- end
-
- it "should flush the node cache using the :filetimeout parameter" do
- node2 = Puppet::Node.new("foo2")
- Puppet[:filetimeout] = -1
- # I couldn't get this to work with :expects
- @searcher.stubs(:find).returns(@node, node2).then.raises(ArgumentError)
- @searcher.search("foo").should equal(@node)
- @searcher.search("foo").should equal(node2)
- end
-
- after do
- Puppet.settings.clear
- end
-end
diff --git a/test/network/handler/configuration.rb b/test/network/handler/configuration.rb
index e560bd624..36c5d9e54 100755
--- a/test/network/handler/configuration.rb
+++ b/test/network/handler/configuration.rb
@@ -145,7 +145,7 @@ class TestHandlerConfiguration < Test::Unit::TestCase
# First try the case where we can't look up the node
config = Config.new
node = Object.new
- Puppet::Node.stubs(:search).with(:client).returns(false, node)
+ Puppet::Node.stubs(:find_by_any_name).with(:client).returns(false, node)
interp = Object.new
assert_instance_of(Bignum, config.version(:client), "Did not return configuration version")