Class Puppet::Util::Ldap::Manager
In: lib/puppet/util/ldap/manager.rb
Parent: Object

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

Methods

and   at   base   connect   create   delete   dn   entry2provider   filter   find   generate   generates   ldap_name   manages   maps   modify   named_by   new   puppet_name   search   update   valid?  

Attributes

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

Public Class methods

[Source]

     # File lib/puppet/util/ldap/manager.rb, line 156
156:     def initialize
157:         @rdn = :cn
158:         @generators = []
159:     end

Public Instance methods

A null-op that just returns the config.

[Source]

    # File lib/puppet/util/ldap/manager.rb, line 11
11:     def and
12:         return self
13:     end

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

[Source]

    # File lib/puppet/util/ldap/manager.rb, line 16
16:     def at(location)
17:         @location = location
18:         return self
19:     end

The basic search base.

[Source]

    # File lib/puppet/util/ldap/manager.rb, line 22
22:     def base
23:         [location, Puppet[:ldapbase]].join(",")
24:     end

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

[Source]

    # File lib/puppet/util/ldap/manager.rb, line 46
46:     def connect
47:         raise ArgumentError, "You must pass a block to #connect" unless block_given?
48: 
49:         unless defined?(@connection) and @connection
50:             if Puppet[:ldaptls]
51:                 ssl = :tls
52:             elsif Puppet[:ldapssl]
53:                 ssl = true
54:             else
55:                 ssl = false
56:             end
57:             options = {:ssl => ssl}
58:             if user = Puppet[:ldapuser] and user != ""
59:                 options[:user] = user
60:             end
61:             if password = Puppet[:ldappassword] and password != ""
62:                 options[:password] = password
63:             end
64:             @connection = Puppet::Util::Ldap::Connection.new(Puppet[:ldapserver], Puppet[:ldapport], options)
65:         end
66:         @connection.start
67:         begin
68:             yield @connection.connection
69:         ensure
70:             @connection.close
71:         end
72:         return nil
73:     end

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

[Source]

    # File lib/puppet/util/ldap/manager.rb, line 28
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

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

[Source]

    # File lib/puppet/util/ldap/manager.rb, line 77
77:     def delete(name)
78:         connect { |connection| connection.delete dn(name) }
79:     end

Calculate the dn for a given resource.

[Source]

    # File lib/puppet/util/ldap/manager.rb, line 82
82:     def dn(name)
83:         ["%s=%s" % [rdn, name], base].join(",")
84:     end

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

[Source]

     # File lib/puppet/util/ldap/manager.rb, line 87
 87:     def entry2provider(entry)
 88:         raise ArgumentError, "Could not get dn from ldap entry" unless entry["dn"]
 89: 
 90:         # DN is always a single-entry array.  Strip off the bits before the
 91:         # first comma, then the bits after the remaining equal sign.  This is the
 92:         # name.
 93:         name = entry["dn"].dup.pop.split(",").shift.split("=").pop
 94: 
 95:         result = {:name => name}
 96: 
 97:         @ldap2puppet.each do |ldap, puppet|
 98:             result[puppet] = entry[ldap.to_s] || :absent
 99:         end
100: 
101:         result
102:     end

Create our normal search filter.

[Source]

     # File lib/puppet/util/ldap/manager.rb, line 105
105:     def filter
106:         return "objectclass=%s" % objectclasses[0] if objectclasses.length == 1
107:         return "(&(objectclass=" + objectclasses.join(")(objectclass=") + "))"
108:     end

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

[Source]

     # File lib/puppet/util/ldap/manager.rb, line 112
112:     def find(name)
113:         result = nil
114:         connect do |conn|
115:             begin
116:                 conn.search2(dn(name), 0, "objectclass=*") do |result|
117:                     # Convert to puppet-appropriate attributes
118:                     return entry2provider(result)
119:                 end
120:             rescue => detail
121:                 return nil
122:             end
123:         end
124:     end

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

[Source]

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

Declare a new attribute generator.

[Source]

     # File lib/puppet/util/ldap/manager.rb, line 127
127:     def generates(parameter)
128:         @generators << Puppet::Util::Ldap::Generator.new(parameter)
129:         @generators[-1]
130:     end

Return the ldap name for a puppet attribute.

[Source]

     # File lib/puppet/util/ldap/manager.rb, line 181
181:     def ldap_name(attribute)
182:         @puppet2ldap[attribute].to_s
183:     end

Specify what classes this provider models.

[Source]

     # File lib/puppet/util/ldap/manager.rb, line 162
162:     def manages(*classes)
163:         @objectclasses = classes
164:         return self
165:     end

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.

[Source]

     # File lib/puppet/util/ldap/manager.rb, line 170
170:     def maps(attributes)
171:         # The map with the puppet attributes as the keys
172:         @puppet2ldap = attributes
173: 
174:         # and the ldap attributes as the keys.
175:         @ldap2puppet = attributes.inject({}) { |map, ary| map[ary[1]] = ary[0]; map }
176: 
177:         return self
178:     end

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

[Source]

     # File lib/puppet/util/ldap/manager.rb, line 187
187:     def modify(name, mods)
188:         connect { |connection| connection.modify dn(name), mods }
189:     end

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

[Source]

     # File lib/puppet/util/ldap/manager.rb, line 192
192:     def named_by(attribute)
193:         @rdn = attribute
194:         self
195:     end

Return the puppet name for an ldap attribute.

[Source]

     # File lib/puppet/util/ldap/manager.rb, line 198
198:     def puppet_name(attribute)
199:         @ldap2puppet[attribute]
200:     end

Search for all entries at our base. A potentially expensive search.

[Source]

     # File lib/puppet/util/ldap/manager.rb, line 203
203:     def search(sfilter = nil)
204:         sfilter ||= filter()
205: 
206:         result = []
207:         connect do |conn|
208:             conn.search2(base, 1, sfilter) do |entry|
209:                 result << entry2provider(entry)
210:             end
211:         end
212:         return nil if result.empty?
213:         return result
214:     end

Update the ldap entry with the desired state.

[Source]

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

Is this a complete ldap configuration?

[Source]

     # File lib/puppet/util/ldap/manager.rb, line 266
266:     def valid?
267:         location and objectclasses and ! objectclasses.empty? and puppet2ldap
268:     end

[Validate]