summaryrefslogtreecommitdiffstats
path: root/lib/puppet/parser/interpreter.rb
diff options
context:
space:
mode:
authorluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2006-02-14 06:21:04 +0000
committerluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2006-02-14 06:21:04 +0000
commit6cfee76f94824157a28354c9d6838716cb2c5d47 (patch)
treefb82fc83a94de987824aa129066df72878f3179c /lib/puppet/parser/interpreter.rb
parent19942633b69f04c6789ef08a04d434024e1bc334 (diff)
downloadpuppet-6cfee76f94824157a28354c9d6838716cb2c5d47.tar.gz
puppet-6cfee76f94824157a28354c9d6838716cb2c5d47.tar.xz
puppet-6cfee76f94824157a28354c9d6838716cb2c5d47.zip
Committing the initial ldap support -- puppet can now look up node configurations in ldap. The test scripts currently only work on my home network.
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@909 980ebf18-57e1-0310-9a29-db15c13687c0
Diffstat (limited to 'lib/puppet/parser/interpreter.rb')
-rw-r--r--lib/puppet/parser/interpreter.rb125
1 files changed, 124 insertions, 1 deletions
diff --git a/lib/puppet/parser/interpreter.rb b/lib/puppet/parser/interpreter.rb
index 7bb9f6b3b..ce6a9935c 100644
--- a/lib/puppet/parser/interpreter.rb
+++ b/lib/puppet/parser/interpreter.rb
@@ -10,6 +10,32 @@ require 'puppet/parser/scope'
module Puppet
module Parser
class Interpreter
+ Puppet.setdefaults("ldap",
+ [:ldapnodes, false,
+ "Whether to search for node configurations in LDAP."],
+ [:ldapserver, "ldap",
+ "The LDAP server. Only used if ``ldapnodes`` is enabled."],
+ [:ldapport, 389,
+ "The LDAP port. Only used if ``ldapnodes`` is enabled."],
+ [:ldapstring, "(&(objectclass=puppetClient)(cn=%s))",
+ "The search string used to find an LDAP node."],
+ [:ldapattrs, "puppetclass",
+ "The LDAP attributes to use to define Puppet classes. Values
+ should be comma-separated."],
+ [:ldapparentattr, "parentnode",
+ "The attribute to use to define the parent node."],
+ [:ldapuser, "",
+ "The user to use to connect to LDAP. Must be specified as a
+ full DN."],
+ [:ldappassword, "",
+ "The password to use to connect to LDAP."],
+ [:ldapbase, "",
+ "The search base for LDAP searches. It's impossible to provide
+ a meaningful default here, although the LDAP libraries might
+ have one already set. Generally, it should be the 'ou=Hosts'
+ branch under your main directory."]
+ )
+
attr_accessor :ast, :filetimeout
# just shorten the constant path a bit, using what amounts to an alias
AST = Puppet::Parser::AST
@@ -31,6 +57,20 @@ module Puppet
@usenodes = true
end
+ @nodesources = hash[:NodeSources] || [:file]
+
+ @nodesources.each { |source|
+ method = "setup_%s" % source.to_s
+ if respond_to? method
+ begin
+ self.send(method)
+ rescue => detail
+ raise Puppet::Error,
+ "Could not set up node source %s" % source
+ end
+ end
+ }
+
# Set it to either the value or nil. This is currently only used
# by the cfengine module.
@classes = hash[:Classes] || []
@@ -41,6 +81,73 @@ module Puppet
evaluate
end
+ # Connect to the LDAP Server
+ def setup_ldap
+ require 'ldap'
+ begin
+ @ldap = LDAP::Conn.new(Puppet[:ldapserver], Puppet[:ldapport])
+ @ldap.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
+ @ldap.simple_bind(Puppet[:ldapuser], Puppet[:ldappassword])
+ rescue => detail
+ raise Puppet::Error, "Could not connect to LDAP: %s" % detail
+ end
+ end
+
+ # Find the ldap node and extra the info, returning just
+ # the critical data.
+ def nodesearch_ldap(node)
+ unless defined? @ldap
+ ldapconnect()
+ end
+
+ filter = Puppet[:ldapstring]
+ attrs = Puppet[:ldapattrs].split("\s*,\s*")
+ sattrs = attrs.dup
+ pattr = nil
+ if pattr = Puppet[:ldapparentattr]
+ if pattr == ""
+ pattr = nil
+ else
+ sattrs << pattr
+ end
+ end
+
+ if filter =~ /%s/
+ filter = filter.gsub(/%s/, node)
+ end
+
+ parent = nil
+ classes = []
+
+ found = false
+ # We're always doing a sub here; oh well.
+ @ldap.search(Puppet[:ldapbase], 2, filter, sattrs) do |entry|
+ found = true
+ if pattr
+ if values = entry.vals(pattr)
+ if values.length > 1
+ raise Puppet::Error,
+ "Node %s has more than one parent: %s" %
+ [node, values.inspect]
+ end
+ unless values.empty?
+ parent = values.shift
+ end
+ end
+ end
+
+ attrs.each { |attr|
+ if values = entry.vals(attr)
+ classes += values
+ end
+ }
+ end
+
+ classes.flatten!
+
+ return parent, classes
+ end
+
def parsedate
parsefiles()
@parsedate
@@ -67,8 +174,24 @@ module Puppet
"Cannot evaluate nodes with a nil client"
end
+ classes = nil
+ parent = nil
+ # At this point, stop at the first source that defines
+ # the node
+ @nodesources.each do |source|
+ method = "nodesearch_%s" % source
+ if self.respond_to? method
+ parent, classes = self.send(method, client)
+ end
+
+ if classes
+ Puppet.info "Found %s in %s" % [client, source]
+ break
+ end
+ end
+
# We've already evaluated the AST, in this case
- return @scope.evalnode(names, facts)
+ return @scope.evalnode(names, facts, classes, parent)
else
# We've already evaluated the AST, in this case
@scope = Puppet::Parser::Scope.new() # no parent scope