puppet 0.13.1 → 0.13.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puppet might be problematic. Click here for more details.
- data/CHANGELOG +4 -0
- data/Rakefile +2 -2
- data/bin/puppet +29 -0
- data/bin/puppetd +35 -1
- data/conf/redhat/puppet.spec +1 -1
- data/lib/puppet.rb +1 -1
- data/lib/puppet/client/master.rb +34 -3
- data/lib/puppet/filetype.rb +6 -2
- data/lib/puppet/networkclient.rb +4 -1
- data/lib/puppet/parameter.rb +35 -38
- data/lib/puppet/parser/ast/node.rb +1 -0
- data/lib/puppet/parser/interpreter.rb +129 -2
- data/lib/puppet/parser/scope.rb +44 -6
- data/lib/puppet/type.rb +47 -37
- data/lib/puppet/type/cron.rb +25 -10
- data/lib/puppet/type/exec.rb +165 -71
- data/lib/puppet/type/nameservice.rb +2 -17
- data/lib/puppet/type/package.rb +31 -7
- data/lib/puppet/type/package/sun.rb +11 -6
- data/lib/puppet/type/parsedtype.rb +94 -60
- data/lib/puppet/type/parsedtype/host.rb +5 -12
- data/lib/puppet/type/parsedtype/port.rb +53 -32
- data/lib/puppet/type/parsedtype/sshkey.rb +8 -4
- data/lib/puppet/type/pfile.rb +6 -4
- data/lib/puppet/type/pfile/ensure.rb +1 -6
- data/lib/puppet/type/state.rb +34 -74
- data/lib/puppet/type/symlink.rb +30 -19
- data/lib/puppet/type/user.rb +63 -11
- data/lib/puppet/util.rb +54 -60
- data/test/client/master.rb +72 -0
- data/test/language/interpreter.rb +94 -0
- data/test/other/log.rb +8 -1
- data/test/puppet/utiltest.rb +101 -1
- data/test/test +12 -5
- data/test/types/cron.rb +21 -1
- data/test/types/exec.rb +46 -2
- data/test/types/group.rb +15 -3
- data/test/types/host.rb +43 -4
- data/test/types/port.rb +67 -6
- data/test/types/sshkey.rb +45 -4
- data/test/types/symlink.rb +4 -4
- data/test/types/type.rb +41 -3
- data/test/types/user.rb +23 -2
- metadata +3 -2
data/CHANGELOG
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
0.13.2
|
2
|
+
Changed package[answerfile] to package[adminfile], and added package[responsefile]
|
3
|
+
Fixed a bunch of internal functions to behave more consistently and usefully
|
4
|
+
|
1
5
|
0.13.1
|
2
6
|
Fixed RPM spec files to create puppet user and group (lutter)
|
3
7
|
Fixed crontab reading and writing (luke)
|
data/Rakefile
CHANGED
@@ -47,7 +47,7 @@ DOWNDIR = "/export/docroots/reductivelabs.com/htdocs/downloads"
|
|
47
47
|
if ENV['HOSTS']
|
48
48
|
TESTHOSTS = ENV['HOSTS'].split(/\s+/)
|
49
49
|
else
|
50
|
-
TESTHOSTS = %w{fedora1 rh3a
|
50
|
+
TESTHOSTS = %w{fedora1 rh3a culain openbsd1 centos1}
|
51
51
|
end
|
52
52
|
#TESTHOSTS = %w{sol10b}
|
53
53
|
|
@@ -386,8 +386,8 @@ task :hosttest do
|
|
386
386
|
if $? != 0
|
387
387
|
file = File.join("/tmp", "%stest.out" % host)
|
388
388
|
File.open(file, "w") { |of| of.print out }
|
389
|
-
puts "%s failed; output is in %s" % [host, file]
|
390
389
|
puts out
|
390
|
+
puts "%s failed; output is in %s" % [host, file]
|
391
391
|
end
|
392
392
|
#sh %{ssh #{host} 'cd #{cwd}/test; sudo ./test' 2>&1}
|
393
393
|
}
|
data/bin/puppet
CHANGED
@@ -27,9 +27,18 @@
|
|
27
27
|
# debug::
|
28
28
|
# Enable full debugging.
|
29
29
|
#
|
30
|
+
# extclassfile::
|
31
|
+
# Specify the location of the class file to load. Only affects the
|
32
|
+
# +--loadclasses+ option.
|
33
|
+
#
|
30
34
|
# help::
|
31
35
|
# Print this help message
|
32
36
|
#
|
37
|
+
# loadclasses::
|
38
|
+
# Load any stored classes. +puppetd+ caches configured classes (usually at
|
39
|
+
# /etc/puppet/classes.txt), and setting this option causes all of those classes
|
40
|
+
# to be set in your +puppet+ manifest.
|
41
|
+
#
|
33
42
|
# logfile::
|
34
43
|
# Where to send messages. Choose between syslog, the console, and a log file.
|
35
44
|
# Defaults to sending messages to the console.
|
@@ -65,8 +74,10 @@ end
|
|
65
74
|
|
66
75
|
options = [
|
67
76
|
[ "--debug", "-d", GetoptLong::NO_ARGUMENT ],
|
77
|
+
[ "--extclassfile", "-e", GetoptLong::REQUIRED_ARGUMENT ],
|
68
78
|
[ "--help", "-h", GetoptLong::NO_ARGUMENT ],
|
69
79
|
[ "--logdest", "-l", GetoptLong::REQUIRED_ARGUMENT ],
|
80
|
+
[ "--loadclasses", GetoptLong::NO_ARGUMENT ],
|
70
81
|
[ "--verbose", "-v", GetoptLong::NO_ARGUMENT ],
|
71
82
|
[ "--use-nodes", GetoptLong::NO_ARGUMENT ],
|
72
83
|
[ "--version", "-V", GetoptLong::NO_ARGUMENT ]
|
@@ -82,6 +93,8 @@ verbose = false
|
|
82
93
|
noop = false
|
83
94
|
logfile = false
|
84
95
|
parseonly = false
|
96
|
+
loadclasses = false
|
97
|
+
classfile = nil
|
85
98
|
|
86
99
|
master = {
|
87
100
|
:Local => true
|
@@ -108,6 +121,10 @@ begin
|
|
108
121
|
verbose = true
|
109
122
|
when "--debug"
|
110
123
|
debug = true
|
124
|
+
when "--extclassfile"
|
125
|
+
classfile = arg
|
126
|
+
when "--loadclasses"
|
127
|
+
loadclasses = true
|
111
128
|
when "--logdest"
|
112
129
|
begin
|
113
130
|
Puppet::Log.newdestination(arg)
|
@@ -142,6 +159,18 @@ Puppet.genmanifest
|
|
142
159
|
|
143
160
|
master[:File] = ARGV.shift
|
144
161
|
|
162
|
+
if loadclasses
|
163
|
+
file = classfile || Puppet[:classfile]
|
164
|
+
if FileTest.exists?(file)
|
165
|
+
unless FileTest.readable?(file)
|
166
|
+
$stderr.puts "%s is not readable" % file
|
167
|
+
exit(63)
|
168
|
+
end
|
169
|
+
|
170
|
+
master[:Classes] = File.read(file).split(/[\s\n]/)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
145
174
|
begin
|
146
175
|
server = Puppet::Server::Master.new(master)
|
147
176
|
client = Puppet::Client::MasterClient.new(
|
data/bin/puppetd
CHANGED
@@ -37,9 +37,24 @@
|
|
37
37
|
# Send all produced logs to the central puppetmasterd system. This currently
|
38
38
|
# results in a significant slowdown, so it is not recommended.
|
39
39
|
#
|
40
|
+
# disable::
|
41
|
+
# Disable working on the local system. This puts a lock file in place,
|
42
|
+
# causing +puppetd+ not to work on the system until the lock file is removed.
|
43
|
+
# This is useful if you are testing a configuration and do not want the central
|
44
|
+
# configuration to override the local state until everything is tested and
|
45
|
+
# committed.
|
46
|
+
#
|
47
|
+
# +puppetd+ exits after executing this.
|
48
|
+
#
|
40
49
|
# debug::
|
41
50
|
# Enable full debugging.
|
42
51
|
#
|
52
|
+
# enable::
|
53
|
+
# Enable working on the local system. This removes any lock file, causing
|
54
|
+
# +puppetd+ to start managing the local system again.
|
55
|
+
#
|
56
|
+
# +puppetd+ exits after executing this.
|
57
|
+
#
|
43
58
|
# fqdn::
|
44
59
|
# Set the fully-qualified domain name of the client. This is only used for
|
45
60
|
# certificate purposes, but can be used to override the discovered hostname.
|
@@ -95,7 +110,9 @@ end
|
|
95
110
|
|
96
111
|
options = [
|
97
112
|
[ "--centrallogging", GetoptLong::NO_ARGUMENT ],
|
113
|
+
[ "--disable", GetoptLong::NO_ARGUMENT ],
|
98
114
|
[ "--debug", "-d", GetoptLong::NO_ARGUMENT ],
|
115
|
+
[ "--enable", GetoptLong::NO_ARGUMENT ],
|
99
116
|
[ "--fqdn", "-f", GetoptLong::REQUIRED_ARGUMENT ],
|
100
117
|
[ "--help", "-h", GetoptLong::NO_ARGUMENT ],
|
101
118
|
[ "--logdest", "-l", GetoptLong::REQUIRED_ARGUMENT ],
|
@@ -122,11 +139,18 @@ centrallogs = false
|
|
122
139
|
|
123
140
|
setdest = false
|
124
141
|
|
142
|
+
enable = false
|
143
|
+
disable = false
|
144
|
+
|
125
145
|
begin
|
126
146
|
result.each { |opt,arg|
|
127
147
|
case opt
|
128
148
|
# First check to see if the argument is a valid configuration parameter;
|
129
149
|
# if so, set it.
|
150
|
+
when "--disable"
|
151
|
+
disable = true
|
152
|
+
when "--enable"
|
153
|
+
enable = true
|
130
154
|
when "--centrallogging"
|
131
155
|
centrallogs = true
|
132
156
|
when "--help"
|
@@ -209,6 +233,16 @@ end
|
|
209
233
|
Puppet.notice "Starting Puppet client version %s" % [Puppet.version]
|
210
234
|
client = Puppet::Client::MasterClient.new(args)
|
211
235
|
|
236
|
+
if enable
|
237
|
+
client.enable
|
238
|
+
elsif disable
|
239
|
+
client.disable
|
240
|
+
end
|
241
|
+
|
242
|
+
if enable or disable
|
243
|
+
exit(0)
|
244
|
+
end
|
245
|
+
|
212
246
|
unless client.readcert
|
213
247
|
if waitforcert
|
214
248
|
begin
|
@@ -264,4 +298,4 @@ else
|
|
264
298
|
Puppet.start
|
265
299
|
end
|
266
300
|
|
267
|
-
# $Id: puppetd
|
301
|
+
# $Id: puppetd 908 2006-02-14 00:14:56Z luke $
|
data/conf/redhat/puppet.spec
CHANGED
data/lib/puppet.rb
CHANGED
data/lib/puppet/client/master.rb
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# The client for interacting with the puppetmaster config server.
|
2
2
|
class Puppet::Client::MasterClient < Puppet::Client
|
3
|
+
Puppet.setdefaults("puppetd",
|
4
|
+
[:puppetdlockfile, "$statedir/puppetdlock",
|
5
|
+
"A lock file to temporarily stop puppetd from doing anything."]
|
6
|
+
)
|
7
|
+
|
3
8
|
@drivername = :Master
|
4
9
|
|
5
10
|
def self.facts
|
@@ -79,6 +84,19 @@ class Puppet::Client::MasterClient < Puppet::Client
|
|
79
84
|
@cachefile
|
80
85
|
end
|
81
86
|
|
87
|
+
# Disable running the configuration.
|
88
|
+
def disable
|
89
|
+
Puppet.notice "Disabling puppetd"
|
90
|
+
unless FileTest.exists? File.dirname(Puppet[:puppetdlockfile])
|
91
|
+
Puppet.recmkdir(File.dirname(Puppet[:puppetdlockfile]))
|
92
|
+
end
|
93
|
+
begin
|
94
|
+
File.open(Puppet[:puppetdlockfile], "w") { |f| f.puts ""; f.flush }
|
95
|
+
rescue => detail
|
96
|
+
raise Puppet::Error, "Could not lock puppetd: %s" % detail
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
82
100
|
# Initialize and load storage
|
83
101
|
def dostorage
|
84
102
|
begin
|
@@ -96,6 +114,14 @@ class Puppet::Client::MasterClient < Puppet::Client
|
|
96
114
|
end
|
97
115
|
end
|
98
116
|
|
117
|
+
# Enable running again.
|
118
|
+
def enable
|
119
|
+
Puppet.notice "Enabling puppetd"
|
120
|
+
if FileTest.exists? Puppet[:puppetdlockfile]
|
121
|
+
File.unlink(Puppet[:puppetdlockfile])
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
99
125
|
# Check whether our configuration is up to date
|
100
126
|
def fresh?
|
101
127
|
unless defined? @configstamp
|
@@ -227,8 +253,13 @@ class Puppet::Client::MasterClient < Puppet::Client
|
|
227
253
|
|
228
254
|
# The code that actually runs the configuration.
|
229
255
|
def run
|
230
|
-
|
231
|
-
|
256
|
+
if FileTest.exists? Puppet[:puppetdlockfile]
|
257
|
+
Puppet.notice "%s exists; skipping configuration run" %
|
258
|
+
Puppet[:puppetdlockfile]
|
259
|
+
else
|
260
|
+
self.getconfig
|
261
|
+
self.apply
|
262
|
+
end
|
232
263
|
end
|
233
264
|
|
234
265
|
def setclasses(ary)
|
@@ -243,4 +274,4 @@ class Puppet::Client::MasterClient < Puppet::Client
|
|
243
274
|
end
|
244
275
|
end
|
245
276
|
|
246
|
-
# $Id: master.rb
|
277
|
+
# $Id: master.rb 908 2006-02-14 00:14:56Z luke $
|
data/lib/puppet/filetype.rb
CHANGED
@@ -40,7 +40,11 @@ module Puppet
|
|
40
40
|
begin
|
41
41
|
val = real_read()
|
42
42
|
@loaded = Time.now
|
43
|
-
|
43
|
+
if val
|
44
|
+
return val.gsub(/# HEADER.*\n/,'')
|
45
|
+
else
|
46
|
+
return ""
|
47
|
+
end
|
44
48
|
rescue Puppet::Error => detail
|
45
49
|
raise
|
46
50
|
rescue => detail
|
@@ -204,4 +208,4 @@ module Puppet
|
|
204
208
|
end
|
205
209
|
end
|
206
210
|
|
207
|
-
# $Id: filetype.rb
|
211
|
+
# $Id: filetype.rb 910 2006-02-15 07:20:36Z luke $
|
data/lib/puppet/networkclient.rb
CHANGED
@@ -68,6 +68,9 @@ module Puppet
|
|
68
68
|
Puppet.err "Could not call %s.%s: %s" %
|
69
69
|
[namespace, method, detail.inspect]
|
70
70
|
#raise NetworkClientError.new(detail.to_s)
|
71
|
+
if Puppet[:debug]
|
72
|
+
puts detail.backtrace
|
73
|
+
end
|
71
74
|
raise
|
72
75
|
end
|
73
76
|
}
|
@@ -142,4 +145,4 @@ module Puppet
|
|
142
145
|
end
|
143
146
|
end
|
144
147
|
|
145
|
-
# $Id: networkclient.rb
|
148
|
+
# $Id: networkclient.rb 914 2006-02-15 21:04:14Z luke $
|
data/lib/puppet/parameter.rb
CHANGED
@@ -11,14 +11,18 @@ module Puppet
|
|
11
11
|
if block
|
12
12
|
define_method(:default, &block)
|
13
13
|
else
|
14
|
+
if value.nil?
|
15
|
+
raise Puppet::DevError,
|
16
|
+
"Either a default value or block must be provided"
|
17
|
+
end
|
14
18
|
define_method(:default) do value end
|
15
19
|
end
|
16
20
|
end
|
17
21
|
|
18
22
|
def nodefault
|
19
|
-
|
20
|
-
|
21
|
-
|
23
|
+
if public_method_defined? :default
|
24
|
+
undef_method :default
|
25
|
+
end
|
22
26
|
end
|
23
27
|
|
24
28
|
# Store documentation for this parameter.
|
@@ -42,6 +46,9 @@ module Puppet
|
|
42
46
|
Puppet.debug "Reraising %s" % detail
|
43
47
|
raise
|
44
48
|
rescue => detail
|
49
|
+
if Puppet[:debug]
|
50
|
+
puts detail.backtrace
|
51
|
+
end
|
45
52
|
raise Puppet::DevError, "Munging failed for class %s: %s" %
|
46
53
|
[self.name, detail]
|
47
54
|
end
|
@@ -101,6 +108,9 @@ module Puppet
|
|
101
108
|
rescue ArgumentError, Puppet::Error, TypeError
|
102
109
|
raise
|
103
110
|
rescue => detail
|
111
|
+
if Puppet[:debug]
|
112
|
+
puts detail.backtrace
|
113
|
+
end
|
104
114
|
raise Puppet::DevError,
|
105
115
|
"Validate method failed for class %s: %s" %
|
106
116
|
[self.name, detail]
|
@@ -142,7 +152,13 @@ module Puppet
|
|
142
152
|
@aliasvalues ||= {}
|
143
153
|
|
144
154
|
#[@aliasvalues.keys, @parametervalues.keys].flatten
|
145
|
-
@parametervalues.
|
155
|
+
if @parametervalues.is_a? Array
|
156
|
+
return @parametervalues.dup
|
157
|
+
elsif @parametervalues.is_a? Hash
|
158
|
+
return @parametervalues.keys
|
159
|
+
else
|
160
|
+
return []
|
161
|
+
end
|
146
162
|
end
|
147
163
|
end
|
148
164
|
|
@@ -159,36 +175,6 @@ module Puppet
|
|
159
175
|
|
160
176
|
attr_accessor :parent
|
161
177
|
|
162
|
-
# This doesn't work, because the instance_eval doesn't bind the inner block
|
163
|
-
# only the outer one.
|
164
|
-
# def munge(value)
|
165
|
-
# if munger = self.class.munger
|
166
|
-
# return @parent.instance_eval {
|
167
|
-
# munger.call(value)
|
168
|
-
# }
|
169
|
-
# else
|
170
|
-
# return value
|
171
|
-
# end
|
172
|
-
# end
|
173
|
-
#
|
174
|
-
# def validate(value)
|
175
|
-
# if validater = self.class.validater
|
176
|
-
# return @parent.instance_eval {
|
177
|
-
# validater.call(value)
|
178
|
-
# }
|
179
|
-
# end
|
180
|
-
# end
|
181
|
-
|
182
|
-
#def default
|
183
|
-
# default = self.class.default
|
184
|
-
# if default.is_a?(Proc)
|
185
|
-
# val = self.instance_eval(&default)
|
186
|
-
# return val
|
187
|
-
# else
|
188
|
-
# return default
|
189
|
-
# end
|
190
|
-
#end
|
191
|
-
|
192
178
|
def devfail(msg)
|
193
179
|
self.fail(Puppet::DevError, msg)
|
194
180
|
end
|
@@ -273,16 +259,17 @@ module Puppet
|
|
273
259
|
|
274
260
|
# Verify that the passed value is valid.
|
275
261
|
validate do |value|
|
276
|
-
|
262
|
+
values = self.class.values
|
263
|
+
if values.empty?
|
277
264
|
# This parameter isn't using defined values to do its work.
|
278
265
|
return
|
279
266
|
end
|
280
267
|
unless value.is_a?(Symbol)
|
281
268
|
value = value.to_s.intern
|
282
269
|
end
|
283
|
-
unless
|
270
|
+
unless values.include?(value) or self.class.alias(value)
|
284
271
|
self.fail "Invalid '%s' value '%s'. Valid values are '%s'" %
|
285
|
-
[self.class.name, value,
|
272
|
+
[self.class.name, value, values.join(", ")]
|
286
273
|
end
|
287
274
|
end
|
288
275
|
|
@@ -290,7 +277,17 @@ module Puppet
|
|
290
277
|
# it possible to call for states, too.
|
291
278
|
def value
|
292
279
|
if self.is_a?(Puppet::State)
|
293
|
-
return
|
280
|
+
# We should return the 'is' value if there's not 'should' value.
|
281
|
+
# This might be bad, though, because the 'should' method
|
282
|
+
# knows whether to return an array or not and that info is
|
283
|
+
# not exposed, and the 'is' value could be a symbol. I can't
|
284
|
+
# seem to create a test in which this is a problem, but that doesn't
|
285
|
+
# mean it's not one.
|
286
|
+
if self.should
|
287
|
+
return self.should
|
288
|
+
else
|
289
|
+
return self.is
|
290
|
+
end
|
294
291
|
else
|
295
292
|
if defined? @value
|
296
293
|
return @value
|
@@ -48,6 +48,7 @@ class Puppet::Parser::AST
|
|
48
48
|
# Evaluate our parent class.
|
49
49
|
def evalparent(scope)
|
50
50
|
if @parentclass
|
51
|
+
Puppet.warning "evaluating parent %s" % @parentclass
|
51
52
|
# This is pretty messed up. I don't know if this will
|
52
53
|
# work in the long term, but we need to evaluate the node
|
53
54
|
# in our own scope, even though our parent node has
|
@@ -10,6 +10,32 @@ require 'puppet/parser/scope'
|
|
10
10
|
module Puppet
|
11
11
|
module Parser
|
12
12
|
class Interpreter
|
13
|
+
Puppet.setdefaults("ldap",
|
14
|
+
[:ldapnodes, false,
|
15
|
+
"Whether to search for node configurations in LDAP."],
|
16
|
+
[:ldapserver, "ldap",
|
17
|
+
"The LDAP server. Only used if ``ldapnodes`` is enabled."],
|
18
|
+
[:ldapport, 389,
|
19
|
+
"The LDAP port. Only used if ``ldapnodes`` is enabled."],
|
20
|
+
[:ldapstring, "(&(objectclass=puppetClient)(cn=%s))",
|
21
|
+
"The search string used to find an LDAP node."],
|
22
|
+
[:ldapattrs, "puppetclass",
|
23
|
+
"The LDAP attributes to use to define Puppet classes. Values
|
24
|
+
should be comma-separated."],
|
25
|
+
[:ldapparentattr, "parentnode",
|
26
|
+
"The attribute to use to define the parent node."],
|
27
|
+
[:ldapuser, "",
|
28
|
+
"The user to use to connect to LDAP. Must be specified as a
|
29
|
+
full DN."],
|
30
|
+
[:ldappassword, "",
|
31
|
+
"The password to use to connect to LDAP."],
|
32
|
+
[:ldapbase, "",
|
33
|
+
"The search base for LDAP searches. It's impossible to provide
|
34
|
+
a meaningful default here, although the LDAP libraries might
|
35
|
+
have one already set. Generally, it should be the 'ou=Hosts'
|
36
|
+
branch under your main directory."]
|
37
|
+
)
|
38
|
+
|
13
39
|
attr_accessor :ast, :filetimeout
|
14
40
|
# just shorten the constant path a bit, using what amounts to an alias
|
15
41
|
AST = Puppet::Parser::AST
|
@@ -31,6 +57,20 @@ module Puppet
|
|
31
57
|
@usenodes = true
|
32
58
|
end
|
33
59
|
|
60
|
+
@nodesources = hash[:NodeSources] || [:file]
|
61
|
+
|
62
|
+
@nodesources.each { |source|
|
63
|
+
method = "setup_%s" % source.to_s
|
64
|
+
if respond_to? method
|
65
|
+
begin
|
66
|
+
self.send(method)
|
67
|
+
rescue => detail
|
68
|
+
raise Puppet::Error,
|
69
|
+
"Could not set up node source %s" % source
|
70
|
+
end
|
71
|
+
end
|
72
|
+
}
|
73
|
+
|
34
74
|
# Set it to either the value or nil. This is currently only used
|
35
75
|
# by the cfengine module.
|
36
76
|
@classes = hash[:Classes] || []
|
@@ -41,6 +81,77 @@ module Puppet
|
|
41
81
|
evaluate
|
42
82
|
end
|
43
83
|
|
84
|
+
# Connect to the LDAP Server
|
85
|
+
def setup_ldap
|
86
|
+
begin
|
87
|
+
require 'ldap'
|
88
|
+
rescue LoadError
|
89
|
+
@ldap = nil
|
90
|
+
end
|
91
|
+
begin
|
92
|
+
@ldap = LDAP::Conn.new(Puppet[:ldapserver], Puppet[:ldapport])
|
93
|
+
@ldap.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
|
94
|
+
@ldap.simple_bind(Puppet[:ldapuser], Puppet[:ldappassword])
|
95
|
+
rescue => detail
|
96
|
+
raise Puppet::Error, "Could not connect to LDAP: %s" % detail
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# Find the ldap node and extra the info, returning just
|
101
|
+
# the critical data.
|
102
|
+
def nodesearch_ldap(node)
|
103
|
+
unless defined? @ldap
|
104
|
+
ldapconnect()
|
105
|
+
end
|
106
|
+
|
107
|
+
filter = Puppet[:ldapstring]
|
108
|
+
attrs = Puppet[:ldapattrs].split("\s*,\s*")
|
109
|
+
sattrs = attrs.dup
|
110
|
+
pattr = nil
|
111
|
+
if pattr = Puppet[:ldapparentattr]
|
112
|
+
if pattr == ""
|
113
|
+
pattr = nil
|
114
|
+
else
|
115
|
+
sattrs << pattr
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
if filter =~ /%s/
|
120
|
+
filter = filter.gsub(/%s/, node)
|
121
|
+
end
|
122
|
+
|
123
|
+
parent = nil
|
124
|
+
classes = []
|
125
|
+
|
126
|
+
found = false
|
127
|
+
# We're always doing a sub here; oh well.
|
128
|
+
@ldap.search(Puppet[:ldapbase], 2, filter, sattrs) do |entry|
|
129
|
+
found = true
|
130
|
+
if pattr
|
131
|
+
if values = entry.vals(pattr)
|
132
|
+
if values.length > 1
|
133
|
+
raise Puppet::Error,
|
134
|
+
"Node %s has more than one parent: %s" %
|
135
|
+
[node, values.inspect]
|
136
|
+
end
|
137
|
+
unless values.empty?
|
138
|
+
parent = values.shift
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
attrs.each { |attr|
|
144
|
+
if values = entry.vals(attr)
|
145
|
+
classes += values
|
146
|
+
end
|
147
|
+
}
|
148
|
+
end
|
149
|
+
|
150
|
+
classes.flatten!
|
151
|
+
|
152
|
+
return parent, classes
|
153
|
+
end
|
154
|
+
|
44
155
|
def parsedate
|
45
156
|
parsefiles()
|
46
157
|
@parsedate
|
@@ -67,8 +178,24 @@ module Puppet
|
|
67
178
|
"Cannot evaluate nodes with a nil client"
|
68
179
|
end
|
69
180
|
|
181
|
+
classes = nil
|
182
|
+
parent = nil
|
183
|
+
# At this point, stop at the first source that defines
|
184
|
+
# the node
|
185
|
+
@nodesources.each do |source|
|
186
|
+
method = "nodesearch_%s" % source
|
187
|
+
if self.respond_to? method
|
188
|
+
parent, classes = self.send(method, client)
|
189
|
+
end
|
190
|
+
|
191
|
+
if classes
|
192
|
+
Puppet.info "Found %s in %s" % [client, source]
|
193
|
+
break
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
70
197
|
# We've already evaluated the AST, in this case
|
71
|
-
return @scope.evalnode(names, facts)
|
198
|
+
return @scope.evalnode(names, facts, classes, parent)
|
72
199
|
else
|
73
200
|
# We've already evaluated the AST, in this case
|
74
201
|
@scope = Puppet::Parser::Scope.new() # no parent scope
|
@@ -164,4 +291,4 @@ module Puppet
|
|
164
291
|
end
|
165
292
|
end
|
166
293
|
|
167
|
-
# $Id: interpreter.rb
|
294
|
+
# $Id: interpreter.rb 915 2006-02-15 21:56:54Z luke $
|