class Puppet::Util::Ldap::Manager

The configuration class for LDAP providers, plus connection handling for actually interacting with ldap.

Attributes

location[R]
objectclasses[R]
puppet2ldap[R]
rdn[R]

Public Class Methods

new() click to toggle source
    # File lib/puppet/util/ldap/manager.rb
160 def initialize
161   @rdn = :cn
162   @generators = []
163 end

Public Instance Methods

and() click to toggle source

A null-op that just returns the config.

   # File lib/puppet/util/ldap/manager.rb
11 def and
12   self
13 end
at(location) click to toggle source

Set the offset from the search base and return the config.

   # File lib/puppet/util/ldap/manager.rb
16 def at(location)
17   @location = location
18   self
19 end
base() click to toggle source

The basic search base.

   # File lib/puppet/util/ldap/manager.rb
22 def base
23   [location, Puppet[:ldapbase]].join(",")
24 end
connect() { |connection| ... } click to toggle source

Open, yield, and close the connection. Cannot be left open, at this point.

   # File lib/puppet/util/ldap/manager.rb
46 def connect
47   #TRANSLATORS '#connect' is a method name and and should not be translated, 'block' refers to a Ruby code block
48   raise ArgumentError, _("You must pass a block to #connect") unless block_given?
49 
50   unless @connection
51     if Puppet[:ldaptls]
52       ssl = :tls
53     elsif Puppet[:ldapssl]
54       ssl = true
55     else
56       ssl = false
57     end
58     options = {:ssl => ssl}
59     user = Puppet[:ldapuser]
60     if user && user != ""
61       options[:user] = user
62     end
63     password = Puppet[:ldappassword]
64     if password && password != ""
65       options[:password] = password
66     end
67     @connection = Puppet::Util::Ldap::Connection.new(Puppet[:ldapserver], Puppet[:ldapport], options)
68   end
69   @connection.start
70   begin
71     yield @connection.connection
72   ensure
73     @connection.close
74   end
75   nil
76 end
create(name, attributes) click to toggle source

Convert the name to a dn, then pass the args along to our connection.

   # File lib/puppet/util/ldap/manager.rb
28 def create(name, attributes)
29   attributes = attributes.dup
30 
31   # Add the objectclasses
32   attributes["objectClass"] = objectclasses.collect { |o| o.to_s }
33   attributes["objectClass"] << "top" unless attributes["objectClass"].include?("top")
34 
35   attributes[rdn.to_s] = [name]
36 
37   # Generate any new values we might need.
38   generate(attributes)
39 
40   # And create our resource.
41   connect { |conn| conn.add dn(name), attributes }
42 end
delete(name) click to toggle source

Convert the name to a dn, then pass the args along to our connection.

   # File lib/puppet/util/ldap/manager.rb
80 def delete(name)
81   connect { |connection| connection.delete dn(name) }
82 end
dn(name) click to toggle source

Calculate the dn for a given resource.

   # File lib/puppet/util/ldap/manager.rb
85 def dn(name)
86   ["#{rdn}=#{name}", base].join(",")
87 end
entry2provider(entry) click to toggle source

Convert an ldap-style entry hash to a provider-style hash.

    # File lib/puppet/util/ldap/manager.rb
 90 def entry2provider(entry)
 91   #TRANSLATOR 'dn' refers to a 'distinguished name' in LDAP (Lightweight Directory Access Protocol) and they should not be translated
 92   raise ArgumentError, _("Could not get dn from ldap entry") unless entry["dn"]
 93 
 94   # DN is always a single-entry array.  Strip off the bits before the
 95   # first comma, then the bits after the remaining equal sign.  This is the
 96   # name.
 97   name = entry["dn"].dup.pop.split(",").shift.split("=").pop
 98 
 99   result = {:name => name}
100 
101   @ldap2puppet.each do |ldap, puppet|
102     result[puppet] = entry[ldap.to_s] || :absent
103   end
104 
105   result
106 end
filter() click to toggle source

Create our normal search filter.

    # File lib/puppet/util/ldap/manager.rb
109 def filter
110   return(objectclasses.length == 1 ? "objectclass=#{objectclasses[0]}" : "(&(objectclass=" + objectclasses.join(")(objectclass=") + "))")
111 end
find(name) click to toggle source

Find the associated entry for a resource. Returns a hash, minus 'dn', or nil if the entry cannot be found.

    # File lib/puppet/util/ldap/manager.rb
115 def find(name)
116   connect do |conn|
117     begin
118       conn.search2(dn(name), 0, "objectclass=*") do |result|
119         # Convert to puppet-appropriate attributes
120         return entry2provider(result)
121       end
122     rescue
123       return nil
124     end
125   end
126 end
generate(values) click to toggle source

Generate any extra values we need to make the ldap entry work.

    # File lib/puppet/util/ldap/manager.rb
135 def generate(values)
136   return unless @generators.length > 0
137 
138   @generators.each do |generator|
139     # Don't override any values that might exist.
140     next if values[generator.name]
141 
142     if generator.source
143       value = values[generator.source]
144       unless value
145         raise ArgumentError, _("%{source} must be defined to generate %{name}") %
146             { source: generator.source, name: generator.name }
147       end
148       result = generator.generate(value)
149     else
150       result = generator.generate
151     end
152 
153     result = [result] unless result.is_a?(Array)
154     result = result.collect { |r| r.to_s }
155 
156     values[generator.name] = result
157   end
158 end
generates(parameter) click to toggle source

Declare a new attribute generator.

    # File lib/puppet/util/ldap/manager.rb
129 def generates(parameter)
130   @generators << Puppet::Util::Ldap::Generator.new(parameter)
131   @generators[-1]
132 end
ldap_name(attribute) click to toggle source

Return the ldap name for a puppet attribute.

    # File lib/puppet/util/ldap/manager.rb
185 def ldap_name(attribute)
186   @puppet2ldap[attribute].to_s
187 end
manages(*classes) click to toggle source

Specify what classes this provider models.

    # File lib/puppet/util/ldap/manager.rb
166 def manages(*classes)
167   @objectclasses = classes
168   self
169 end
maps(attributes) click to toggle source

Specify the attribute map. Assumes the keys are the puppet attributes, and the values are the ldap attributes, and creates a map for each direction.

    # File lib/puppet/util/ldap/manager.rb
174 def maps(attributes)
175   # The map with the puppet attributes as the keys
176   @puppet2ldap = attributes
177 
178   # and the ldap attributes as the keys.
179   @ldap2puppet = attributes.inject({}) { |map, ary| map[ary[1]] = ary[0]; map }
180 
181   self
182 end
modify(name, mods) click to toggle source

Convert the name to a dn, then pass the args along to our connection.

    # File lib/puppet/util/ldap/manager.rb
191 def modify(name, mods)
192   connect { |connection| connection.modify dn(name), mods }
193 end
named_by(attribute) click to toggle source

Specify the rdn that we use to build up our dn.

    # File lib/puppet/util/ldap/manager.rb
196 def named_by(attribute)
197   @rdn = attribute
198   self
199 end
puppet_name(attribute) click to toggle source

Return the puppet name for an ldap attribute.

    # File lib/puppet/util/ldap/manager.rb
202 def puppet_name(attribute)
203   @ldap2puppet[attribute]
204 end
update(name, is, should) click to toggle source

Update the ldap entry with the desired state.

    # File lib/puppet/util/ldap/manager.rb
220 def update(name, is, should)
221   if should[:ensure] == :absent
222     Puppet.info _("Removing %{name} from ldap") % { name: dn(name) }
223     delete(name)
224     return
225   end
226 
227   # We're creating a new entry
228   if is.empty? or is[:ensure] == :absent
229     Puppet.info _("Creating %{name} in ldap") % { name: dn(name) }
230     # Remove any :absent params and :ensure, then convert the names to ldap names.
231     attrs = ldap_convert(should)
232     create(name, attrs)
233     return
234   end
235 
236   # We're modifying an existing entry.  Yuck.
237 
238   mods = []
239   # For each attribute we're deleting that is present, create a
240   # modify instance for deletion.
241   [is.keys, should.keys].flatten.uniq.each do |property|
242     # They're equal, so do nothing.
243     next if is[property] == should[property]
244 
245     attributes = ldap_convert(should)
246 
247     prop_name = ldap_name(property).to_s
248 
249     # We're creating it.
250     if is[property] == :absent or is[property].nil?
251       mods << LDAP::Mod.new(LDAP::LDAP_MOD_ADD, prop_name, attributes[prop_name])
252       next
253     end
254 
255     # We're deleting it
256     if should[property] == :absent or should[property].nil?
257       mods << LDAP::Mod.new(LDAP::LDAP_MOD_DELETE, prop_name, [])
258       next
259     end
260 
261     # We're replacing an existing value
262     mods << LDAP::Mod.new(LDAP::LDAP_MOD_REPLACE, prop_name, attributes[prop_name])
263   end
264 
265   modify(name, mods)
266 end
valid?() click to toggle source

Is this a complete ldap configuration?

    # File lib/puppet/util/ldap/manager.rb
269 def valid?
270   location and objectclasses and ! objectclasses.empty? and puppet2ldap
271 end

Private Instance Methods

ldap_convert(attributes) click to toggle source

Convert a hash of attributes to ldap-like forms. This mostly means getting rid of :ensure and making sure everything's an array of strings.

    # File lib/puppet/util/ldap/manager.rb
277 def ldap_convert(attributes)
278   attributes.reject { |param, value| value == :absent or param == :ensure }.inject({}) do |result, ary|
279     value = (ary[1].is_a?(Array) ? ary[1] : [ary[1]]).collect { |v| v.to_s }
280     result[ldap_name(ary[0])] = value
281     result
282   end
283 end