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
161 def initialize
162   @rdn = :cn
163   @generators = []
164 end

Public Instance Methods

and() click to toggle source

A null-op that just returns the config.

   # File lib/puppet/util/ldap/manager.rb
12 def and
13   self
14 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
17 def at(location)
18   @location = location
19   self
20 end
base() click to toggle source

The basic search base.

   # File lib/puppet/util/ldap/manager.rb
23 def base
24   [location, Puppet[:ldapbase]].join(",")
25 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
47 def connect
48   #TRANSLATORS '#connect' is a method name and and should not be translated, 'block' refers to a Ruby code block
49   raise ArgumentError, _("You must pass a block to #connect") unless block_given?
50 
51   unless @connection
52     if Puppet[:ldaptls]
53       ssl = :tls
54     elsif Puppet[:ldapssl]
55       ssl = true
56     else
57       ssl = false
58     end
59     options = {:ssl => ssl}
60     user = Puppet[:ldapuser]
61     if user && user != ""
62       options[:user] = user
63     end
64     password = Puppet[:ldappassword]
65     if password && password != ""
66       options[:password] = password
67     end
68     @connection = Puppet::Util::Ldap::Connection.new(Puppet[:ldapserver], Puppet[:ldapport], options)
69   end
70   @connection.start
71   begin
72     yield @connection.connection
73   ensure
74     @connection.close
75   end
76   nil
77 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
29 def create(name, attributes)
30   attributes = attributes.dup
31 
32   # Add the objectclasses
33   attributes["objectClass"] = objectclasses.collect { |o| o.to_s }
34   attributes["objectClass"] << "top" unless attributes["objectClass"].include?("top")
35 
36   attributes[rdn.to_s] = [name]
37 
38   # Generate any new values we might need.
39   generate(attributes)
40 
41   # And create our resource.
42   connect { |conn| conn.add dn(name), attributes }
43 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
81 def delete(name)
82   connect { |connection| connection.delete dn(name) }
83 end
dn(name) click to toggle source

Calculate the dn for a given resource.

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

Create our normal search filter.

    # File lib/puppet/util/ldap/manager.rb
110 def filter
111   return(objectclasses.length == 1 ? "objectclass=#{objectclasses[0]}" : "(&(objectclass=" + objectclasses.join(")(objectclass=") + "))")
112 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
116 def find(name)
117   connect do |conn|
118     begin
119       conn.search2(dn(name), 0, "objectclass=*") do |result|
120         # Convert to puppet-appropriate attributes
121         return entry2provider(result)
122       end
123     rescue
124       return nil
125     end
126   end
127 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
136 def generate(values)
137   return unless @generators.length > 0
138 
139   @generators.each do |generator|
140     # Don't override any values that might exist.
141     next if values[generator.name]
142 
143     if generator.source
144       value = values[generator.source]
145       unless value
146         raise ArgumentError, _("%{source} must be defined to generate %{name}") %
147             { source: generator.source, name: generator.name }
148       end
149       result = generator.generate(value)
150     else
151       result = generator.generate
152     end
153 
154     result = [result] unless result.is_a?(Array)
155     result = result.collect { |r| r.to_s }
156 
157     values[generator.name] = result
158   end
159 end
generates(parameter) click to toggle source

Declare a new attribute generator.

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

Return the ldap name for a puppet attribute.

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

Specify what classes this provider models.

    # File lib/puppet/util/ldap/manager.rb
167 def manages(*classes)
168   @objectclasses = classes
169   self
170 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
175 def maps(attributes)
176   # The map with the puppet attributes as the keys
177   @puppet2ldap = attributes
178 
179   # and the ldap attributes as the keys.
180   @ldap2puppet = attributes.inject({}) { |map, ary| map[ary[1]] = ary[0]; map }
181 
182   self
183 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
192 def modify(name, mods)
193   connect { |connection| connection.modify dn(name), mods }
194 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
197 def named_by(attribute)
198   @rdn = attribute
199   self
200 end
puppet_name(attribute) click to toggle source

Return the puppet name for an ldap attribute.

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

Update the ldap entry with the desired state.

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

Is this a complete ldap configuration?

    # File lib/puppet/util/ldap/manager.rb
270 def valid?
271   location and objectclasses and ! objectclasses.empty? and puppet2ldap
272 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
278 def ldap_convert(attributes)
279   attributes.reject { |param, value| value == :absent or param == :ensure }.inject({}) do |result, ary|
280     value = (ary[1].is_a?(Array) ? ary[1] : [ary[1]]).collect { |v| v.to_s }
281     result[ldap_name(ary[0])] = value
282     result
283   end
284 end