| 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.
| location | [R] | |
| objectclasses | [R] | |
| puppet2ldap | [R] | |
| rdn | [R] |
# File lib/puppet/util/ldap/manager.rb, line 156
156: def initialize
157: @rdn = :cn
158: @generators = []
159: end
A null-op that just returns the config.
# File lib/puppet/util/ldap/manager.rb, line 11
11: def and
12: return self
13: end
Open, yield, and close the connection. Cannot be left open, at this point.
# 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.
# 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 an ldap-style entry hash to a provider-style hash.
# 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
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, 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.
# 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
Return the ldap name for a puppet attribute.
# 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.
# 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.
# 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
Return the puppet name for an ldap attribute.
# 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.
# 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.
# 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