diff options
author | James Turnbull <james@lovedthanlost.net> | 2008-05-16 16:08:56 +1000 |
---|---|---|
committer | James Turnbull <james@lovedthanlost.net> | 2008-05-16 16:08:56 +1000 |
commit | 7897335318be2bb98187b570fb7c867ebe109c12 (patch) | |
tree | c337fc64373fa3424e0449907ca46ea142345ca3 /lib/puppet | |
parent | 83ef1b0cda1b010eea3f7d001716ea52f7081c24 (diff) | |
parent | a1409d73b4bb8acbf5db2f8d7a244c2bca81db14 (diff) | |
download | puppet-7897335318be2bb98187b570fb7c867ebe109c12.tar.gz puppet-7897335318be2bb98187b570fb7c867ebe109c12.tar.xz puppet-7897335318be2bb98187b570fb7c867ebe109c12.zip |
Merge branch '0.24.x' of git://github.com/lak/puppet into 0.24.x
Diffstat (limited to 'lib/puppet')
-rw-r--r-- | lib/puppet/defaults.rb | 4 | ||||
-rw-r--r-- | lib/puppet/indirector/node/ldap.rb | 29 | ||||
-rw-r--r-- | lib/puppet/provider.rb | 104 | ||||
-rw-r--r-- | lib/puppet/provider/confine.rb | 89 | ||||
-rw-r--r-- | lib/puppet/provider/confine_collection.rb | 48 | ||||
-rw-r--r-- | lib/puppet/provider/confiner.rb | 20 |
6 files changed, 199 insertions, 95 deletions
diff --git a/lib/puppet/defaults.rb b/lib/puppet/defaults.rb index eed1a00f3..df2fb9425 100644 --- a/lib/puppet/defaults.rb +++ b/lib/puppet/defaults.rb @@ -622,6 +622,10 @@ module Puppet :ldapclassattrs => ["puppetclass", "The LDAP attributes to use to define Puppet classes. Values should be comma-separated."], + :ldapstackedattrs => ["puppetvar", + "The LDAP attributes that should be stacked to arrays by adding + the values in all hierarchy elements of the tree. Values + should be comma-separated."], :ldapattrs => ["all", "The LDAP attributes to include when querying LDAP for nodes. All returned attributes are set as variables in the top-level scope. diff --git a/lib/puppet/indirector/node/ldap.rb b/lib/puppet/indirector/node/ldap.rb index 6c41c18d4..bc58908fd 100644 --- a/lib/puppet/indirector/node/ldap.rb +++ b/lib/puppet/indirector/node/ldap.rb @@ -19,6 +19,8 @@ class Puppet::Node::Ldap < Puppet::Indirector::Ldap node = Puppet::Node.new(name) + information[:stacked_parameters] = {} + parent_info = nil parent = information[:parent] parents = [name] @@ -34,6 +36,10 @@ class Puppet::Node::Ldap < Puppet::Indirector::Ldap 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. @@ -45,6 +51,15 @@ class Puppet::Node::Ldap < Puppet::Indirector::Ldap parent = parent_info[:parent] end + information[:stacked].each do |value| + param = value.split('=', 2) + information[:stacked_parameters][param[0]] = param[1] + end + + information[:stacked_parameters].each do |param, value| + information[:parameters][param] = value unless information[:parameters].include?(param) + end + node.classes = information[:classes].uniq unless information[:classes].empty? node.parameters = information[:parameters] unless information[:parameters].empty? node.environment = information[:environment] if information[:environment] @@ -62,6 +77,12 @@ class Puppet::Node::Ldap < Puppet::Indirector::Ldap end end + # The attributes that Puppet will stack as array over the full + # hierarchy. + def stacked_attributes + Puppet[:ldapstackedattrs].split(/\s*,\s*/) + end + # Process the found entry. We assume that we don't just want the # ldap object. def process(name, entry) @@ -85,6 +106,14 @@ class Puppet::Node::Ldap < Puppet::Indirector::Ldap end } + result[:stacked] = [] + stacked_attributes.each { |attr| + if values = entry.vals(attr) + result[:stacked] = result[:stacked] + values + end + } + + result[:parameters] = entry.to_hash.inject({}) do |hash, ary| if ary[1].length == 1 hash[ary[0]] = ary[1].shift diff --git a/lib/puppet/provider.rb b/lib/puppet/provider.rb index e73bb0cb6..c02e15029 100644 --- a/lib/puppet/provider.rb +++ b/lib/puppet/provider.rb @@ -5,6 +5,10 @@ class Puppet::Provider include Puppet::Util::Warnings extend Puppet::Util::Warnings + require 'puppet/provider/confiner' + + extend Puppet::Provider::Confiner + Puppet::Util.logmethods(self, true) class << self @@ -40,27 +44,13 @@ class Puppet::Provider [name, self.name] end - if command == :missing - return nil - end - - command + return binary(command) end # Define commands that are not optional. def self.commands(hash) optional_commands(hash) do |name, path| - confine :exists => path - end - end - - def self.confine(hash) - hash.each do |p,v| - if v.is_a? Array - @confines[p] += v - else - @confines[p] << v - end + confine :exists => path, :for_binary => true end end @@ -108,10 +98,6 @@ class Puppet::Provider def self.initvars @defaults = {} @commands = {} - @origcommands = {} - @confines = Hash.new do |hash, key| - hash[key] = [] - end end # The method for returning a list of provider instances. Note that it returns providers, preferably with values already @@ -180,16 +166,7 @@ class Puppet::Provider def self.optional_commands(hash) hash.each do |name, path| name = symbolize(name) - @origcommands[name] = path - - # Try to find the full path (or verify already-full paths); otherwise - # store that the command is missing so we know it's defined but absent. - if tmp = binary(path) - path = tmp - @commands[name] = path - else - @commands[name] = :missing - end + @commands[name] = path if block_given? yield(name, path) @@ -208,69 +185,6 @@ class Puppet::Provider @source end - # Check whether this implementation is suitable for our platform. - def self.suitable?(short = true) - # A single false result is sufficient to turn the whole thing down. - # We don't return 'true' until the very end, though, so that every - # confine is tested. - missing = {} - @confines.each do |check, values| - case check - when :exists: - values.each do |value| - unless value and FileTest.exists? value - debug "Not suitable: missing %s" % value - return false if short - missing[:exists] ||= [] - missing[:exists] << value - end - end - when :true: - values.each do |v| - debug "Not suitable: false value" - unless v - return false if short - missing[:true] ||= 0 - missing[:true] += 1 - end - end - when :false: - values.each do |v| - debug "Not suitable: true value" - if v and short - return false if short - missing[:false] ||= 0 - missing[:false] += 1 - end - end - else # Just delegate everything else to facter - if result = Facter.value(check) - result = result.to_s.downcase.intern - - found = values.find do |v| - result == v.to_s.downcase.intern - end - unless found - debug "Not suitable: %s not in %s" % [check, values] - return false if short - missing[:facter] ||= {} - missing[:facter][check] = values - end - else - return false if short - missing[:facter] ||= {} - missing[:facter][check] = values - end - end - end - - if short - return true - else - return missing - end - end - # Does this provider support the specified parameter? def self.supports_parameter?(param) if param.is_a?(Class) @@ -309,8 +223,8 @@ class Puppet::Provider end dochook(:commands) do - if @origcommands.length > 0 - return " Required binaries: " + @origcommands.collect do |n, c| + if @commands.length > 0 + return " Required binaries: " + @commands.collect do |n, c| "``#{c}``" end.join(", ") + "." end diff --git a/lib/puppet/provider/confine.rb b/lib/puppet/provider/confine.rb new file mode 100644 index 000000000..227c923e6 --- /dev/null +++ b/lib/puppet/provider/confine.rb @@ -0,0 +1,89 @@ +# The class that handles testing whether our providers +# actually work or not. +require 'puppet/util' + +class Puppet::Provider::Confine + include Puppet::Util + + attr_reader :test, :values, :fact + + # Mark that this confine is used for testing binary existence. + attr_accessor :for_binary + def for_binary? + for_binary + end + + def exists?(value) + if for_binary? + return false unless value = binary(value) + end + value and FileTest.exist?(value) + end + + # Are we a facter comparison? + def facter? + defined?(@facter) + end + + # Retrieve the value from facter + def facter_value + unless defined?(@facter_value) and @facter_value + @facter_value = Facter.value(@fact).to_s.downcase + end + @facter_value + end + + def false?(value) + ! value + end + + def initialize(test, values) + values = [values] unless values.is_a?(Array) + @values = values + + if %w{exists false true}.include?(test.to_s) + @test = test + @method = @test.to_s + "?" + else + @fact = test + @test = :facter + @method = "match?" + end + end + + def match?(value) + facter_value == value.to_s.downcase + end + + # Collect the results of all of them. + def result + values.collect { |value| send(@method, value) } + end + + def true?(value) + # Double negate, so we only get true or false. + ! ! value + end + + # Test whether our confine matches. + def valid? + values.each do |value| + unless send(@method, value) + msg = case test + when :false: "false value when expecting true" + when :true: "true value when expecting false" + when :exists: "file %s does not exist" % value + when :facter: "facter value '%s' for '%s' not in required list '%s'" % [value, @fact, values.join(",")] + end + Puppet.debug msg + return false + end + end + + return true + ensure + # Reset the cache. We want to cache it during a given + # run, but across runs. + @facter_value = nil + end +end diff --git a/lib/puppet/provider/confine_collection.rb b/lib/puppet/provider/confine_collection.rb new file mode 100644 index 000000000..f38035521 --- /dev/null +++ b/lib/puppet/provider/confine_collection.rb @@ -0,0 +1,48 @@ +# Manage a collection of confines, returning a boolean or +# helpful information. +require 'puppet/provider/confine' + +class Puppet::Provider::ConfineCollection + def confine(hash) + if hash.include?(:for_binary) + for_binary = true + hash.delete(:for_binary) + else + for_binary = false + end + hash.each do |test, values| + @confines << Puppet::Provider::Confine.new(test, values) + @confines[-1].for_binary = true if for_binary + end + end + + def initialize + @confines = [] + end + + # Return a hash of the whole confine set, used for the Provider + # reference. + def result + defaults = { + :false => 0, + :true => 0, + :exists => [], + :facter => {} + } + missing = Hash.new { |hash, key| hash[key] = defaults[key] } + @confines.each do |confine| + case confine.test + when :false: missing[confine.test] += confine.result.find_all { |v| v == false }.length + when :true: missing[confine.test] += confine.result.find_all { |v| v == true }.length + when :exists: confine.result.zip(confine.values).each { |val, f| missing[:exists] << f unless val } + when :facter: missing[:facter][confine.fact] = confine.values if confine.result.include?(false) + end + end + + missing + end + + def valid? + ! @confines.detect { |c| ! c.valid? } + end +end diff --git a/lib/puppet/provider/confiner.rb b/lib/puppet/provider/confiner.rb new file mode 100644 index 000000000..3e406873b --- /dev/null +++ b/lib/puppet/provider/confiner.rb @@ -0,0 +1,20 @@ +require 'puppet/provider/confine_collection' + +module Puppet::Provider::Confiner + def confine(hash) + confine_collection.confine(hash) + end + + def confine_collection + unless defined?(@confine_collection) + @confine_collection = Puppet::Provider::ConfineCollection.new + end + @confine_collection + end + + # Check whether this implementation is suitable for our platform. + def suitable?(short = true) + return confine_collection.valid? if short + return confine_collection.result + end +end |