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, line 155
def initialize
  @rdn = :cn
  @generators = []
end

Public Instance Methods

and() click to toggle source

A null-op that just returns the config.

# File lib/puppet/util/ldap/manager.rb, line 11
def and
  self
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, line 16
def at(location)
  @location = location
  self
end
base() click to toggle source

The basic search base.

# File lib/puppet/util/ldap/manager.rb, line 22
def base
  [location, Puppet[:ldapbase]].join(",")
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, line 46
def connect
  raise ArgumentError, "You must pass a block to #connect" unless block_given?

  unless @connection
    if Puppet[:ldaptls]
      ssl = :tls
    elsif Puppet[:ldapssl]
      ssl = true
    else
      ssl = false
    end
    options = {:ssl => ssl}
    if user = Puppet[:ldapuser] and user != ""
      options[:user] = user
    end
    if password = Puppet[:ldappassword] and password != ""
      options[:password] = password
    end
    @connection = Puppet::Util::Ldap::Connection.new(Puppet[:ldapserver], Puppet[:ldapport], options)
  end
  @connection.start
  begin
    yield @connection.connection
  ensure
    @connection.close
  end
  nil
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, line 28
def create(name, attributes)
  attributes = attributes.dup

  # Add the objectclasses
  attributes["objectClass"] = objectclasses.collect { |o| o.to_s }
  attributes["objectClass"] << "top" unless attributes["objectClass"].include?("top")

  attributes[rdn.to_s] = [name]

  # Generate any new values we might need.
  generate(attributes)

  # And create our resource.
  connect { |conn| conn.add dn(name), attributes }
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, line 77
def delete(name)
  connect { |connection| connection.delete dn(name) }
end
dn(name) click to toggle source

Calculate the dn for a given resource.

# File lib/puppet/util/ldap/manager.rb, line 82
def dn(name)
  ["#{rdn}=#{name}", base].join(",")
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, line 87
def entry2provider(entry)
  raise ArgumentError, "Could not get dn from ldap entry" unless entry["dn"]

  # DN is always a single-entry array.  Strip off the bits before the
  # first comma, then the bits after the remaining equal sign.  This is the
  # name.
  name = entry["dn"].dup.pop.split(",").shift.split("=").pop

  result = {:name => name}

  @ldap2puppet.each do |ldap, puppet|
    result[puppet] = entry[ldap.to_s] || :absent
  end

  result
end
filter() click to toggle source

Create our normal search filter.

# File lib/puppet/util/ldap/manager.rb, line 105
def filter
  return(objectclasses.length == 1 ? "objectclass=#{objectclasses[0]}" : "(&(objectclass=" + objectclasses.join(")(objectclass=") + "))")
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, line 111
def find(name)
  result = nil
  connect do |conn|
    begin
      conn.search2(dn(name), 0, "objectclass=*") do |result|
        # Convert to puppet-appropriate attributes
        return entry2provider(result)
      end
    rescue => detail
      return nil
    end
  end
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, line 132
def generate(values)
  return unless @generators.length > 0

  @generators.each do |generator|
    # Don't override any values that might exist.
    next if values[generator.name]

    if generator.source
      unless value = values[generator.source]
        raise ArgumentError, "#{generator.source} must be defined to generate #{generator.name}"
      end
      result = generator.generate(value)
    else
      result = generator.generate
    end

    result = [result] unless result.is_a?(Array)
    result = result.collect { |r| r.to_s }

    values[generator.name] = result
  end
end
generates(parameter) click to toggle source

Declare a new attribute generator.

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

Return the ldap name for a puppet attribute.

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

Specify what classes this provider models.

# File lib/puppet/util/ldap/manager.rb, line 161
def manages(*classes)
  @objectclasses = classes
  self
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, line 169
def maps(attributes)
  # The map with the puppet attributes as the keys
  @puppet2ldap = attributes

  # and the ldap attributes as the keys.
  @ldap2puppet = attributes.inject({}) { |map, ary| map[ary[1]] = ary[0]; map }

  self
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, line 186
def modify(name, mods)
  connect { |connection| connection.modify dn(name), mods }
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, line 191
def named_by(attribute)
  @rdn = attribute
  self
end
puppet_name(attribute) click to toggle source

Return the puppet name for an ldap attribute.

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

Update the ldap entry with the desired state.

# File lib/puppet/util/ldap/manager.rb, line 215
def update(name, is, should)
  if should[:ensure] == :absent
    Puppet.info "Removing #{dn(name)} from ldap"
    delete(name)
    return
  end

  # We're creating a new entry
  if is.empty? or is[:ensure] == :absent
    Puppet.info "Creating #{dn(name)} in ldap"
    # Remove any :absent params and :ensure, then convert the names to ldap names.
    attrs = ldap_convert(should)
    create(name, attrs)
    return
  end

  # We're modifying an existing entry.  Yuck.

  mods = []
  # For each attribute we're deleting that is present, create a
  # modify instance for deletion.
  [is.keys, should.keys].flatten.uniq.each do |property|
    # They're equal, so do nothing.
    next if is[property] == should[property]

    attributes = ldap_convert(should)

    prop_name = ldap_name(property).to_s

    # We're creating it.
    if is[property] == :absent or is[property].nil?
      mods << LDAP::Mod.new(LDAP::LDAP_MOD_ADD, prop_name, attributes[prop_name])
      next
    end

    # We're deleting it
    if should[property] == :absent or should[property].nil?
      mods << LDAP::Mod.new(LDAP::LDAP_MOD_DELETE, prop_name, [])
      next
    end

    # We're replacing an existing value
    mods << LDAP::Mod.new(LDAP::LDAP_MOD_REPLACE, prop_name, attributes[prop_name])
  end

  modify(name, mods)
end
valid?() click to toggle source

Is this a complete ldap configuration?

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