summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGunnar Wrobel <p@rdus.de>2008-05-15 08:27:07 +0200
committerLuke Kanies <luke@madstop.com>2008-05-15 10:39:12 -0500
commit158d3df805ebe28f52db5ced928dda7129aeec1b (patch)
treef0a76a332e9c392a686f8a841b44063ec93408e9
parente972a3bcf0c95eaf7797d15734257d189ff8c3bf (diff)
downloadpuppet-158d3df805ebe28f52db5ced928dda7129aeec1b.tar.gz
puppet-158d3df805ebe28f52db5ced928dda7129aeec1b.tar.xz
puppet-158d3df805ebe28f52db5ced928dda7129aeec1b.zip
Added the ability to add arbitrary attributes to ldap.
This fixes #1179.
-rw-r--r--ext/ldap/puppet.schema7
-rw-r--r--lib/puppet/defaults.rb4
-rw-r--r--lib/puppet/indirector/node/ldap.rb29
-rwxr-xr-xspec/unit/indirector/node/ldap.rb91
4 files changed, 130 insertions, 1 deletions
diff --git a/ext/ldap/puppet.schema b/ext/ldap/puppet.schema
index d8dc4260d..a7a5f46ff 100644
--- a/ext/ldap/puppet.schema
+++ b/ext/ldap/puppet.schema
@@ -17,6 +17,11 @@ attributetype ( 1.1.3.11 NAME 'environment'
EQUALITY caseIgnoreIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+attributetype ( 1.1.3.12 NAME 'puppetvar'
+ DESC 'A variable setting for puppet'
+ EQUALITY caseIgnoreIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
objectclass ( 1.1.1.2 NAME 'puppetClient' SUP top AUXILIARY
DESC 'Puppet Client objectclass'
- MAY ( puppetclass $ parentnode $ environment ))
+ MAY ( puppetclass $ parentnode $ environment $ puppetvar ))
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/spec/unit/indirector/node/ldap.rb b/spec/unit/indirector/node/ldap.rb
index a40698662..878039c7c 100755
--- a/spec/unit/indirector/node/ldap.rb
+++ b/spec/unit/indirector/node/ldap.rb
@@ -17,6 +17,7 @@ describe Puppet::Node::Ldap do
@searcher.stubs(:connection).returns(@connection)
@searcher.stubs(:class_attributes).returns([])
@searcher.stubs(:parent_attribute).returns(nil)
+ @searcher.stubs(:stacked_attributes).returns([])
@searcher.stubs(:search_base).returns(:yay)
@searcher.stubs(:search_filter).returns(:filter)
@@ -195,6 +196,96 @@ describe Puppet::Node::Ldap do
proc { @searcher.find(@request) }.should raise_error(ArgumentError)
end
end
+
+ describe "and a puppet variable is specified" do
+ before do
+ @searcher.stubs(:stacked_attributes).returns(['puppetvar'])
+ end
+
+ it "should add the variable to the node parameters" do
+ @entry.stubs(:vals).with("puppetvar").returns(%w{one=two})
+ @entry.stubs(:to_hash).returns({})
+ @node.expects(:parameters=).with("one" => "two")
+ @searcher.find(@request)
+ end
+
+ it "should not overwrite node parameters specified as ldap object attribute" do
+ @entry.stubs(:vals).with("puppetvar").returns(%w{one=two})
+ @entry.stubs(:to_hash).returns("one" => "three")
+ @node.expects(:parameters=).with("one" => "three")
+ @searcher.find(@request)
+ end
+
+ it "should set entries without an equal sign to nil" do
+ @entry.stubs(:vals).with("puppetvar").returns(%w{one})
+ @entry.stubs(:to_hash).returns({})
+ @node.expects(:parameters=).with("one" => nil)
+ @searcher.find(@request)
+ end
+
+ it "should ignore empty entries" do
+ @entry.stubs(:vals).with("puppetvar").returns(%w{})
+ @entry.stubs(:to_hash).returns({})
+ @searcher.find(@request)
+ end
+ end
+ describe "and a puppet variable as well as a parent node are specified" do
+ before do
+ @parent = mock 'parent'
+
+ @searcher.meta_def(:search_filter) do |name|
+ return name
+ end
+ @connection.stubs(:search).with { |*args| args[2] == @name }.yields(@entry)
+ @connection.stubs(:search).with { |*args| args[2] == 'parent' }.yields(@parent)
+
+ @searcher.stubs(:stacked_attributes).returns(['puppetvar'])
+ @searcher.stubs(:parent_attribute).returns(:parent)
+ end
+
+ it "should add parent node variables to the child node parameters" do
+ @parent.stubs(:to_hash).returns({})
+ @parent.stubs(:vals).with("puppetvar").returns(%w{one=two})
+ @parent.stubs(:vals).with(:parent).returns(nil)
+
+ @entry.stubs(:to_hash).returns({})
+ @entry.stubs(:vals).with("puppetvar").returns(%w{})
+ @entry.stubs(:vals).with(:parent).returns(%w{parent})
+
+ @node.expects(:parameters=).with("one" => "two")
+
+ @searcher.find(@request)
+ end
+
+ it "should overwrite parent node variables with child node parameters" do
+ @parent.stubs(:to_hash).returns({})
+ @parent.stubs(:vals).with("puppetvar").returns(%w{one=two})
+ @parent.stubs(:vals).with(:parent).returns(nil)
+
+ @entry.stubs(:to_hash).returns({})
+ @entry.stubs(:vals).with("puppetvar").returns(%w{one=three})
+ @entry.stubs(:vals).with(:parent).returns(%w{parent})
+
+ @node.expects(:parameters=).with("one" => "three")
+
+ @searcher.find(@request)
+ end
+
+ it "should not overwrite parent node parameters specified as ldap object attribute" do
+ @parent.stubs(:to_hash).returns("one" => "three")
+ @parent.stubs(:vals).with("puppetvar").returns(%w{})
+ @parent.stubs(:vals).with(:parent).returns(nil)
+
+ @entry.stubs(:vals).with("puppetvar").returns(%w{one=two})
+ @entry.stubs(:to_hash).returns({})
+ @entry.stubs(:vals).with(:parent).returns(%w{parent})
+
+ @node.expects(:parameters=).with("one" => "three")
+
+ @searcher.find(@request)
+ end
+
+ end
end
end