diff options
Diffstat (limited to 'lib/puppet')
-rw-r--r-- | lib/puppet/indirector/catalog/compiler.rb | 2 | ||||
-rw-r--r-- | lib/puppet/indirector/ldap.rb | 12 | ||||
-rw-r--r-- | lib/puppet/indirector/node/ldap.rb | 122 | ||||
-rw-r--r-- | lib/puppet/node.rb | 118 |
4 files changed, 119 insertions, 135 deletions
diff --git a/lib/puppet/indirector/catalog/compiler.rb b/lib/puppet/indirector/catalog/compiler.rb index 2b5e8d912..455a92cc7 100644 --- a/lib/puppet/indirector/catalog/compiler.rb +++ b/lib/puppet/indirector/catalog/compiler.rb @@ -89,7 +89,7 @@ class Puppet::Node::Catalog::Compiler < Puppet::Indirector::Code # key = client #end - return nil unless node = Puppet::Node.find_by_any_name(key) + return nil unless node = Puppet::Node.find(key) # Add any external data to the node. add_node_data(node) diff --git a/lib/puppet/indirector/ldap.rb b/lib/puppet/indirector/ldap.rb index 07ad38933..695d38a95 100644 --- a/lib/puppet/indirector/ldap.rb +++ b/lib/puppet/indirector/ldap.rb @@ -1,14 +1,16 @@ require 'puppet/indirector/terminus' class Puppet::Indirector::Ldap < Puppet::Indirector::Terminus - # Perform our ldap search and process the result. - def find(request) + # We split this apart so it's easy to call multiple times with different names. + def entry2hash(name) # We have to use 'yield' here because the LDAP::Entry objects # get destroyed outside the scope of the search, strangely. - ldapsearch(request.key) { |entry| return process(request.key, entry) } + ldapsearch(name) { |entry| return process(name, entry) } + end - # Return nil if we haven't found something. - return nil + # Perform our ldap search and process the result. + def find(request) + return entry2hash(request.key) || nil end # Process the found entry. We assume that we don't just want the diff --git a/lib/puppet/indirector/node/ldap.rb b/lib/puppet/indirector/node/ldap.rb index bc58908fd..4ed053eff 100644 --- a/lib/puppet/indirector/node/ldap.rb +++ b/lib/puppet/indirector/node/ldap.rb @@ -3,7 +3,9 @@ require 'puppet/indirector/ldap' class Puppet::Node::Ldap < Puppet::Indirector::Ldap desc "Search in LDAP for node configuration information. See - the `LdapNodes`:trac: page for more information." + the `LdapNodes`:trac: page for more information. This will first + search for whatever the certificate name is, then (if that name + contains a '.') for the short name, then 'default'." # The attributes that Puppet class information is stored in. def class_attributes @@ -13,57 +15,23 @@ class Puppet::Node::Ldap < Puppet::Indirector::Ldap # Look for our node in ldap. def find(request) - return nil unless information = super - - name = request.key - - node = Puppet::Node.new(name) - - information[:stacked_parameters] = {} - - parent_info = nil - parent = information[:parent] - parents = [name] - while parent - if parents.include?(parent) - raise ArgumentError, "Found loop in LDAP node parents; %s appears twice" % parent - end - parents << parent - - ldapsearch(parent) { |entry| parent_info = process(parent, entry) } - - unless parent_info - raise Puppet::Error.new("Could not find parent node '%s'" % parent) - end - information[:classes] += parent_info[:classes] - parent_info[:stacked].each do |value| - param = value.split('=', 2) - information[:stacked_parameters][param[0]] = param[1] - end - parent_info[:parameters].each do |param, value| - # Specifically test for whether it's set, so false values are handled - # correctly. - information[:parameters][param] = value unless information[:parameters].include?(param) - end - - information[:environment] ||= parent_info[:environment] - - parent = parent_info[:parent] + names = [request.key] + if request.key.include?(".") # we assume it's an fqdn + names << request.key.sub(/\..+/, '') end + names << "default" - information[:stacked].each do |value| - param = value.split('=', 2) - information[:stacked_parameters][param[0]] = param[1] + information = nil + names.each do |name| + break if information = entry2hash(name) end + return nil unless information - information[:stacked_parameters].each do |param, value| - information[:parameters][param] = value unless information[:parameters].include?(param) - end + name = request.key - node.classes = information[:classes].uniq unless information[:classes].empty? - node.parameters = information[:parameters] unless information[:parameters].empty? - node.environment = information[:environment] if information[:environment] - node.fact_merge + node = Puppet::Node.new(name) + + add_to_node(node, information) return node end @@ -155,4 +123,64 @@ class Puppet::Node::Ldap < Puppet::Indirector::Ldap end filter end + + private + + # Add our hash of ldap information to the node instance. + def add_to_node(node, information) + information[:stacked_parameters] = {} + + parent_info = nil + parent = information[:parent] + parents = [node.name] + while parent + if parents.include?(parent) + raise ArgumentError, "Found loop in LDAP node parents; %s appears twice" % parent + end + parents << parent + parent = find_and_merge_parent(parent, information) + end + + if information[:stacked] + information[:stacked].each do |value| + param = value.split('=', 2) + information[:stacked_parameters][param[0]] = param[1] + end + end + + if information[:stacked_parameters] + information[:stacked_parameters].each do |param, value| + information[:parameters][param] = value unless information[:parameters].include?(param) + end + end + + node.classes = information[:classes].uniq unless information[:classes].nil? or information[:classes].empty? + node.parameters = information[:parameters] unless information[:parameters].nil? or information[:parameters].empty? + node.environment = information[:environment] if information[:environment] + node.fact_merge + end + + # Find information for our parent and merge it into the current info. + def find_and_merge_parent(parent, information) + parent_info = nil + ldapsearch(parent) { |entry| parent_info = process(parent, entry) } + + unless parent_info + raise Puppet::Error.new("Could not find parent node '%s'" % parent) + end + information[:classes] += parent_info[:classes] + parent_info[:stacked].each do |value| + param = value.split('=', 2) + information[:stacked_parameters][param[0]] = param[1] + end + parent_info[:parameters].each do |param, value| + # Specifically test for whether it's set, so false values are handled + # correctly. + information[:parameters][param] = value unless information[:parameters].include?(param) + end + + information[:environment] ||= parent_info[:environment] + + parent_info[:parent] + end end diff --git a/lib/puppet/node.rb b/lib/puppet/node.rb index 576e2265d..14d0f6ac7 100644 --- a/lib/puppet/node.rb +++ b/lib/puppet/node.rb @@ -13,88 +13,7 @@ class Puppet::Node indirects :node, :terminus_setting => :node_terminus, :doc => "Where to find node information. A node is composed of its name, its facts, and its environment." - # 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 - - node = nil - names = node_names(key) - 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 - - return nil unless node - - node.names = names - - # This is critical, because it forces our node's name to always - # be the key, which is nearly always the node's certificate. - # This is how the node instance is linked to the Facts instance, - # so it quite matters. - node.name = key - return node - end - - private - - # Look up the node facts so we can generate the node names to use. - 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 = [] - - # First, get the fqdn - unless fqdn = facts["fqdn"] - if domain = facts["domain"] - fqdn = facts["hostname"] + "." + facts["domain"] - end - end - - # Now that we (might) have the fqdn, add each piece to the name - # list to search, in order of longest to shortest. - if fqdn - list = fqdn.split(".") - tmp = [] - list.each_with_index do |short, i| - tmp << list[0..i].join(".") - end - names += tmp.reverse - end - - # And make sure the key is first, since that's the most - # likely usage. - # The key is usually the Certificate CN, but it can be - # set to the 'facter' hostname instead. - if Puppet[:node_name] == 'cert' - names.unshift key - else - names.unshift facts["hostname"] - end - names.uniq - end - - public - - attr_accessor :name, :classes, :parameters, :source, :ipaddress, :names + attr_accessor :name, :classes, :parameters, :source, :ipaddress attr_reader :time # Set the environment, making sure that it's valid. @@ -165,4 +84,39 @@ class Puppet::Node @parameters[name] = value unless @parameters.include?(name) end end + + # Calculate the list of names we might use for looking + # up our node. This is only used for AST nodes. + def names + names = [] + + # First, get the fqdn + unless fqdn = parameters["fqdn"] + if domain = parameters["domain"] + fqdn = parameters["hostname"] + "." + parameters["domain"] + end + end + + # Now that we (might) have the fqdn, add each piece to the name + # list to search, in order of longest to shortest. + if fqdn + list = fqdn.split(".") + tmp = [] + list.each_with_index do |short, i| + tmp << list[0..i].join(".") + end + names += tmp.reverse + end + + # And make sure the node name is first, since that's the most + # likely usage. + # The name is usually the Certificate CN, but it can be + # set to the 'facter' hostname instead. + if Puppet[:node_name] == 'cert' + names.unshift name + else + names.unshift parameters["hostname"] + end + names.uniq + end end |