Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,4 @@ The key being looked up is actually processsed just like rfc4515 so you can use
- Spencer Krum http://github.com/nibalizer
- Sage Imel http://github.com/nightfly
- Fabio Rauber http://github.com/fabiorauber
- Arnaud Gomes http://forge.ircam.fr/p/hiera-ldap-backend/
140 changes: 112 additions & 28 deletions lib/hiera/backend/ldap_backend.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require 'rubygems'
require 'net/ldap'
require 'json'

# Monkey patch Net::LDAP::Connection to ensure SSL certs aren't verified
class Net::LDAP::Connection
Expand All @@ -17,6 +18,17 @@ def self.wrap_with_ssl(io)
end
end

class String
def valid_json?
begin
JSON.parse(self)
return true
rescue JSON::ParserError
return false
end
end
end

class Hiera
module Backend
class Ldap_backend
Expand All @@ -25,51 +37,123 @@ def initialize
@base = conf[:base]

Hiera.debug("Hiera LDAP backend starting")

@searchattr = get_config_value(:attribute, "puppetVar")
@connection = Net::LDAP.new(
:host => conf[:host],
:port => conf[:port],
:port => get_config_value(:port, "389"),
:auth => conf[:auth],
:base => conf[:base],
:encryption => conf[:encryption])
end

def lookup(key, scope, order_override, resolution_type)
answer = nil
# Helper for parsing config. Does not Hiera provide one?
def get_config_value(label, default)
if Config.include?(:ldap) && Config[:ldap].include?(label)
Config[:ldap][label]
else
default
end
end

Hiera.debug("Looking up #{key} in LDAP backend")

Backend.datasources(scope, order_override) do |source|
Hiera.debug("Looking for data source #{source}")
conf = Config[:ldap]
base = conf[:base]
Hiera.debug("Searching on base: #{base}")
def lookup(key, scope, order_override, resolution_type)
conf = Config[:ldap]

# Testing if the key is an arbitrary LDAP Search key
if key.split('')[0] == '(' and key.split('')[key.length-1] == ')'
answer = []
filter = Net::LDAP::Filter.from_rfc4515(key)
treebase = conf[:base]
Hiera.debug("Searching #{key} in LDAP backend, base #{treebase}.")
searchresult = @connection.search(:filter => filter)

begin
filter = Net::LDAP::Filter.from_rfc4515(key)
treebase = conf[:base]
searchresult = @connection.search(:filter => filter)

for i in 0..searchresult.length-1 do
answer[i] = {}
searchresult[i].each do |attribute, values|
Hiera.debug( " #{attribute}:")
answer[i][attribute.to_s] = values
values.each do |value|
Hiera.debug( " ---->#{value}:")
end
for i in 0..searchresult.length-1 do
answer[i] = {}
searchresult[i].each do |attribute, values|
Hiera.debug( " #{attribute}:")
answer[i][attribute.to_s] = values
values.each do |value|
Hiera.debug( " ---->#{value}:")
end
end
rescue Exception => e
Hiera.debug("Exception: #{e}")
end
Hiera.debug(answer)
return answer unless answer == []

# "Key" is an ordinary puppet variable
else
answer = []
Hiera.debug("Looking up #{key} in LDAP backend")

Backend.datasources(scope, order_override) do |source|
Hiera.debug("Looking for data source #{source}")
base = conf[:base]
Hiera.debug("Searching on base: #{base}")
begin
filterstr = "(&(objectClass=puppetClient)(cn=#{source}))"
filter = Net::LDAP::Filter.from_rfc4515(filterstr)
treebase = conf[:base]
searchresult = @connection.search(:filter => filter)

end

return answer unless answer == []
searchresult.each do |entry|
if entry[@searchattr] != []
Hiera.debug("Entry #{entry['cn']} has key #{@searchattr}: '#{entry[@searchattr]}'")
# Now we do have hiera data, let's see if the key we're looking for is here.
entry[@searchattr].each do |line|
k, v = line.split "=", 2
if k == key
# Verify if boolean
if v == "true"
v = true
end
if v == "false"
v = false
end

# Parse JSON
if v.valid_json?
v = JSON.parse(v)
end

# Construct response
if answer
if answer.is_a? String
answer = [answer, v]
else
answer.push v
end
else
answer = v
end
end #end if k == key
end #end entry[@searchattr].each
end #end if entry[@searchattr] != []

if answer == []
k = key.rpartition("::").last
Hiera.debug("Entry #{key} not found in #{@searchattr} key. Looking up for key #{k}.")
entry[k].each do |line|
# Construct response
if answer
if answer.is_a? String
answer = [answer, line]
else
answer.push line
end
else
answer = line
end
Hiera.debug("Found LDAP key #{k} with value: #{line}.")
end
end

end #end searchresult.each
end #end datasources begin
end #end datasources
return answer unless answer == []
end #end else
rescue Exception => e
Hiera.debug("Exception: #{e}")
end
end
end
Expand Down