puppet 0.22.4 → 0.23.0

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.

Files changed (266) hide show
  1. data/CHANGELOG +156 -0
  2. data/README +2 -2
  3. data/Rakefile +6 -6
  4. data/bin/filebucket +212 -0
  5. data/bin/puppet +2 -0
  6. data/bin/puppetca +2 -4
  7. data/bin/puppetd +16 -15
  8. data/bin/puppetdoc +46 -496
  9. data/bin/puppetmasterd +3 -5
  10. data/bin/puppetrun +8 -3
  11. data/bin/ralsh +271 -0
  12. data/conf/redhat/client.init +1 -1
  13. data/conf/redhat/puppet.spec +13 -2
  14. data/conf/solaris/pkginfo +1 -1
  15. data/ext/puppet-test +374 -0
  16. data/install.rb +40 -31
  17. data/lib/puppet.rb +39 -4
  18. data/lib/puppet/config_stores/rest.rb +60 -0
  19. data/lib/puppet/configuration.rb +312 -17
  20. data/lib/puppet/external/event-loop/event-loop.rb +4 -0
  21. data/lib/puppet/external/gratr/rdot.rb +1 -1
  22. data/lib/puppet/fact_stores/yaml.rb +42 -0
  23. data/lib/puppet/feature/base.rb +4 -1
  24. data/lib/puppet/metatype/attributes.rb +20 -43
  25. data/lib/puppet/metatype/container.rb +1 -36
  26. data/lib/puppet/metatype/evaluation.rb +48 -19
  27. data/lib/puppet/metatype/instances.rb +35 -1
  28. data/lib/puppet/metatype/metaparams.rb +23 -19
  29. data/lib/puppet/metatype/providers.rb +25 -38
  30. data/lib/puppet/network/client/ca.rb +8 -5
  31. data/lib/puppet/network/client/master.rb +59 -17
  32. data/lib/puppet/network/handler.rb +18 -1
  33. data/lib/puppet/network/handler/ca.rb +9 -3
  34. data/lib/puppet/network/handler/facts.rb +70 -0
  35. data/lib/puppet/network/handler/filebucket.rb +4 -1
  36. data/lib/puppet/network/handler/fileserver.rb +65 -21
  37. data/lib/puppet/network/handler/master.rb +6 -3
  38. data/lib/puppet/network/handler/report.rb +12 -26
  39. data/lib/puppet/network/handler/resource.rb +14 -2
  40. data/lib/puppet/network/handler/runner.rb +5 -1
  41. data/lib/puppet/network/handler/status.rb +5 -1
  42. data/lib/puppet/network/server/mongrel.rb +4 -4
  43. data/lib/puppet/network/server/webrick.rb +14 -3
  44. data/lib/puppet/parameter.rb +30 -25
  45. data/lib/puppet/parser/ast.rb +1 -6
  46. data/lib/puppet/parser/ast/component.rb +23 -20
  47. data/lib/puppet/parser/ast/hostclass.rb +7 -11
  48. data/lib/puppet/parser/ast/leaf.rb +4 -1
  49. data/lib/puppet/parser/ast/node.rb +6 -8
  50. data/lib/puppet/parser/functions.rb +7 -4
  51. data/lib/puppet/parser/interpreter.rb +155 -205
  52. data/lib/puppet/parser/lexer.rb +35 -2
  53. data/lib/puppet/parser/parser.rb +705 -612
  54. data/lib/puppet/parser/resource.rb +91 -48
  55. data/lib/puppet/parser/resource/param.rb +52 -29
  56. data/lib/puppet/parser/scope.rb +28 -23
  57. data/lib/puppet/pgraph.rb +26 -21
  58. data/lib/puppet/propertychange.rb +12 -12
  59. data/lib/puppet/provider.rb +102 -31
  60. data/lib/puppet/provider/cron/crontab.rb +7 -8
  61. data/lib/puppet/provider/group/groupadd.rb +4 -4
  62. data/lib/puppet/provider/group/pw.rb +3 -3
  63. data/lib/puppet/provider/mount.rb +8 -8
  64. data/lib/puppet/provider/mount/netinfo.rb +5 -5
  65. data/lib/puppet/provider/mount/parsed.rb +2 -2
  66. data/lib/puppet/provider/nameservice.rb +19 -31
  67. data/lib/puppet/provider/nameservice/netinfo.rb +14 -14
  68. data/lib/puppet/provider/nameservice/objectadd.rb +4 -4
  69. data/lib/puppet/provider/nameservice/pw.rb +4 -4
  70. data/lib/puppet/provider/package.rb +31 -0
  71. data/lib/puppet/provider/package/appdmg.rb +118 -0
  72. data/lib/puppet/provider/package/apple.rb +18 -16
  73. data/lib/puppet/provider/package/apt.rb +13 -15
  74. data/lib/puppet/provider/package/aptitude.rb +5 -3
  75. data/lib/puppet/provider/package/aptrpm.rb +9 -11
  76. data/lib/puppet/provider/package/blastwave.rb +9 -9
  77. data/lib/puppet/provider/package/darwinport.rb +12 -11
  78. data/lib/puppet/provider/package/dpkg.rb +20 -12
  79. data/lib/puppet/provider/package/fink.rb +87 -0
  80. data/lib/puppet/provider/package/freebsd.rb +10 -11
  81. data/lib/puppet/provider/package/gem.rb +15 -15
  82. data/lib/puppet/provider/package/openbsd.rb +12 -17
  83. data/lib/puppet/provider/package/pkgdmg.rb +90 -16
  84. data/lib/puppet/provider/package/portage.rb +20 -14
  85. data/lib/puppet/provider/package/ports.rb +15 -13
  86. data/lib/puppet/provider/package/rpm.rb +20 -23
  87. data/lib/puppet/provider/package/rug.rb +6 -8
  88. data/lib/puppet/provider/package/sun.rb +20 -18
  89. data/lib/puppet/provider/package/sunfreeware.rb +2 -2
  90. data/lib/puppet/provider/package/up2date.rb +6 -10
  91. data/lib/puppet/provider/package/urpmi.rb +51 -0
  92. data/lib/puppet/provider/package/yum.rb +15 -13
  93. data/lib/puppet/provider/parsedfile.rb +53 -63
  94. data/lib/puppet/provider/service/base.rb +13 -15
  95. data/lib/puppet/provider/service/debian.rb +4 -4
  96. data/lib/puppet/provider/service/gentoo.rb +4 -4
  97. data/lib/puppet/provider/service/init.rb +22 -15
  98. data/lib/puppet/provider/service/redhat.rb +6 -6
  99. data/lib/puppet/provider/service/smf.rb +6 -6
  100. data/lib/puppet/provider/user/netinfo.rb +5 -5
  101. data/lib/puppet/provider/user/pw.rb +10 -5
  102. data/lib/puppet/provider/user/useradd.rb +9 -14
  103. data/lib/puppet/provider/zone/solaris.rb +80 -45
  104. data/lib/puppet/rails.rb +3 -34
  105. data/lib/puppet/rails/database/schema.rb +45 -24
  106. data/lib/puppet/rails/fact_value.rb +1 -0
  107. data/lib/puppet/rails/host.rb +69 -40
  108. data/lib/puppet/rails/param_name.rb +3 -8
  109. data/lib/puppet/rails/param_value.rb +2 -1
  110. data/lib/puppet/rails/puppet_class.rb +0 -2
  111. data/lib/puppet/rails/puppet_tag.rb +5 -0
  112. data/lib/puppet/rails/resource.rb +41 -17
  113. data/lib/puppet/rails/resource_tag.rb +4 -0
  114. data/lib/puppet/reference/configuration.rb +149 -0
  115. data/lib/puppet/reference/function.rb +13 -0
  116. data/lib/puppet/reference/network.rb +37 -0
  117. data/lib/puppet/reference/providers.rb +118 -0
  118. data/lib/puppet/reference/report.rb +21 -0
  119. data/lib/puppet/reference/type.rb +152 -0
  120. data/lib/puppet/reports/rrdgraph.rb +21 -7
  121. data/lib/puppet/reports/tagmail.rb +4 -1
  122. data/lib/puppet/sslcertificates.rb +1 -49
  123. data/lib/puppet/sslcertificates/ca.rb +2 -79
  124. data/lib/puppet/sslcertificates/inventory.rb +0 -10
  125. data/lib/puppet/transaction.rb +24 -41
  126. data/lib/puppet/transaction/report.rb +27 -1
  127. data/lib/puppet/type.rb +7 -43
  128. data/lib/puppet/type/component.rb +198 -124
  129. data/lib/puppet/type/cron.rb +51 -42
  130. data/lib/puppet/type/exec.rb +20 -19
  131. data/lib/puppet/type/group.rb +6 -55
  132. data/lib/puppet/type/host.rb +16 -37
  133. data/lib/puppet/type/mount.rb +30 -17
  134. data/lib/puppet/type/notify.rb +7 -8
  135. data/lib/puppet/type/package.rb +44 -80
  136. data/lib/puppet/type/pfile.rb +50 -41
  137. data/lib/puppet/type/pfile/checksum.rb +82 -95
  138. data/lib/puppet/type/pfile/content.rb +21 -25
  139. data/lib/puppet/type/pfile/ensure.rb +32 -30
  140. data/lib/puppet/type/pfile/group.rb +21 -26
  141. data/lib/puppet/type/pfile/mode.rb +25 -32
  142. data/lib/puppet/type/pfile/owner.rb +23 -27
  143. data/lib/puppet/type/pfile/source.rb +42 -33
  144. data/lib/puppet/type/pfile/target.rb +20 -18
  145. data/lib/puppet/type/pfile/type.rb +6 -7
  146. data/lib/puppet/type/pfilebucket.rb +3 -3
  147. data/lib/puppet/type/port.rb +5 -7
  148. data/lib/puppet/type/property.rb +58 -61
  149. data/lib/puppet/type/resources.rb +12 -8
  150. data/lib/puppet/type/schedule.rb +8 -8
  151. data/lib/puppet/type/service.rb +26 -33
  152. data/lib/puppet/type/sshkey.rb +6 -7
  153. data/lib/puppet/type/tidy.rb +41 -35
  154. data/lib/puppet/type/user.rb +34 -67
  155. data/lib/puppet/type/yumrepo.rb +27 -12
  156. data/lib/puppet/type/zone.rb +71 -110
  157. data/lib/puppet/util.rb +46 -61
  158. data/lib/puppet/util/autoload.rb +59 -47
  159. data/lib/puppet/util/config.rb +160 -18
  160. data/lib/puppet/util/config_store.rb +61 -0
  161. data/lib/puppet/util/fact_store.rb +60 -0
  162. data/lib/puppet/util/instance_loader.rb +74 -0
  163. data/lib/puppet/util/loadedfile.rb +5 -8
  164. data/lib/puppet/util/metric.rb +17 -25
  165. data/lib/puppet/util/posix.rb +39 -7
  166. data/lib/puppet/util/provider_features.rb +9 -1
  167. data/lib/puppet/util/rails/collection_merger.rb +16 -1
  168. data/lib/puppet/util/reference.rb +189 -0
  169. data/lib/puppet/util/storage.rb +2 -2
  170. data/lib/puppet/util/subclass_loader.rb +9 -2
  171. data/test/language/ast.rb +4 -148
  172. data/test/language/ast/component.rb +10 -1
  173. data/test/language/collector.rb +1 -191
  174. data/test/language/interpreter.rb +284 -327
  175. data/test/language/lexer.rb +13 -1
  176. data/test/language/node.rb +1 -1
  177. data/test/language/parser.rb +17 -4
  178. data/test/language/resource.rb +67 -101
  179. data/test/language/scope.rb +18 -3
  180. data/test/language/snippets.rb +114 -151
  181. data/test/lib/puppettest.rb +13 -0
  182. data/test/lib/puppettest/exetest.rb +7 -0
  183. data/test/lib/puppettest/fakes.rb +39 -28
  184. data/test/lib/puppettest/railstesting.rb +1 -1
  185. data/test/lib/puppettest/support/assertions.rb +2 -2
  186. data/test/lib/puppettest/support/collection.rb +30 -0
  187. data/test/network/client/ca.rb +27 -1
  188. data/test/network/client/client.rb +3 -3
  189. data/test/network/client/master.rb +102 -1
  190. data/test/network/handler/ca.rb +35 -1
  191. data/test/network/handler/facts.rb +112 -0
  192. data/test/network/handler/fileserver.rb +25 -1
  193. data/test/network/handler/handler.rb +2 -2
  194. data/test/network/handler/master.rb +2 -49
  195. data/test/network/handler/resource.rb +5 -6
  196. data/test/network/server/mongrel_test.rb +65 -0
  197. data/test/network/server/webrick.rb +2 -2
  198. data/test/network/xmlrpc/client.rb +2 -1
  199. data/test/network/xmlrpc/processor.rb +2 -1
  200. data/test/other/pgraph.rb +6 -5
  201. data/test/other/propertychange.rb +11 -12
  202. data/test/other/report.rb +44 -27
  203. data/test/other/transactions.rb +17 -16
  204. data/test/puppet/tc_suidmanager.rb +2 -2
  205. data/test/rails/ast.rb +74 -0
  206. data/test/rails/collection.rb +214 -0
  207. data/test/rails/host.rb +49 -24
  208. data/test/rails/interpreter.rb +91 -0
  209. data/test/rails/railsparameter.rb +22 -11
  210. data/test/rails/railsresource.rb +140 -7
  211. data/test/ral/manager/attributes.rb +37 -13
  212. data/test/ral/manager/instances.rb +82 -0
  213. data/test/ral/manager/provider.rb +60 -22
  214. data/test/ral/manager/type.rb +9 -6
  215. data/test/ral/providers/cron/crontab.rb +59 -7
  216. data/test/ral/providers/group.rb +7 -7
  217. data/test/ral/providers/host/netinfo.rb +5 -6
  218. data/test/ral/providers/host/parsed.rb +4 -4
  219. data/test/ral/providers/mount/parsed.rb +11 -6
  220. data/test/ral/providers/nameservice.rb +2 -2
  221. data/test/ral/providers/package.rb +39 -14
  222. data/test/ral/providers/package/apt.rb +72 -3
  223. data/test/ral/providers/package/aptitude.rb +15 -12
  224. data/test/ral/providers/package/aptrpm.rb +3 -3
  225. data/test/ral/providers/package/dpkg.rb +2 -2
  226. data/test/ral/providers/parsedfile.rb +114 -88
  227. data/test/ral/providers/{parsedport.rb → port/parsed.rb} +1 -1
  228. data/test/ral/providers/provider.rb +93 -13
  229. data/test/ral/providers/service.rb +52 -26
  230. data/test/ral/providers/sshkey/parsed.rb +3 -3
  231. data/test/ral/providers/user.rb +19 -20
  232. data/test/ral/providers/user/useradd.rb +1 -5
  233. data/test/ral/types/cron.rb +49 -36
  234. data/test/ral/types/file.rb +38 -35
  235. data/test/ral/types/file/target.rb +4 -4
  236. data/test/ral/types/filesources.rb +24 -22
  237. data/test/ral/types/group.rb +4 -2
  238. data/test/ral/types/host.rb +17 -10
  239. data/test/ral/types/mount.rb +40 -23
  240. data/test/ral/types/package.rb +62 -5
  241. data/test/ral/types/parameter.rb +2 -2
  242. data/test/ral/types/property.rb +27 -20
  243. data/test/ral/types/resources.rb +4 -16
  244. data/test/ral/types/schedule.rb +2 -2
  245. data/test/ral/types/service.rb +2 -3
  246. data/test/ral/types/sshkey.rb +3 -3
  247. data/test/ral/types/tidy.rb +6 -15
  248. data/test/ral/types/user.rb +17 -17
  249. data/test/ral/types/yumrepo.rb +2 -2
  250. data/test/ral/types/zone.rb +71 -87
  251. data/test/util/autoload.rb +6 -21
  252. data/test/util/config.rb +201 -101
  253. data/test/util/fact_store.rb +67 -0
  254. data/test/util/features.rb +9 -6
  255. data/test/util/instance_loader.rb +53 -0
  256. data/test/util/loadedfile.rb +17 -1
  257. data/test/util/metrics.rb +54 -57
  258. data/test/util/posixtest.rb +8 -11
  259. data/test/util/utiltest.rb +31 -2
  260. metadata +520 -492
  261. data/TODO +0 -4
  262. data/lib/puppet/network/client/logger.rb +0 -6
  263. data/lib/puppet/network/handler/logger.rb +0 -52
  264. data/lib/puppet/rails/database/001_add_indexes.rb +0 -38
  265. data/lib/puppet/type/parsedtype.rb +0 -219
  266. data/test/network/handler/logger.rb +0 -183
@@ -12,11 +12,6 @@ class Puppet::Parser::AST
12
12
 
13
13
  include Puppet::Util::Errors
14
14
  include Puppet::Util::MethodHelper
15
-
16
- Puppet.setdefaults("ast",
17
- :typecheck => [true, "Whether to validate types during parsing."],
18
- :paramcheck => [true, "Whether to validate parameters during parsing."]
19
- )
20
15
  attr_accessor :line, :file, :parent, :scope
21
16
 
22
17
  # Just used for 'tree', which is only used in debugging.
@@ -122,4 +117,4 @@ end
122
117
 
123
118
  require 'puppet/parser/ast/leaf'
124
119
 
125
- # $Id: ast.rb 2231 2007-02-27 21:31:02Z luke $
120
+ # $Id: ast.rb 2463 2007-05-04 23:09:34Z luke $
@@ -15,37 +15,43 @@ class Puppet::Parser::AST
15
15
  # The class name
16
16
  @name = :definition
17
17
 
18
- attr_accessor :type, :arguments, :code, :scope, :keyword
19
- attr_accessor :exported, :namespace, :fqname, :interp
18
+ attr_accessor :classname, :arguments, :code, :scope, :keyword
19
+ attr_accessor :exported, :namespace, :interp, :virtual
20
20
 
21
21
  # These are retrieved when looking up the superclass
22
22
  attr_accessor :name
23
23
 
24
+ attr_reader :parentclass
25
+
24
26
  def child_of?(klass)
25
27
  false
26
28
  end
27
29
 
28
30
  def evaluate(hash)
29
31
  origscope = hash[:scope]
30
- objtype = hash[:type]
31
32
  title = hash[:title]
32
33
  args = symbolize_options(hash[:arguments] || {})
33
34
 
34
35
  name = args[:name] || title
35
36
 
36
37
  exported = hash[:exported]
38
+ virtual = hash[:virtual]
37
39
 
38
40
  pscope = origscope
39
41
  scope = subscope(pscope, title)
40
42
 
43
+ if virtual or origscope.virtual?
44
+ scope.virtual = true
45
+ end
46
+
41
47
  if exported or origscope.exported?
42
48
  scope.exported = true
43
49
  end
44
50
 
45
51
  # Additionally, add a tag for whatever kind of class
46
52
  # we are
47
- if @type != "" and ! @type.nil?
48
- scope.tag(@type)
53
+ if @classname != "" and ! @classname.nil?
54
+ @classname.split(/::/).each { |tag| scope.tag(tag) }
49
55
  end
50
56
 
51
57
  [name, title].each do |str|
@@ -68,7 +74,7 @@ class Puppet::Parser::AST
68
74
  # [default.inspect, arg.inspect, @name.inspect]
69
75
  else
70
76
  parsefail "Must pass %s to %s of type %s" %
71
- [arg,title,@type]
77
+ [arg,title,@classname]
72
78
  end
73
79
  end
74
80
  }
@@ -78,7 +84,7 @@ class Puppet::Parser::AST
78
84
  # component's scope.
79
85
  args.each { |arg,value|
80
86
  unless validattr?(arg)
81
- parsefail "%s does not accept attribute %s" % [@type, arg]
87
+ parsefail "%s does not accept attribute %s" % [@classname, arg]
82
88
  end
83
89
 
84
90
  exceptwrap do
@@ -133,16 +139,14 @@ class Puppet::Parser::AST
133
139
  end
134
140
  end
135
141
 
136
- def parentclass
137
- parentobj do |name|
138
- @interp.findclass(namespace, name)
139
- end
142
+ def find_parentclass
143
+ @interp.findclass(namespace, parentclass)
140
144
  end
141
145
 
142
146
  # Set our parent class, with a little check to avoid some potential
143
147
  # weirdness.
144
148
  def parentclass=(name)
145
- if name == self.type
149
+ if name == self.classname
146
150
  parsefail "Parent classes must have dissimilar names"
147
151
  end
148
152
 
@@ -153,8 +157,8 @@ class Puppet::Parser::AST
153
157
  def parentobj
154
158
  if @parentclass
155
159
  # Cache our result, since it should never change.
156
- unless @parentclass.is_a?(AST::HostClass)
157
- unless tmp = yield(@parentclass)
160
+ unless defined?(@parentobj)
161
+ unless tmp = find_parentclass
158
162
  parsefail "Could not find %s %s" % [self.class.name, @parentclass]
159
163
  end
160
164
 
@@ -162,9 +166,9 @@ class Puppet::Parser::AST
162
166
  parsefail "Parent classes must have dissimilar names"
163
167
  end
164
168
 
165
- @parentclass = tmp
169
+ @parentobj = tmp
166
170
  end
167
- @parentclass
171
+ @parentobj
168
172
  else
169
173
  nil
170
174
  end
@@ -173,13 +177,12 @@ class Puppet::Parser::AST
173
177
  # Create a new subscope in which to evaluate our code.
174
178
  def subscope(scope, name = nil)
175
179
  args = {
176
- :type => @type,
180
+ :type => self.classname,
177
181
  :keyword => self.keyword,
178
182
  :namespace => self.namespace
179
183
  }
180
184
 
181
185
  args[:name] = name if name
182
- args[:type] = self.type if self.type
183
186
  scope = scope.newscope(args)
184
187
  scope.source = self
185
188
 
@@ -187,7 +190,7 @@ class Puppet::Parser::AST
187
190
  end
188
191
 
189
192
  def to_s
190
- fqname
193
+ classname
191
194
  end
192
195
 
193
196
  # Check whether a given argument is valid. Searches up through
@@ -220,4 +223,4 @@ class Puppet::Parser::AST
220
223
  end
221
224
  end
222
225
 
223
- # $Id: component.rb 2393 2007-04-19 18:34:03Z luke $
226
+ # $Id: component.rb 2562 2007-06-11 21:54:37Z luke $
@@ -12,10 +12,10 @@ class Puppet::Parser::AST
12
12
  def child_of?(klass)
13
13
  return false unless self.parentclass
14
14
 
15
- if klass == self.parentclass
15
+ if klass == self.parentobj
16
16
  return true
17
17
  else
18
- return self.parentclass.child_of?(klass)
18
+ return self.parentobj.child_of?(klass)
19
19
  end
20
20
  end
21
21
 
@@ -31,15 +31,11 @@ class Puppet::Parser::AST
31
31
  end
32
32
 
33
33
  pnames = nil
34
- if @parentclass
35
- if pklass = self.parentclass
36
- pklass.safeevaluate :scope => scope
34
+ if pklass = self.parentobj
35
+ pklass.safeevaluate :scope => scope
37
36
 
38
- scope = parent_scope(scope, pklass)
39
- pnames = scope.namespaces
40
- else
41
- parsefail "Could not find class %s" % @parentclass
42
- end
37
+ scope = parent_scope(scope, pklass)
38
+ pnames = scope.namespaces
43
39
  end
44
40
 
45
41
  unless hash[:nosubscope]
@@ -79,4 +75,4 @@ class Puppet::Parser::AST
79
75
  end
80
76
  end
81
77
 
82
- # $Id: hostclass.rb 2226 2007-02-27 16:30:09Z luke $
78
+ # $Id: hostclass.rb 2511 2007-05-14 15:19:48Z luke $
@@ -66,6 +66,9 @@ class Puppet::Parser::AST
66
66
  # double-colon separated class names
67
67
  class ClassName < AST::Leaf; end
68
68
 
69
+ # undef values; equiv to nil
70
+ class Undef < AST::Leaf; end
71
+
69
72
  # Host names, either fully qualified or just the short name
70
73
  class HostName < AST::Leaf
71
74
  def initialize(hash)
@@ -92,4 +95,4 @@ class Puppet::Parser::AST
92
95
 
93
96
  end
94
97
 
95
- # $Id: leaf.rb 2239 2007-02-28 01:21:58Z luke $
98
+ # $Id: leaf.rb 2522 2007-05-17 21:43:51Z luke $
@@ -19,7 +19,7 @@ class Puppet::Parser::AST
19
19
 
20
20
  # We don't have to worry about the declarativeness of node parentage,
21
21
  # because the entry point is always a single node definition.
22
- if parent = self.parentclass
22
+ if parent = self.parentobj
23
23
  scope = parent.safeevaluate :scope => scope
24
24
  end
25
25
 
@@ -53,14 +53,12 @@ class Puppet::Parser::AST
53
53
  end
54
54
  end
55
55
 
56
- def parentclass
57
- parentobj do |name|
58
- @interp.nodesearch(name)
59
- end
60
-
61
- @parentclass
56
+ private
57
+ # Search for the object matching our parent class.
58
+ def find_parentclass
59
+ @interp.nodesearch(parentclass)
62
60
  end
63
61
  end
64
62
  end
65
63
 
66
- # $Id: node.rb 1727 2006-10-04 18:44:26Z luke $
64
+ # $Id: node.rb 2511 2007-05-14 15:19:48Z luke $
@@ -142,7 +142,7 @@ module Functions
142
142
  # specified tags are unset, we return false.
143
143
  newfunction(:tagged, :type => :rvalue, :doc => "A boolean function that
144
144
  tells you whether the current container is tagged with the specified tags.
145
- The tags are ANDed, so thta all of the specified tags must be included for
145
+ The tags are ANDed, so that all of the specified tags must be included for
146
146
  the function to return true.") do |vals|
147
147
  classlist = self.classlist
148
148
 
@@ -196,9 +196,12 @@ module Functions
196
196
  end
197
197
 
198
198
  newfunction(:template, :type => :rvalue, :doc => "Evaluate a template and
199
- return its value. See [the templating docs](/trac/puppet/wiki/PuppetTemplating)
199
+ return its value. See `the templating docs`_
200
200
  for more information. Note that if multiple templates are specified, their
201
- output is all concatenated and returned as the output of the function.") do |vals|
201
+ output is all concatenated and returned as the output of the function.
202
+
203
+ .. _the templating docs: /trac/puppet/wiki/PuppetTemplating
204
+ ") do |vals|
202
205
  require 'erb'
203
206
 
204
207
  vals.collect do |file|
@@ -297,4 +300,4 @@ module Functions
297
300
  end
298
301
  end
299
302
 
300
- # $Id: functions.rb 2406 2007-04-23 06:16:10Z luke $
303
+ # $Id: functions.rb 2502 2007-05-10 21:27:40Z luke $
@@ -5,66 +5,55 @@
5
5
  require 'puppet'
6
6
  require 'timeout'
7
7
  require 'puppet/rails'
8
+ require 'puppet/util/methodhelper'
8
9
  require 'puppet/parser/parser'
9
10
  require 'puppet/parser/scope'
10
11
 
11
12
  class Puppet::Parser::Interpreter
13
+ class NodeDef
14
+ include Puppet::Util::MethodHelper
15
+ attr_accessor :name, :classes, :parameters, :source
16
+
17
+ def evaluate(options)
18
+ begin
19
+ parameters.each do |param, value|
20
+ # Don't try to override facts with these parameters
21
+ options[:scope].setvar(param, value) unless options[:scope].lookupvar(param, false) != :undefined
22
+ end
23
+
24
+ # Also, set the 'nodename', since it might not be obvious how the node was looked up
25
+ options[:scope].setvar("nodename", @name) unless options[:scope].lookupvar(@nodename, false) != :undefined
26
+ rescue => detail
27
+ raise Puppet::ParseError, "Could not set parameters for %s: %s" % [name, detail]
28
+ end
29
+
30
+ # Then evaluate the classes.
31
+ begin
32
+ options[:scope].function_include(classes)
33
+ rescue => detail
34
+ raise Puppet::ParseError, "Could not evaluate classes for %s: %s" % [name, detail]
35
+ end
36
+ end
37
+
38
+ def initialize(args)
39
+ set_options(args)
40
+
41
+ raise Puppet::DevError, "NodeDefs require names" unless self.name
42
+
43
+ if self.classes.is_a?(String)
44
+ @classes = [@classes]
45
+ else
46
+ @classes ||= []
47
+ end
48
+ @parameters ||= {}
49
+ end
50
+
51
+ def safeevaluate(args)
52
+ evaluate(args)
53
+ end
54
+ end
55
+
12
56
  include Puppet::Util
13
-
14
- Puppet.setdefaults(:puppet,
15
- :casesensitive => [false,
16
- "Whether matching in case statements and selectors
17
- should be case-sensitive. Case insensitivity is
18
- handled by downcasing all values before comparison."],
19
- :external_nodes => ["none",
20
- "An external command that can produce node information. The
21
- first line of output must be either the parent node or blank,
22
- and if there is a second line of output it should be a list of
23
- whitespace-separated classes to include on that node. This command
24
- makes it straightforward to store your node mapping information
25
- in other data sources like databases.
26
-
27
- For unknown nodes, the commands should exit with an exit code of 1."])
28
-
29
- Puppet.setdefaults("ldap",
30
- :ldapnodes => [false,
31
- "Whether to search for node configurations in LDAP."],
32
- :ldapssl => [false,
33
- "Whether SSL should be used when searching for nodes.
34
- Defaults to false because SSL usually requires certificates
35
- to be set up on the client side."],
36
- :ldaptls => [false,
37
- "Whether TLS should be used when searching for nodes.
38
- Defaults to false because TLS usually requires certificates
39
- to be set up on the client side."],
40
- :ldapserver => ["ldap",
41
- "The LDAP server. Only used if ``ldapnodes`` is enabled."],
42
- :ldapport => [389,
43
- "The LDAP port. Only used if ``ldapnodes`` is enabled."],
44
- :ldapstring => ["(&(objectclass=puppetClient)(cn=%s))",
45
- "The search string used to find an LDAP node."],
46
- :ldapattrs => ["puppetclass",
47
- "The LDAP attributes to use to define Puppet classes. Values
48
- should be comma-separated."],
49
- :ldapparentattr => ["parentnode",
50
- "The attribute to use to define the parent node."],
51
- :ldapuser => ["",
52
- "The user to use to connect to LDAP. Must be specified as a
53
- full DN."],
54
- :ldappassword => ["",
55
- "The password to use to connect to LDAP."],
56
- :ldapbase => ["",
57
- "The search base for LDAP searches. It's impossible to provide
58
- a meaningful default here, although the LDAP libraries might
59
- have one already set. Generally, it should be the 'ou=Hosts'
60
- branch under your main directory."]
61
- )
62
-
63
- Puppet.setdefaults(:puppetmaster,
64
- :storeconfigs => [false,
65
- "Whether to store each client's configuration. This
66
- requires ActiveRecord from Ruby on Rails."]
67
- )
68
57
 
69
58
  attr_accessor :usenodes
70
59
 
@@ -211,7 +200,8 @@ class Puppet::Parser::Interpreter
211
200
  klass.safeevaluate :scope => scope, :nosubscope => true
212
201
  end
213
202
 
214
- # Next evaluate the node
203
+ # Next evaluate the node. We pass the facts so they can be used
204
+ # when building the list of names for which to search.
215
205
  evalnode(client, scope, facts)
216
206
 
217
207
  # If we were passed any classes, evaluate those.
@@ -313,51 +303,6 @@ class Puppet::Parser::Interpreter
313
303
  return nil
314
304
  end
315
305
 
316
- # Create a new node, just from a list of names, classes, and an optional parent.
317
- def gennode(name, hash, source = nil)
318
- facts = hash[:facts]
319
- classes = hash[:classes]
320
- parent = hash[:parentnode]
321
- arghash = {
322
- :name => name,
323
- :interp => self,
324
- :fqname => name
325
- }
326
-
327
- if (classes.is_a?(Array) and classes.empty?) or classes.nil?
328
- arghash[:code] = AST::ASTArray.new(:children => [])
329
- else
330
- classes = [classes] unless classes.is_a?(Array)
331
-
332
- classcode = @parser.ast(AST::ASTArray, :children => classes.collect do |klass|
333
- @parser.ast(AST::FlatString, :value => klass)
334
- end)
335
-
336
- # Now generate a function call.
337
- code = @parser.ast(AST::Function,
338
- :name => "include",
339
- :arguments => classcode,
340
- :ftype => :statement
341
- )
342
-
343
- arghash[:code] = code
344
- end
345
-
346
- if parent
347
- arghash[:parentclass] = parent
348
- end
349
-
350
- # Create the node
351
- if source
352
- arghash[:file] = source
353
- else
354
- arghash[:file] = nil
355
- end
356
- arghash[:line] = nil
357
- node = @parser.ast(AST::Node, arghash)
358
- return node
359
- end
360
-
361
306
  # create our interpreter
362
307
  def initialize(hash)
363
308
  if @code = hash[:Code]
@@ -372,33 +317,15 @@ class Puppet::Parser::Interpreter
372
317
  @usenodes = true
373
318
  end
374
319
 
375
- # By default, we only search for parsed nodes.
376
- @nodesources = []
377
320
 
378
321
  if Puppet[:ldapnodes]
379
322
  # Nodes in the file override nodes in ldap.
380
- @nodesources << :ldap
381
- end
382
-
383
- if hash[:NodeSources]
384
- unless hash[:NodeSources].is_a?(Array)
385
- hash[:NodeSources] = [hash[:NodeSources]]
386
- end
387
- hash[:NodeSources].each do |src|
388
- if respond_to? "nodesearch_#{src.to_s}"
389
- @nodesources << src.to_s.intern
390
- else
391
- Puppet.warning "Node source '#{src}' not supported"
392
- end
393
- end
394
- end
395
-
396
- unless @nodesources.include?(:code)
397
- @nodesources << :code
398
- end
399
-
400
- unless Puppet[:external_nodes] == "none"
401
- @nodesources << :external
323
+ @nodesource = :ldap
324
+ elsif Puppet[:external_nodes] != "none"
325
+ @nodesource = :external
326
+ else
327
+ # By default, we only search for parsed nodes.
328
+ @nodesource = :code
402
329
  end
403
330
 
404
331
  @setup = false
@@ -444,26 +371,31 @@ class Puppet::Parser::Interpreter
444
371
  @definetable = {}
445
372
  end
446
373
 
447
- # Find the ldap node and extra the info, returning just
448
- # the critical data.
374
+ # Find the ldap node, return the class list and parent node specially,
375
+ # and everything else in a parameter hash.
449
376
  def ldapsearch(node)
450
377
  unless defined? @ldap and @ldap
451
378
  setup_ldap()
452
379
  unless @ldap
453
380
  Puppet.info "Skipping ldap source; no ldap connection"
454
- return nil, []
381
+ return nil
455
382
  end
456
383
  end
457
384
 
458
385
  filter = Puppet[:ldapstring]
459
- attrs = Puppet[:ldapattrs].split("\s*,\s*")
460
- sattrs = attrs.dup
386
+ classattrs = Puppet[:ldapclassattrs].split("\s*,\s*")
387
+ if Puppet[:ldapattrs] == "all"
388
+ # A nil value here causes all attributes to be returned.
389
+ search_attrs = nil
390
+ else
391
+ search_attrs = classattrs + Puppet[:ldapattrs].split("\s*,\s*")
392
+ end
461
393
  pattr = nil
462
394
  if pattr = Puppet[:ldapparentattr]
463
395
  if pattr == ""
464
396
  pattr = nil
465
397
  else
466
- sattrs << pattr
398
+ search_attrs << pattr unless search_attrs.nil?
467
399
  end
468
400
  end
469
401
 
@@ -473,12 +405,14 @@ class Puppet::Parser::Interpreter
473
405
 
474
406
  parent = nil
475
407
  classes = []
408
+ parameters = nil
476
409
 
477
410
  found = false
478
411
  count = 0
412
+
479
413
  begin
480
414
  # We're always doing a sub here; oh well.
481
- @ldap.search(Puppet[:ldapbase], 2, filter, sattrs) do |entry|
415
+ @ldap.search(Puppet[:ldapbase], 2, filter, search_attrs) do |entry|
482
416
  found = true
483
417
  if pattr
484
418
  if values = entry.vals(pattr)
@@ -493,11 +427,20 @@ class Puppet::Parser::Interpreter
493
427
  end
494
428
  end
495
429
 
496
- attrs.each { |attr|
430
+ classattrs.each { |attr|
497
431
  if values = entry.vals(attr)
498
432
  values.each do |v| classes << v end
499
433
  end
500
434
  }
435
+
436
+ parameters = entry.to_hash.inject({}) do |hash, ary|
437
+ if ary[1].length == 1
438
+ hash[ary[0]] = ary[1].shift
439
+ else
440
+ hash[ary[0]] = ary[1]
441
+ end
442
+ hash
443
+ end
501
444
  end
502
445
  rescue => detail
503
446
  if count == 0
@@ -516,7 +459,11 @@ class Puppet::Parser::Interpreter
516
459
  classes = nil
517
460
  end
518
461
 
519
- return parent, classes
462
+ if parent or classes or parameters
463
+ return parent, classes, parameters
464
+ else
465
+ return nil
466
+ end
520
467
  end
521
468
 
522
469
  # Split an fq name into a namespace and name
@@ -528,20 +475,20 @@ class Puppet::Parser::Interpreter
528
475
  end
529
476
 
530
477
  # Create a new class, or merge with an existing class.
531
- def newclass(fqname, options = {})
532
- fqname = fqname.downcase
533
- if @definetable.include?(fqname)
478
+ def newclass(name, options = {})
479
+ name = name.downcase
480
+ if @definetable.include?(name)
534
481
  raise Puppet::ParseError, "Cannot redefine class %s as a definition" %
535
- fqname
482
+ name
536
483
  end
537
484
  code = options[:code]
538
485
  parent = options[:parent]
539
486
 
540
487
  # If the class is already defined, then add code to it.
541
- if other = @classtable[fqname]
488
+ if other = @classtable[name]
542
489
  # Make sure the parents match
543
490
  if parent and other.parentclass and (parent != other.parentclass)
544
- @parser.error("Class %s is already defined at %s:%s; cannot redefine" % [fqname, other.file, other.line])
491
+ @parser.error("Class %s is already defined at %s:%s; cannot redefine" % [name, other.file, other.line])
545
492
  end
546
493
 
547
494
  # This might be dangerous...
@@ -551,7 +498,7 @@ class Puppet::Parser::Interpreter
551
498
 
552
499
  # This might just be an empty, stub class.
553
500
  if code
554
- tmp = fqname
501
+ tmp = name
555
502
  if tmp == ""
556
503
  tmp = "main"
557
504
  end
@@ -566,46 +513,43 @@ class Puppet::Parser::Interpreter
566
513
  end
567
514
  else
568
515
  # Define it anew.
569
- ns, name = namesplit(fqname)
570
-
571
516
  # Note we're doing something somewhat weird here -- we're setting
572
517
  # the class's namespace to its fully qualified name. This means
573
518
  # anything inside that class starts looking in that namespace first.
574
- args = {:type => name, :namespace => fqname, :fqname => fqname, :interp => self}
519
+ args = {:namespace => name, :classname => name, :interp => self}
575
520
  args[:code] = code if code
576
521
  args[:parentclass] = parent if parent
577
- @classtable[fqname] = @parser.ast AST::HostClass, args
522
+ @classtable[name] = @parser.ast AST::HostClass, args
578
523
  end
579
524
 
580
- return @classtable[fqname]
525
+ return @classtable[name]
581
526
  end
582
527
 
583
528
  # Create a new definition.
584
- def newdefine(fqname, options = {})
585
- fqname = fqname.downcase
586
- if @classtable.include?(fqname)
529
+ def newdefine(name, options = {})
530
+ name = name.downcase
531
+ if @classtable.include?(name)
587
532
  raise Puppet::ParseError, "Cannot redefine class %s as a definition" %
588
- fqname
533
+ name
589
534
  end
590
535
  # Make sure our definition doesn't already exist
591
- if other = @definetable[fqname]
592
- @parser.error("%s is already defined at %s:%s; cannot redefine" % [fqname, other.file, other.line])
536
+ if other = @definetable[name]
537
+ @parser.error("%s is already defined at %s:%s; cannot redefine" % [name, other.file, other.line])
593
538
  end
594
539
 
595
- ns, name = namesplit(fqname)
540
+ ns, whatever = namesplit(name)
596
541
  args = {
597
- :type => name,
598
542
  :namespace => ns,
599
543
  :arguments => options[:arguments],
600
544
  :code => options[:code],
601
- :fqname => fqname
545
+ :classname => name
602
546
  }
603
547
 
604
548
  [:code, :arguments].each do |param|
605
549
  args[param] = options[param] if options[param]
606
550
  end
607
551
 
608
- @definetable[fqname] = @parser.ast AST::Component, args
552
+ @definetable[name] = @parser.ast AST::Component, args
609
553
  end
610
554
 
611
555
  # Create a new node. Nodes are special, because they're stored in a global
@@ -628,8 +572,7 @@ class Puppet::Parser::Interpreter
628
572
  args[:parentclass] = options[:parent]
629
573
  end
630
574
  @nodetable[name] = @parser.ast(AST::Node, args)
631
- @nodetable[name].fqname = name
632
- @nodetable[name]
575
+ @nodetable[name].classname = name
633
576
  @nodetable[name].interp = self
634
577
  @nodetable[name]
635
578
  end
@@ -649,21 +592,20 @@ class Puppet::Parser::Interpreter
649
592
  # Search for our node in the various locations.
650
593
  def nodesearch(*nodes)
651
594
  nodes = nodes.collect { |n| n.to_s.downcase }
652
- # At this point, stop at the first source that defines
653
- # the node
654
- @nodesources.each do |source|
655
- method = "nodesearch_%s" % source
656
- if self.respond_to? method
657
- # Do an inverse sort on the length, so the longest match always
658
- # wins
659
- nodes.sort { |a,b| b.length <=> a.length }.each do |node|
660
- node = node.to_s if node.is_a?(Symbol)
661
- if obj = self.send(method, node)
662
- nsource = obj.file || source
663
- Puppet.info "Found %s in %s" % [node, nsource]
664
- return obj
665
- end
595
+
596
+ method = "nodesearch_%s" % @nodesource
597
+ # Do an inverse sort on the length, so the longest match always
598
+ # wins
599
+ nodes.sort { |a,b| b.length <=> a.length }.each do |node|
600
+ node = node.to_s if node.is_a?(Symbol)
601
+ if obj = self.send(method, node)
602
+ if obj.is_a?(AST::Node)
603
+ nsource = obj.file
604
+ else
605
+ nsource = obj.source
666
606
  end
607
+ Puppet.info "Found %s in %s" % [node, nsource]
608
+ return obj
667
609
  end
668
610
  end
669
611
 
@@ -699,41 +641,51 @@ class Puppet::Parser::Interpreter
699
641
  return nil
700
642
  end
701
643
 
702
- if output =~ /\A\s+\Z/ # all whitespace
703
- puts "empty response for %s" % name
644
+ if output =~ /\A\s*\Z/ # all whitespace
645
+ Puppet.debug "Empty response for %s from external node source" % name
704
646
  return nil
705
647
  end
706
-
707
- lines = output.split("\n")
708
-
709
- args = {}
710
- parent = lines[0].gsub(/\s+/, '')
711
- args[:parentnode] = parent unless parent == ""
712
-
713
- if lines[1]
714
- classes = lines[1].sub(/^\s+/,'').sub(/\s+$/,'').split(/\s+/)
715
- args[:classes] = classes unless classes.empty?
648
+
649
+ begin
650
+ result = YAML.load(output).inject({}) { |hash, data| hash[symbolize(data[0])] = data[1]; hash }
651
+ rescue => detail
652
+ raise Puppet::Error, "Could not load external node results for %s: %s" % [name, detail]
716
653
  end
717
-
718
- if args.empty?
719
- Puppet.warning "Somehow got a node with no information"
720
- return nil
654
+
655
+ node_args = {:source => "external node source", :name => name}
656
+ set = false
657
+ [:parameters, :classes].each do |param|
658
+ if value = result[param]
659
+ node_args[param] = value
660
+ set = true
661
+ end
662
+ end
663
+
664
+ if set
665
+ return NodeDef.new(node_args)
721
666
  else
722
- return gennode(name, args, Puppet[:external_nodes])
667
+ return nil
723
668
  end
724
669
  end
725
670
 
726
671
  # Look for our node in ldap.
727
672
  def nodesearch_ldap(node)
728
- parent, classes = ldapsearch(node)
729
- if parent or classes
730
- args = {}
731
- args[:classes] = classes if classes
732
- args[:parentnode] = parent if parent
733
- return gennode(node, args, "ldap")
734
- else
673
+ unless ary = ldapsearch(node)
735
674
  return nil
736
675
  end
676
+ parent, classes, parameters = ary
677
+
678
+ while parent
679
+ parent, tmpclasses, tmpparams = ldapsearch(parent)
680
+ classes += tmpclasses if tmpclasses
681
+ tmpparams.each do |param, value|
682
+ # Specifically test for whether it's set, so false values are handled
683
+ # correctly.
684
+ parameters[param] = value unless parameters.include?(param)
685
+ end
686
+ end
687
+
688
+ return NodeDef.new(:name => node, :classes => classes, :source => "ldap", :parameters => parameters)
737
689
  end
738
690
 
739
691
  def parsedate
@@ -746,15 +698,13 @@ class Puppet::Parser::Interpreter
746
698
  # We have to leave this for after initialization because there
747
699
  # seems to be a problem keeping ldap open after a fork.
748
700
  unless @setup
749
- @nodesources.each { |source|
750
- method = "setup_%s" % source.to_s
751
- if respond_to? method
752
- exceptwrap :type => Puppet::Error,
753
- :message => "Could not set up node source %s" % source do
754
- self.send(method)
755
- end
701
+ method = "setup_%s" % @nodesource.to_s
702
+ if respond_to? method
703
+ exceptwrap :type => Puppet::Error,
704
+ :message => "Could not set up node source %s" % @nodesource do
705
+ self.send(method)
756
706
  end
757
- }
707
+ end
758
708
  end
759
709
  parsefiles()
760
710
 
@@ -893,4 +843,4 @@ class Puppet::Parser::Interpreter
893
843
  end
894
844
  end
895
845
 
896
- # $Id: interpreter.rb 2432 2007-04-30 15:38:06Z luke $
846
+ # $Id: interpreter.rb 2626 2007-06-19 01:58:49Z luke $