class Puppet::Util::Ldap::Manager
The configuration class for LDAP providers, plus connection handling for actually interacting with ldap.
Attributes
Public Class Methods
# File lib/puppet/util/ldap/manager.rb 161 def initialize 162 @rdn = :cn 163 @generators = [] 164 end
Public Instance Methods
A null-op that just returns the config.
# File lib/puppet/util/ldap/manager.rb 12 def and 13 self 14 end
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
The basic search base.
# File lib/puppet/util/ldap/manager.rb 23 def base 24 [location, Puppet[:ldapbase]].join(",") 25 end
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
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
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
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
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
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 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 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
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
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
Specify what classes this provider models.
# File lib/puppet/util/ldap/manager.rb 167 def manages(*classes) 168 @objectclasses = classes 169 self 170 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 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
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
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
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
Search for all entries at our base. A potentially expensive search.
# File lib/puppet/util/ldap/manager.rb 208 def search(sfilter = nil) 209 sfilter ||= filter 210 211 result = [] 212 connect do |conn| 213 conn.search2(base, 1, sfilter) do |entry| 214 result << entry2provider(entry) 215 end 216 end 217 return(result.empty? ? nil : result) 218 end
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
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
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