summaryrefslogtreecommitdiffstats
path: root/lib/puppet
diff options
context:
space:
mode:
authorJames Turnbull <james@lovedthanlost.net>2008-05-16 16:08:56 +1000
committerJames Turnbull <james@lovedthanlost.net>2008-05-16 16:08:56 +1000
commit7897335318be2bb98187b570fb7c867ebe109c12 (patch)
treec337fc64373fa3424e0449907ca46ea142345ca3 /lib/puppet
parent83ef1b0cda1b010eea3f7d001716ea52f7081c24 (diff)
parenta1409d73b4bb8acbf5db2f8d7a244c2bca81db14 (diff)
downloadpuppet-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.rb4
-rw-r--r--lib/puppet/indirector/node/ldap.rb29
-rw-r--r--lib/puppet/provider.rb104
-rw-r--r--lib/puppet/provider/confine.rb89
-rw-r--r--lib/puppet/provider/confine_collection.rb48
-rw-r--r--lib/puppet/provider/confiner.rb20
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