diff options
| author | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2006-02-14 06:21:04 +0000 |
|---|---|---|
| committer | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2006-02-14 06:21:04 +0000 |
| commit | 6cfee76f94824157a28354c9d6838716cb2c5d47 (patch) | |
| tree | fb82fc83a94de987824aa129066df72878f3179c /lib/puppet/parser/interpreter.rb | |
| parent | 19942633b69f04c6789ef08a04d434024e1bc334 (diff) | |
| download | puppet-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.rb | 125 |
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 |
