1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
Puppet::Indirector.register_terminus :node, :ldap do
desc "Search in LDAP for node configuration information."
# Look for our node in ldap.
def get(name)
unless ary = ldapsearch(name)
return nil
end
parent, classes, parameters = ary
while parent
parent, tmpclasses, tmpparams = ldapsearch(parent)
classes += tmpclasses if tmpclasses
tmpparams.each do |param, value|
# Specifically test for whether it's set, so false values are handled
# correctly.
parameters[param] = value unless parameters.include?(param)
end
end
node = Puppe::Node.new(name, :classes => classes, :source => "ldap", :parameters => parameters)
if facts = Puppet::Node.facts(name)
node.fact_merge(facts)
end
return node
end
# Find the ldap node, return the class list and parent node specially,
# and everything else in a parameter hash.
def ldapsearch(node)
filter = Puppet[:ldapstring]
classattrs = Puppet[:ldapclassattrs].split("\s*,\s*")
if Puppet[:ldapattrs] == "all"
# A nil value here causes all attributes to be returned.
search_attrs = nil
else
search_attrs = classattrs + Puppet[:ldapattrs].split("\s*,\s*")
end
pattr = nil
if pattr = Puppet[:ldapparentattr]
if pattr == ""
pattr = nil
else
search_attrs << pattr unless search_attrs.nil?
end
end
if filter =~ /%s/
filter = filter.gsub(/%s/, node)
end
parent = nil
classes = []
parameters = nil
found = false
count = 0
begin
# We're always doing a sub here; oh well.
ldap.search(Puppet[:ldapbase], 2, filter, search_attrs) do |entry|
found = true
if pattr
if values = entry.vals(pattr)
if values.length > 1
raise Puppet::Error,
"Node %s has more than one parent: %s" %
[node, values.inspect]
end
unless values.empty?
parent = values.shift
end
end
end
classattrs.each { |attr|
if values = entry.vals(attr)
values.each do |v| classes << v end
end
}
parameters = entry.to_hash.inject({}) do |hash, ary|
if ary[1].length == 1
hash[ary[0]] = ary[1].shift
else
hash[ary[0]] = ary[1]
end
hash
end
end
rescue => detail
if count == 0
# Try reconnecting to ldap
@ldap = nil
retry
else
raise Puppet::Error, "LDAP Search failed: %s" % detail
end
end
classes.flatten!
if classes.empty?
classes = nil
end
if parent or classes or parameters
return parent, classes, parameters
else
return nil
end
end
private
# Create an ldap connection.
def ldap
unless defined? @ldap and @ldap
unless Puppet.features.ldap?
raise Puppet::Error, "Could not set up LDAP Connection: Missing ruby/ldap libraries"
end
begin
if Puppet[:ldapssl]
@ldap = LDAP::SSLConn.new(Puppet[:ldapserver], Puppet[:ldapport])
elsif Puppet[:ldaptls]
@ldap = LDAP::SSLConn.new(
Puppet[:ldapserver], Puppet[:ldapport], true
)
else
@ldap = LDAP::Conn.new(Puppet[:ldapserver], Puppet[:ldapport])
end
@ldap.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
@ldap.set_option(LDAP::LDAP_OPT_REFERRALS, LDAP::LDAP_OPT_ON)
@ldap.simple_bind(Puppet[:ldapuser], Puppet[:ldappassword])
rescue => detail
raise Puppet::Error, "Could not connect to LDAP: %s" % detail
end
end
return @ldap
end
end
|