puppet 0.18.4 → 0.22.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (673) hide show
  1. data/CHANGELOG +288 -0
  2. data/README +2 -2
  3. data/Rakefile +78 -5
  4. data/bin/puppet +28 -36
  5. data/bin/puppetca +81 -38
  6. data/bin/puppetd +65 -62
  7. data/bin/puppetdoc +409 -140
  8. data/bin/puppetmasterd +59 -47
  9. data/bin/puppetrun +38 -23
  10. data/conf/freebsd/puppetd +26 -0
  11. data/conf/freebsd/puppetmasterd +26 -0
  12. data/conf/gentoo/conf.d/puppet +5 -0
  13. data/conf/gentoo/conf.d/puppetmaster +12 -0
  14. data/conf/gentoo/init.d/puppet +38 -0
  15. data/conf/gentoo/init.d/puppetmaster +50 -0
  16. data/conf/gentoo/puppet/fileserver.conf +12 -0
  17. data/conf/gentoo/puppet/puppetca.conf +29 -0
  18. data/conf/gentoo/puppet/puppetd.conf +29 -0
  19. data/conf/gentoo/puppet/puppetmasterd.conf +29 -0
  20. data/conf/redhat/client.init +10 -5
  21. data/conf/redhat/client.sysconfig +1 -1
  22. data/conf/redhat/fileserver.conf +2 -2
  23. data/conf/redhat/logrotate +1 -1
  24. data/conf/redhat/no-lockdir.patch +13 -0
  25. data/conf/redhat/puppet.spec +65 -8
  26. data/conf/redhat/puppetd.conf +0 -4
  27. data/conf/redhat/server.init +3 -6
  28. data/conf/solaris/pkginfo +1 -1
  29. data/conf/solaris/smf/svc-puppetd +2 -2
  30. data/conf/suse/client.init +142 -0
  31. data/conf/suse/puppet.spec +221 -0
  32. data/conf/suse/server.init +162 -0
  33. data/examples/code/mac_automount.pp +16 -0
  34. data/examples/root/bin/sleeper +3 -5
  35. data/examples/root/etc/init.d/sleeper +8 -2
  36. data/examples/root/etc/puppet/fileserver.conf +12 -2
  37. data/examples/root/etc/puppet/namespaceauth.conf +20 -0
  38. data/examples/root/etc/puppet/puppetd.conf +4 -0
  39. data/examples/root/etc/puppet/puppetmasterd.conf +6 -9
  40. data/examples/root/etc/puppet/tagmail.conf +1 -0
  41. data/ext/emacs/puppet-mode.el +46 -1
  42. data/ext/logcheck/puppet +15 -0
  43. data/ext/module_puppet +15 -23
  44. data/ext/vim/puppet.vim +4 -2
  45. data/install.rb +2 -1
  46. data/lib/puppet.rb +76 -207
  47. data/lib/puppet/configuration.rb +331 -0
  48. data/lib/puppet/daemon.rb +63 -246
  49. data/lib/puppet/dsl.rb +371 -0
  50. data/lib/puppet/element.rb +8 -26
  51. data/lib/puppet/error.rb +54 -0
  52. data/lib/puppet/event.rb +8 -243
  53. data/lib/puppet/{base64.rb → external/base64.rb} +0 -0
  54. data/lib/puppet/external/event-loop.rb +1 -0
  55. data/lib/puppet/{event-loop → external/event-loop}/better-definers.rb +0 -0
  56. data/lib/puppet/{event-loop → external/event-loop}/event-loop.rb +2 -2
  57. data/lib/puppet/{event-loop → external/event-loop}/signal-system.rb +1 -1
  58. data/lib/puppet/external/gratr.rb +33 -0
  59. data/lib/puppet/external/gratr/adjacency_graph.rb +257 -0
  60. data/lib/puppet/external/gratr/base.rb +34 -0
  61. data/lib/puppet/external/gratr/biconnected.rb +116 -0
  62. data/lib/puppet/external/gratr/chinese_postman.rb +123 -0
  63. data/lib/puppet/external/gratr/common.rb +73 -0
  64. data/lib/puppet/external/gratr/comparability.rb +92 -0
  65. data/lib/puppet/external/gratr/digraph.rb +116 -0
  66. data/lib/puppet/external/gratr/digraph_distance.rb +185 -0
  67. data/lib/puppet/external/gratr/dot.rb +90 -0
  68. data/lib/puppet/external/gratr/edge.rb +145 -0
  69. data/lib/puppet/external/gratr/graph.rb +303 -0
  70. data/lib/puppet/external/gratr/graph_api.rb +83 -0
  71. data/lib/puppet/external/gratr/import.rb +44 -0
  72. data/lib/puppet/external/gratr/labels.rb +90 -0
  73. data/lib/puppet/external/gratr/maximum_flow.rb +64 -0
  74. data/lib/puppet/external/gratr/rdot.rb +327 -0
  75. data/lib/puppet/external/gratr/search.rb +409 -0
  76. data/lib/puppet/external/gratr/strong_components.rb +127 -0
  77. data/lib/puppet/external/gratr/undirected_graph.rb +153 -0
  78. data/lib/puppet/{lock.rb → external/lock.rb} +1 -1
  79. data/lib/puppet/feature/base.rb +20 -0
  80. data/lib/puppet/feature/rails.rb +52 -0
  81. data/lib/puppet/metatype/attributes.rb +719 -0
  82. data/lib/puppet/metatype/closure.rb +111 -0
  83. data/lib/puppet/metatype/container.rb +94 -0
  84. data/lib/puppet/metatype/evaluation.rb +118 -0
  85. data/lib/puppet/metatype/instances.rb +261 -0
  86. data/lib/puppet/metatype/manager.rb +169 -0
  87. data/lib/puppet/metatype/metaparams.rb +409 -0
  88. data/lib/puppet/metatype/providers.rb +260 -0
  89. data/lib/puppet/metatype/relationships.rb +116 -0
  90. data/lib/puppet/metatype/schedules.rb +39 -0
  91. data/lib/puppet/metatype/tags.rb +39 -0
  92. data/lib/puppet/modules.rb +113 -0
  93. data/lib/puppet/network/authconfig.rb +168 -0
  94. data/lib/puppet/network/authorization.rb +84 -0
  95. data/lib/puppet/network/authstore.rb +293 -0
  96. data/lib/puppet/network/client.rb +187 -0
  97. data/lib/puppet/network/client/ca.rb +56 -0
  98. data/lib/puppet/network/client/dipper.rb +81 -0
  99. data/lib/puppet/network/client/file.rb +7 -0
  100. data/lib/puppet/network/client/logger.rb +6 -0
  101. data/lib/puppet/network/client/master.rb +644 -0
  102. data/lib/puppet/{client → network/client}/proxy.rb +3 -3
  103. data/lib/puppet/{client/reporter.rb → network/client/report.rb} +4 -7
  104. data/lib/puppet/{client/pelement.rb → network/client/resource.rb} +6 -19
  105. data/lib/puppet/network/client/runner.rb +13 -0
  106. data/lib/puppet/network/client/status.rb +5 -0
  107. data/lib/puppet/network/client_request.rb +32 -0
  108. data/lib/puppet/network/handler.rb +33 -0
  109. data/lib/puppet/{server → network/handler}/ca.rb +5 -6
  110. data/lib/puppet/network/handler/filebucket.rb +180 -0
  111. data/lib/puppet/{server → network/handler}/fileserver.rb +277 -219
  112. data/lib/puppet/{server → network/handler}/logger.rb +3 -5
  113. data/lib/puppet/{server → network/handler}/master.rb +42 -8
  114. data/lib/puppet/network/handler/report.rb +158 -0
  115. data/lib/puppet/network/handler/resource.rb +190 -0
  116. data/lib/puppet/{server → network/handler}/runner.rb +17 -18
  117. data/lib/puppet/network/handler/status.rb +13 -0
  118. data/lib/puppet/network/rights.rb +74 -0
  119. data/lib/puppet/network/server.rb +5 -0
  120. data/lib/puppet/network/server/mongrel.rb +138 -0
  121. data/lib/puppet/network/server/webrick.rb +153 -0
  122. data/lib/puppet/network/xmlrpc/client.rb +129 -0
  123. data/lib/puppet/network/xmlrpc/processor.rb +91 -0
  124. data/lib/puppet/network/xmlrpc/server.rb +20 -0
  125. data/lib/puppet/network/xmlrpc/webrick_servlet.rb +121 -0
  126. data/lib/puppet/parameter.rb +390 -346
  127. data/lib/puppet/parser/ast.rb +116 -147
  128. data/lib/puppet/parser/ast/astarray.rb +17 -33
  129. data/lib/puppet/parser/ast/branch.rb +2 -0
  130. data/lib/puppet/parser/ast/caseopt.rb +7 -12
  131. data/lib/puppet/parser/ast/casestatement.rb +23 -32
  132. data/lib/puppet/parser/ast/collection.rb +19 -80
  133. data/lib/puppet/parser/ast/collexpr.rb +81 -0
  134. data/lib/puppet/parser/ast/component.rb +160 -89
  135. data/lib/puppet/parser/ast/else.rb +30 -0
  136. data/lib/puppet/parser/ast/function.rb +9 -2
  137. data/lib/puppet/parser/ast/hostclass.rb +47 -131
  138. data/lib/puppet/parser/ast/ifstatement.rb +43 -0
  139. data/lib/puppet/parser/ast/leaf.rb +10 -21
  140. data/lib/puppet/parser/ast/node.rb +32 -79
  141. data/lib/puppet/parser/ast/resourcedef.rb +222 -0
  142. data/lib/puppet/parser/ast/{typedefaults.rb → resourcedefaults.rb} +10 -16
  143. data/lib/puppet/parser/ast/resourceoverride.rb +62 -0
  144. data/lib/puppet/parser/ast/{objectparam.rb → resourceparam.rb} +12 -6
  145. data/lib/puppet/parser/ast/resourceref.rb +44 -0
  146. data/lib/puppet/parser/ast/selector.rb +16 -8
  147. data/lib/puppet/parser/ast/tag.rb +3 -1
  148. data/lib/puppet/parser/ast/vardef.rb +8 -12
  149. data/lib/puppet/parser/collector.rb +181 -0
  150. data/lib/puppet/parser/functions.rb +191 -36
  151. data/lib/puppet/parser/interpreter.rb +802 -380
  152. data/lib/puppet/parser/lexer.rb +86 -19
  153. data/lib/puppet/parser/parser.rb +1123 -960
  154. data/lib/puppet/parser/resource.rb +353 -0
  155. data/lib/puppet/parser/resource/param.rb +57 -0
  156. data/lib/puppet/parser/resource/reference.rb +71 -0
  157. data/lib/puppet/parser/scope.rb +573 -1000
  158. data/lib/puppet/parser/templatewrapper.rb +54 -0
  159. data/lib/puppet/pgraph.rb +208 -0
  160. data/lib/puppet/propertychange.rb +143 -0
  161. data/lib/puppet/provider.rb +302 -0
  162. data/lib/puppet/provider/cron/crontab.rb +187 -0
  163. data/lib/puppet/provider/group/groupadd.rb +29 -0
  164. data/lib/puppet/provider/group/netinfo.rb +12 -0
  165. data/lib/puppet/provider/group/pw.rb +31 -0
  166. data/lib/puppet/provider/host/netinfo.rb +18 -0
  167. data/lib/puppet/provider/host/parsed.rb +73 -0
  168. data/lib/puppet/provider/mount.rb +57 -0
  169. data/lib/puppet/provider/mount/netinfo.rb +38 -0
  170. data/lib/puppet/provider/mount/parsed.rb +37 -0
  171. data/lib/puppet/provider/nameservice.rb +344 -0
  172. data/lib/puppet/provider/nameservice/netinfo.rb +210 -0
  173. data/lib/puppet/provider/nameservice/objectadd.rb +45 -0
  174. data/lib/puppet/provider/nameservice/pw.rb +22 -0
  175. data/lib/puppet/provider/package/apple.rb +53 -0
  176. data/lib/puppet/provider/package/apt.rb +119 -0
  177. data/lib/puppet/provider/package/aptitude.rb +30 -0
  178. data/lib/puppet/provider/package/aptrpm.rb +79 -0
  179. data/lib/puppet/provider/package/blastwave.rb +114 -0
  180. data/lib/puppet/provider/package/darwinport.rb +88 -0
  181. data/lib/puppet/provider/package/dpkg.rb +109 -0
  182. data/lib/puppet/provider/package/freebsd.rb +43 -0
  183. data/lib/puppet/provider/package/gem.rb +104 -0
  184. data/lib/puppet/provider/package/openbsd.rb +93 -0
  185. data/lib/puppet/provider/package/pkgdmg.rb +119 -0
  186. data/lib/puppet/provider/package/portage.rb +112 -0
  187. data/lib/puppet/provider/package/ports.rb +94 -0
  188. data/lib/puppet/provider/package/rpm.rb +125 -0
  189. data/lib/puppet/provider/package/rug.rb +53 -0
  190. data/lib/puppet/provider/package/sun.rb +168 -0
  191. data/lib/puppet/provider/package/sunfreeware.rb +9 -0
  192. data/lib/puppet/provider/package/up2date.rb +45 -0
  193. data/lib/puppet/provider/package/yum.rb +54 -0
  194. data/lib/puppet/provider/parsedfile.rb +342 -0
  195. data/lib/puppet/provider/port/parsed.rb +174 -0
  196. data/lib/puppet/provider/service/base.rb +136 -0
  197. data/lib/puppet/provider/service/debian.rb +32 -0
  198. data/lib/puppet/provider/service/gentoo.rb +49 -0
  199. data/lib/puppet/{type → provider}/service/init.rb +42 -40
  200. data/lib/puppet/provider/service/redhat.rb +59 -0
  201. data/lib/puppet/{type → provider}/service/smf.rb +24 -13
  202. data/lib/puppet/provider/sshkey/parsed.rb +36 -0
  203. data/lib/puppet/provider/user/netinfo.rb +106 -0
  204. data/lib/puppet/provider/user/pw.rb +41 -0
  205. data/lib/puppet/provider/user/useradd.rb +67 -0
  206. data/lib/puppet/provider/zone/solaris.rb +208 -0
  207. data/lib/puppet/rails.rb +102 -66
  208. data/lib/puppet/rails/database/001_add_indexes.rb +38 -0
  209. data/lib/puppet/rails/database/schema.rb +89 -0
  210. data/lib/puppet/rails/external/tagging/acts_as_taggable.rb +62 -0
  211. data/lib/puppet/rails/external/tagging/init.rb +5 -0
  212. data/lib/puppet/rails/external/tagging/tag.rb +50 -0
  213. data/lib/puppet/rails/external/tagging/tagging.rb +12 -0
  214. data/lib/puppet/rails/fact_name.rb +7 -0
  215. data/lib/puppet/rails/fact_value.rb +5 -0
  216. data/lib/puppet/rails/host.rb +95 -46
  217. data/lib/puppet/rails/param_name.rb +28 -0
  218. data/lib/puppet/rails/param_value.rb +5 -0
  219. data/lib/puppet/rails/puppet_class.rb +9 -0
  220. data/lib/puppet/rails/resource.rb +95 -0
  221. data/lib/puppet/rails/source_file.rb +5 -0
  222. data/lib/puppet/relationship.rb +63 -0
  223. data/lib/puppet/reports/log.rb +14 -0
  224. data/lib/puppet/reports/rrdgraph.rb +114 -10
  225. data/lib/puppet/reports/store.rb +64 -0
  226. data/lib/puppet/reports/tagmail.rb +144 -71
  227. data/lib/puppet/sslcertificates.rb +38 -5
  228. data/lib/puppet/sslcertificates/ca.rb +142 -37
  229. data/lib/puppet/sslcertificates/certificate.rb +3 -3
  230. data/lib/puppet/sslcertificates/inventory.rb +53 -0
  231. data/lib/puppet/sslcertificates/support.rb +128 -0
  232. data/lib/puppet/transaction.rb +568 -189
  233. data/lib/puppet/transaction/report.rb +14 -3
  234. data/lib/puppet/transportable.rb +18 -10
  235. data/lib/puppet/type.rb +279 -2299
  236. data/lib/puppet/type/component.rb +63 -63
  237. data/lib/puppet/type/cron.rb +294 -710
  238. data/lib/puppet/type/exec.rb +185 -129
  239. data/lib/puppet/type/group.rb +38 -89
  240. data/lib/puppet/type/host.rb +110 -0
  241. data/lib/puppet/type/mount.rb +189 -0
  242. data/lib/puppet/type/notify.rb +47 -0
  243. data/lib/puppet/type/package.rb +129 -257
  244. data/lib/puppet/type/parsedtype.rb +172 -297
  245. data/lib/puppet/type/pfile.rb +540 -319
  246. data/lib/puppet/type/pfile/checksum.rb +103 -76
  247. data/lib/puppet/type/pfile/content.rb +16 -10
  248. data/lib/puppet/type/pfile/ensure.rb +52 -34
  249. data/lib/puppet/type/pfile/group.rb +25 -18
  250. data/lib/puppet/type/pfile/mode.rb +7 -4
  251. data/lib/puppet/type/pfile/{uid.rb → owner.rb} +21 -17
  252. data/lib/puppet/type/pfile/source.rb +119 -124
  253. data/lib/puppet/type/pfile/target.rb +29 -45
  254. data/lib/puppet/type/pfile/type.rb +2 -2
  255. data/lib/puppet/type/pfilebucket.rb +18 -14
  256. data/lib/puppet/type/port.rb +121 -0
  257. data/lib/puppet/type/property.rb +530 -0
  258. data/lib/puppet/type/resources.rb +150 -0
  259. data/lib/puppet/type/schedule.rb +38 -22
  260. data/lib/puppet/type/service.rb +70 -326
  261. data/lib/puppet/type/sshkey.rb +76 -0
  262. data/lib/puppet/type/tidy.rb +197 -97
  263. data/lib/puppet/type/user.rb +107 -183
  264. data/lib/puppet/type/yumrepo.rb +53 -34
  265. data/lib/puppet/type/zone.rb +55 -208
  266. data/lib/puppet/util.rb +239 -201
  267. data/lib/puppet/util/autoload.rb +107 -0
  268. data/lib/puppet/util/classgen.rb +208 -0
  269. data/lib/puppet/{config.rb → util/config.rb} +102 -54
  270. data/lib/puppet/util/docs.rb +104 -0
  271. data/lib/puppet/util/errors.rb +55 -0
  272. data/lib/puppet/util/execution.rb +22 -0
  273. data/lib/puppet/util/feature.rb +76 -0
  274. data/lib/puppet/util/fileparsing.rb +380 -0
  275. data/lib/puppet/util/filetype.rb +300 -0
  276. data/lib/puppet/util/graph.rb +39 -0
  277. data/lib/puppet/util/inifile.rb +209 -0
  278. data/lib/puppet/util/loadedfile.rb +71 -0
  279. data/lib/puppet/util/log.rb +549 -0
  280. data/lib/puppet/util/logging.rb +20 -0
  281. data/lib/puppet/util/metaid.rb +22 -0
  282. data/lib/puppet/util/methodhelper.rb +37 -0
  283. data/lib/puppet/util/metric.rb +160 -0
  284. data/lib/puppet/util/package.rb +31 -0
  285. data/lib/puppet/util/pidlock.rb +68 -0
  286. data/lib/puppet/util/plist.rb +24 -0
  287. data/lib/puppet/util/plist/generator.rb +226 -0
  288. data/lib/puppet/util/plist/parser.rb +227 -0
  289. data/lib/puppet/util/posix.rb +87 -0
  290. data/lib/puppet/util/provider_features.rb +170 -0
  291. data/lib/puppet/util/rails/collection_merger.rb +42 -0
  292. data/lib/puppet/util/storage.rb +103 -0
  293. data/lib/puppet/util/subclass_loader.rb +83 -0
  294. data/lib/puppet/util/suidmanager.rb +86 -0
  295. data/lib/puppet/util/variables.rb +39 -0
  296. data/lib/puppet/util/warnings.rb +15 -0
  297. data/test/Rakefile +97 -0
  298. data/test/certmgr/ca.rb +81 -0
  299. data/test/certmgr/certmgr.rb +77 -50
  300. data/test/certmgr/inventory.rb +79 -0
  301. data/test/certmgr/support.rb +81 -0
  302. data/test/executables/filebucket.rb +49 -0
  303. data/test/executables/puppetbin.rb +28 -12
  304. data/test/executables/puppetca.rb +75 -54
  305. data/test/executables/puppetd.rb +10 -13
  306. data/test/executables/puppetmasterd.rb +12 -17
  307. data/test/executables/puppetmodule.rb +18 -17
  308. data/test/language/ast.rb +242 -798
  309. data/test/language/ast/casestatement.rb +104 -0
  310. data/test/language/ast/component.rb +133 -0
  311. data/test/language/ast/hostclass.rb +162 -0
  312. data/test/language/ast/selector.rb +62 -0
  313. data/test/language/ast/variable.rb +31 -0
  314. data/test/language/collector.rb +369 -0
  315. data/test/language/functions.rb +305 -18
  316. data/test/language/interpreter.rb +894 -125
  317. data/test/language/lexer.rb +98 -12
  318. data/test/language/node.rb +37 -53
  319. data/test/language/parser.rb +455 -148
  320. data/test/language/resource.rb +535 -0
  321. data/test/language/scope.rb +451 -561
  322. data/test/language/snippets.rb +101 -111
  323. data/test/language/transportable.rb +6 -8
  324. data/test/lib/mocha.rb +19 -0
  325. data/test/lib/mocha/any_instance_method.rb +35 -0
  326. data/test/lib/mocha/auto_verify.rb +113 -0
  327. data/test/lib/mocha/central.rb +35 -0
  328. data/test/lib/mocha/class_method.rb +62 -0
  329. data/test/lib/mocha/expectation.rb +295 -0
  330. data/test/lib/mocha/expectation_error.rb +6 -0
  331. data/test/lib/mocha/infinite_range.rb +27 -0
  332. data/test/lib/mocha/inspect.rb +37 -0
  333. data/test/lib/mocha/instance_method.rb +8 -0
  334. data/test/lib/mocha/metaclass.rb +7 -0
  335. data/test/lib/mocha/mock.rb +20 -0
  336. data/test/lib/mocha/mock_methods.rb +122 -0
  337. data/test/lib/mocha/object.rb +100 -0
  338. data/test/lib/mocha/pretty_parameters.rb +28 -0
  339. data/test/lib/mocha/setup_and_teardown.rb +23 -0
  340. data/test/lib/mocha/standalone.rb +30 -0
  341. data/test/lib/mocha/test_case_adapter.rb +49 -0
  342. data/test/lib/mocha_standalone.rb +2 -0
  343. data/test/lib/puppettest.rb +294 -0
  344. data/test/lib/puppettest/certificates.rb +61 -0
  345. data/test/lib/puppettest/exetest.rb +123 -0
  346. data/test/lib/puppettest/fakes.rb +194 -0
  347. data/test/lib/puppettest/fileparsing.rb +33 -0
  348. data/test/lib/puppettest/filetesting.rb +231 -0
  349. data/test/lib/puppettest/graph.rb +41 -0
  350. data/test/lib/puppettest/parsertesting.rb +392 -0
  351. data/test/lib/puppettest/railstesting.rb +56 -0
  352. data/test/lib/puppettest/reporttesting.rb +19 -0
  353. data/test/lib/puppettest/resourcetesting.rb +73 -0
  354. data/test/lib/puppettest/servertest.rb +72 -0
  355. data/test/lib/puppettest/support.rb +8 -0
  356. data/test/lib/puppettest/support/assertions.rb +101 -0
  357. data/test/lib/puppettest/support/helpers.rb +23 -0
  358. data/test/lib/puppettest/support/resources.rb +37 -0
  359. data/test/lib/puppettest/support/utils.rb +160 -0
  360. data/test/lib/puppettest/testcase.rb +48 -0
  361. data/test/lib/rake/puppet_test_loader.rb +17 -0
  362. data/test/lib/rake/puppet_testtask.rb +17 -0
  363. data/test/lib/spec.rb +8 -0
  364. data/test/lib/spec/callback.rb +11 -0
  365. data/test/lib/spec/callback/callback_container.rb +60 -0
  366. data/test/lib/spec/callback/extensions/module.rb +24 -0
  367. data/test/lib/spec/callback/extensions/object.rb +37 -0
  368. data/test/lib/spec/deprecated.rb +3 -0
  369. data/test/lib/spec/expectations.rb +59 -0
  370. data/test/lib/spec/expectations/differs/default.rb +62 -0
  371. data/test/lib/spec/expectations/errors.rb +6 -0
  372. data/test/lib/spec/expectations/extensions.rb +3 -0
  373. data/test/lib/spec/expectations/extensions/object.rb +109 -0
  374. data/test/lib/spec/expectations/extensions/proc.rb +57 -0
  375. data/test/lib/spec/expectations/extensions/string_and_symbol.rb +17 -0
  376. data/test/lib/spec/expectations/handler.rb +47 -0
  377. data/test/lib/spec/expectations/should.rb +5 -0
  378. data/test/lib/spec/expectations/should/base.rb +64 -0
  379. data/test/lib/spec/expectations/should/change.rb +69 -0
  380. data/test/lib/spec/expectations/should/have.rb +128 -0
  381. data/test/lib/spec/expectations/should/not.rb +74 -0
  382. data/test/lib/spec/expectations/should/should.rb +81 -0
  383. data/test/lib/spec/expectations/sugar.rb +47 -0
  384. data/test/lib/spec/matchers.rb +160 -0
  385. data/test/lib/spec/matchers/be.rb +161 -0
  386. data/test/lib/spec/matchers/be_close.rb +37 -0
  387. data/test/lib/spec/matchers/change.rb +120 -0
  388. data/test/lib/spec/matchers/eql.rb +43 -0
  389. data/test/lib/spec/matchers/equal.rb +43 -0
  390. data/test/lib/spec/matchers/has.rb +44 -0
  391. data/test/lib/spec/matchers/have.rb +140 -0
  392. data/test/lib/spec/matchers/include.rb +50 -0
  393. data/test/lib/spec/matchers/match.rb +41 -0
  394. data/test/lib/spec/matchers/raise_error.rb +100 -0
  395. data/test/lib/spec/matchers/respond_to.rb +35 -0
  396. data/test/lib/spec/matchers/satisfy.rb +47 -0
  397. data/test/lib/spec/matchers/throw_symbol.rb +75 -0
  398. data/test/lib/spec/mocks.rb +232 -0
  399. data/test/lib/spec/mocks/argument_expectation.rb +132 -0
  400. data/test/lib/spec/mocks/error_generator.rb +85 -0
  401. data/test/lib/spec/mocks/errors.rb +10 -0
  402. data/test/lib/spec/mocks/extensions/object.rb +3 -0
  403. data/test/lib/spec/mocks/message_expectation.rb +231 -0
  404. data/test/lib/spec/mocks/methods.rb +40 -0
  405. data/test/lib/spec/mocks/mock.rb +26 -0
  406. data/test/lib/spec/mocks/mock_handler.rb +166 -0
  407. data/test/lib/spec/mocks/order_group.rb +29 -0
  408. data/test/lib/spec/rake/spectask.rb +173 -0
  409. data/test/lib/spec/rake/verify_rcov.rb +47 -0
  410. data/test/lib/spec/runner.rb +132 -0
  411. data/test/lib/spec/runner/backtrace_tweaker.rb +55 -0
  412. data/test/lib/spec/runner/command_line.rb +34 -0
  413. data/test/lib/spec/runner/context.rb +154 -0
  414. data/test/lib/spec/runner/context_eval.rb +142 -0
  415. data/test/lib/spec/runner/context_runner.rb +55 -0
  416. data/test/lib/spec/runner/drb_command_line.rb +21 -0
  417. data/test/lib/spec/runner/execution_context.rb +17 -0
  418. data/test/lib/spec/runner/extensions/kernel.rb +17 -0
  419. data/test/lib/spec/runner/extensions/object.rb +32 -0
  420. data/test/lib/spec/runner/formatter.rb +5 -0
  421. data/test/lib/spec/runner/formatter/base_text_formatter.rb +118 -0
  422. data/test/lib/spec/runner/formatter/html_formatter.rb +219 -0
  423. data/test/lib/spec/runner/formatter/progress_bar_formatter.rb +27 -0
  424. data/test/lib/spec/runner/formatter/rdoc_formatter.rb +22 -0
  425. data/test/lib/spec/runner/formatter/specdoc_formatter.rb +23 -0
  426. data/test/lib/spec/runner/heckle_runner.rb +71 -0
  427. data/test/lib/spec/runner/heckle_runner_win.rb +10 -0
  428. data/test/lib/spec/runner/option_parser.rb +224 -0
  429. data/test/lib/spec/runner/reporter.rb +105 -0
  430. data/test/lib/spec/runner/spec_matcher.rb +25 -0
  431. data/test/lib/spec/runner/spec_parser.rb +41 -0
  432. data/test/lib/spec/runner/spec_should_raise_handler.rb +74 -0
  433. data/test/lib/spec/runner/specification.rb +114 -0
  434. data/test/lib/spec/translator.rb +87 -0
  435. data/test/lib/spec/version.rb +30 -0
  436. data/test/lib/stubba.rb +2 -0
  437. data/test/network/authconfig.rb +72 -0
  438. data/test/network/authorization.rb +138 -0
  439. data/test/network/authstore.rb +450 -0
  440. data/test/network/client/ca.rb +38 -0
  441. data/test/{client → network/client}/client.rb +107 -24
  442. data/test/network/client/dipper.rb +35 -0
  443. data/test/network/client/master.rb +627 -0
  444. data/test/{client/pelement.rb → network/client/resource.rb} +13 -29
  445. data/test/network/client_request.rb +39 -0
  446. data/test/network/daemon.rb +71 -0
  447. data/test/{server → network/handler}/bucket.rb +103 -27
  448. data/test/{server → network/handler}/ca.rb +14 -19
  449. data/test/{server → network/handler}/fileserver.rb +443 -68
  450. data/test/network/handler/handler.rb +64 -0
  451. data/test/{server → network/handler}/logger.rb +26 -26
  452. data/test/network/handler/master.rb +352 -0
  453. data/test/network/handler/report.rb +185 -0
  454. data/test/{server/pelement.rb → network/handler/resource.rb} +25 -38
  455. data/test/{server → network/handler}/runner.rb +17 -16
  456. data/test/network/rights.rb +38 -0
  457. data/test/network/server/webrick.rb +140 -0
  458. data/test/network/xmlrpc/client.rb +68 -0
  459. data/test/network/xmlrpc/processor.rb +80 -0
  460. data/test/network/xmlrpc/server.rb +28 -0
  461. data/test/network/xmlrpc/webrick_servlet.rb +26 -0
  462. data/test/other/dsl.rb +218 -0
  463. data/test/other/events.rb +22 -15
  464. data/test/other/overrides.rb +9 -14
  465. data/test/other/pgraph.rb +289 -0
  466. data/test/other/propertychange.rb +142 -0
  467. data/test/other/provider.rb +162 -0
  468. data/test/other/puppet.rb +63 -10
  469. data/test/other/relationship.rb +74 -0
  470. data/test/other/relationships.rb +199 -123
  471. data/test/other/report.rb +152 -23
  472. data/test/other/transactions.rb +824 -78
  473. data/test/puppet/conffiles.rb +16 -11
  474. data/test/puppet/defaults.rb +7 -10
  475. data/test/puppet/{error.rb → errortest.rb} +5 -8
  476. data/test/puppet/modules.rb +58 -0
  477. data/test/puppet/tc_suidmanager.rb +107 -0
  478. data/test/rails/host.rb +177 -0
  479. data/test/rails/rails.rb +27 -0
  480. data/test/rails/railsparameter.rb +62 -0
  481. data/test/rails/railsresource.rb +100 -0
  482. data/test/ral/manager/attributes.rb +296 -0
  483. data/test/ral/manager/manager.rb +55 -0
  484. data/test/ral/manager/provider.rb +54 -0
  485. data/test/ral/manager/type.rb +837 -0
  486. data/test/ral/providers/cron/crontab.rb +346 -0
  487. data/test/ral/providers/group.rb +252 -0
  488. data/test/ral/providers/host/netinfo.rb +58 -0
  489. data/test/ral/providers/host/parsed.rb +226 -0
  490. data/test/ral/providers/mount/netinfo.rb +80 -0
  491. data/test/ral/providers/mount/parsed.rb +223 -0
  492. data/test/ral/providers/nameservice.rb +33 -0
  493. data/test/ral/providers/package.rb +253 -0
  494. data/test/ral/providers/package/apt.rb +89 -0
  495. data/test/ral/providers/package/aptitude.rb +69 -0
  496. data/test/ral/providers/package/aptrpm.rb +89 -0
  497. data/test/ral/providers/package/dpkg.rb +64 -0
  498. data/test/ral/providers/parsedfile.rb +668 -0
  499. data/test/ral/providers/parsedport.rb +233 -0
  500. data/test/ral/providers/provider.rb +423 -0
  501. data/test/{types → ral/providers}/service.rb +20 -121
  502. data/test/ral/providers/service/base.rb +75 -0
  503. data/test/ral/providers/sshkey/parsed.rb +111 -0
  504. data/test/ral/providers/user.rb +567 -0
  505. data/test/ral/providers/user/useradd.rb +250 -0
  506. data/test/ral/types/basic.rb +90 -0
  507. data/test/ral/types/component.rb +113 -0
  508. data/test/ral/types/cron.rb +480 -0
  509. data/test/{types → ral/types}/exec.rb +278 -82
  510. data/test/ral/types/file.rb +1799 -0
  511. data/test/ral/types/file/target.rb +363 -0
  512. data/test/{types → ral/types}/filebucket.rb +15 -17
  513. data/test/{types → ral/types}/fileignoresource.rb +9 -15
  514. data/test/ral/types/filesources.rb +1046 -0
  515. data/test/ral/types/group.rb +169 -0
  516. data/test/ral/types/host.rb +155 -0
  517. data/test/ral/types/mount.rb +312 -0
  518. data/test/ral/types/package.rb +85 -0
  519. data/test/ral/types/parameter.rb +172 -0
  520. data/test/ral/types/port.rb +148 -0
  521. data/test/ral/types/property.rb +343 -0
  522. data/test/ral/types/resources.rb +221 -0
  523. data/test/{types → ral/types}/schedule.rb +34 -12
  524. data/test/ral/types/service.rb +37 -0
  525. data/test/{types → ral/types}/sshkey.rb +75 -65
  526. data/test/ral/types/tidy.rb +240 -0
  527. data/test/ral/types/user.rb +493 -0
  528. data/test/{types → ral/types}/yumrepo.rb +7 -11
  529. data/test/{types → ral/types}/zone.rb +45 -45
  530. data/test/tagging/tagging.rb +17 -26
  531. data/test/util/autoload.rb +130 -0
  532. data/test/util/classgen.rb +227 -0
  533. data/test/{other → util}/config.rb +373 -113
  534. data/test/util/execution.rb +34 -0
  535. data/test/util/features.rb +94 -0
  536. data/test/util/fileparsing.rb +677 -0
  537. data/test/{other → util}/filetype.rb +9 -12
  538. data/test/util/graph.rb +108 -0
  539. data/test/{other → util}/inifile.rb +24 -11
  540. data/test/util/loadedfile.rb +106 -0
  541. data/test/{other → util}/log.rb +96 -50
  542. data/test/{other → util}/metrics.rb +7 -17
  543. data/test/util/package.rb +27 -0
  544. data/test/util/pidlock.rb +126 -0
  545. data/test/util/posixtest.rb +173 -0
  546. data/test/util/storage.rb +123 -0
  547. data/test/util/subclass_loader.rb +100 -0
  548. data/test/util/utiltest.rb +368 -0
  549. metadata +449 -169
  550. data/examples/code/classing +0 -35
  551. data/examples/code/failers/badclassnoparam +0 -10
  552. data/examples/code/failers/badclassparam +0 -10
  553. data/examples/code/failers/badcompnoparam +0 -9
  554. data/examples/code/failers/badcompparam +0 -9
  555. data/examples/code/failers/badtypeparam +0 -3
  556. data/examples/code/failers/noobjectrvalue +0 -1
  557. data/examples/code/snippets/aliastest.pp +0 -16
  558. data/examples/code/snippets/argumentdefaults +0 -14
  559. data/examples/code/snippets/casestatement.pp +0 -58
  560. data/examples/code/snippets/classheirarchy.pp +0 -15
  561. data/examples/code/snippets/classincludes.pp +0 -17
  562. data/examples/code/snippets/classpathtest +0 -11
  563. data/examples/code/snippets/componentmetaparams.pp +0 -11
  564. data/examples/code/snippets/deepclassheirarchy.pp +0 -23
  565. data/examples/code/snippets/defineoverrides.pp +0 -17
  566. data/examples/code/snippets/dirchmod +0 -19
  567. data/examples/code/snippets/emptyclass.pp +0 -9
  568. data/examples/code/snippets/emptyexec.pp +0 -3
  569. data/examples/code/snippets/failmissingexecpath.pp +0 -13
  570. data/examples/code/snippets/falsevalues.pp +0 -3
  571. data/examples/code/snippets/filecreate +0 -11
  572. data/examples/code/snippets/implicititeration +0 -15
  573. data/examples/code/snippets/multipleinstances +0 -7
  574. data/examples/code/snippets/namevartest +0 -9
  575. data/examples/code/snippets/scopetest +0 -13
  576. data/examples/code/snippets/selectorvalues.pp +0 -42
  577. data/examples/code/snippets/simpledefaults +0 -5
  578. data/examples/code/snippets/simpleselector +0 -38
  579. data/examples/code/snippets/singleary.pp +0 -19
  580. data/examples/code/snippets/singlequote.pp +0 -11
  581. data/examples/code/snippets/singleselector.pp +0 -22
  582. data/examples/code/snippets/tag.pp +0 -9
  583. data/examples/code/snippets/tagged.pp +0 -35
  584. data/lib/puppet/client.rb +0 -177
  585. data/lib/puppet/client/ca.rb +0 -21
  586. data/lib/puppet/client/dipper.rb +0 -76
  587. data/lib/puppet/client/file.rb +0 -20
  588. data/lib/puppet/client/log.rb +0 -17
  589. data/lib/puppet/client/master.rb +0 -531
  590. data/lib/puppet/client/runner.rb +0 -17
  591. data/lib/puppet/client/status.rb +0 -7
  592. data/lib/puppet/event-loop.rb +0 -1
  593. data/lib/puppet/filetype.rb +0 -308
  594. data/lib/puppet/inifile.rb +0 -201
  595. data/lib/puppet/log.rb +0 -524
  596. data/lib/puppet/metric.rb +0 -132
  597. data/lib/puppet/networkclient.rb +0 -175
  598. data/lib/puppet/parsedfile.rb +0 -58
  599. data/lib/puppet/parser/ast/classdef.rb +0 -79
  600. data/lib/puppet/parser/ast/compdef.rb +0 -75
  601. data/lib/puppet/parser/ast/nodedef.rb +0 -73
  602. data/lib/puppet/parser/ast/objectdef.rb +0 -284
  603. data/lib/puppet/parser/ast/objectref.rb +0 -77
  604. data/lib/puppet/rails/database.rb +0 -40
  605. data/lib/puppet/rails/rails_object.rb +0 -42
  606. data/lib/puppet/rails/rails_parameter.rb +0 -5
  607. data/lib/puppet/server.rb +0 -196
  608. data/lib/puppet/server/authconfig.rb +0 -177
  609. data/lib/puppet/server/authstore.rb +0 -226
  610. data/lib/puppet/server/filebucket.rb +0 -155
  611. data/lib/puppet/server/pelement.rb +0 -188
  612. data/lib/puppet/server/report.rb +0 -184
  613. data/lib/puppet/server/rights.rb +0 -78
  614. data/lib/puppet/server/servlet.rb +0 -274
  615. data/lib/puppet/statechange.rb +0 -129
  616. data/lib/puppet/storage.rb +0 -98
  617. data/lib/puppet/type/nameservice.rb +0 -264
  618. data/lib/puppet/type/nameservice/netinfo.rb +0 -232
  619. data/lib/puppet/type/nameservice/objectadd.rb +0 -146
  620. data/lib/puppet/type/nameservice/posix.rb +0 -12
  621. data/lib/puppet/type/nameservice/pw.rb +0 -107
  622. data/lib/puppet/type/package/apple.rb +0 -41
  623. data/lib/puppet/type/package/apt.rb +0 -107
  624. data/lib/puppet/type/package/blastwave.rb +0 -136
  625. data/lib/puppet/type/package/darwinport.rb +0 -97
  626. data/lib/puppet/type/package/dpkg.rb +0 -113
  627. data/lib/puppet/type/package/freebsd.rb +0 -19
  628. data/lib/puppet/type/package/gem.rb +0 -119
  629. data/lib/puppet/type/package/openbsd.rb +0 -112
  630. data/lib/puppet/type/package/ports.rb +0 -103
  631. data/lib/puppet/type/package/rpm.rb +0 -121
  632. data/lib/puppet/type/package/sun.rb +0 -174
  633. data/lib/puppet/type/package/sunfreeware.rb +0 -7
  634. data/lib/puppet/type/package/yum.rb +0 -52
  635. data/lib/puppet/type/parsedtype/host.rb +0 -144
  636. data/lib/puppet/type/parsedtype/mount.rb +0 -271
  637. data/lib/puppet/type/parsedtype/port.rb +0 -261
  638. data/lib/puppet/type/parsedtype/sshkey.rb +0 -123
  639. data/lib/puppet/type/service/base.rb +0 -12
  640. data/lib/puppet/type/service/debian.rb +0 -46
  641. data/lib/puppet/type/service/redhat.rb +0 -38
  642. data/lib/puppet/type/state.rb +0 -393
  643. data/lib/puppet/type/symlink.rb +0 -186
  644. data/test/client/master.rb +0 -207
  645. data/test/language/rails.rb +0 -105
  646. data/test/other/parsedfile.rb +0 -58
  647. data/test/other/storage.rb +0 -100
  648. data/test/puppet/utiltest.rb +0 -299
  649. data/test/puppettest.rb +0 -1170
  650. data/test/server/authconfig.rb +0 -56
  651. data/test/server/authstore.rb +0 -218
  652. data/test/server/master.rb +0 -201
  653. data/test/server/report.rb +0 -93
  654. data/test/server/rights.rb +0 -41
  655. data/test/server/server.rb +0 -152
  656. data/test/test +0 -61
  657. data/test/types/basic.rb +0 -117
  658. data/test/types/component.rb +0 -298
  659. data/test/types/cron.rb +0 -718
  660. data/test/types/file.rb +0 -1314
  661. data/test/types/filesources.rb +0 -590
  662. data/test/types/group.rb +0 -323
  663. data/test/types/host.rb +0 -186
  664. data/test/types/mount.rb +0 -294
  665. data/test/types/package.rb +0 -538
  666. data/test/types/parameter.rb +0 -107
  667. data/test/types/port.rb +0 -201
  668. data/test/types/query.rb +0 -101
  669. data/test/types/state.rb +0 -92
  670. data/test/types/symlink.rb +0 -120
  671. data/test/types/tidy.rb +0 -102
  672. data/test/types/type.rb +0 -469
  673. data/test/types/user.rb +0 -563
@@ -3,472 +3,894 @@
3
3
  # and calls out to other objects.
4
4
 
5
5
  require 'puppet'
6
+ require 'timeout'
7
+ require 'puppet/rails'
6
8
  require 'puppet/parser/parser'
7
9
  require 'puppet/parser/scope'
8
10
 
11
+ class Puppet::Parser::Interpreter
12
+ 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
+
69
+ attr_accessor :usenodes
70
+
71
+ class << self
72
+ attr_writer :ldap
73
+ end
74
+ # just shorten the constant path a bit, using what amounts to an alias
75
+ AST = Puppet::Parser::AST
76
+
77
+ include Puppet::Util::Errors
78
+
79
+ # Create an ldap connection. This is a class method so others can call
80
+ # it and use the same variables and such.
81
+ def self.ldap
82
+ unless defined? @ldap and @ldap
83
+ if Puppet[:ldapssl]
84
+ @ldap = LDAP::SSLConn.new(Puppet[:ldapserver], Puppet[:ldapport])
85
+ elsif Puppet[:ldaptls]
86
+ @ldap = LDAP::SSLConn.new(
87
+ Puppet[:ldapserver], Puppet[:ldapport], true
88
+ )
89
+ else
90
+ @ldap = LDAP::Conn.new(Puppet[:ldapserver], Puppet[:ldapport])
91
+ end
92
+ @ldap.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
93
+ @ldap.set_option(LDAP::LDAP_OPT_REFERRALS, LDAP::LDAP_OPT_ON)
94
+ @ldap.simple_bind(Puppet[:ldapuser], Puppet[:ldappassword])
95
+ end
9
96
 
10
- module Puppet
11
- module Parser
12
- class Interpreter
13
- include Puppet::Util
14
-
15
- Puppet.setdefaults("ldap",
16
- :ldapnodes => [false,
17
- "Whether to search for node configurations in LDAP."],
18
- :ldapssl => [false,
19
- "Whether SSL should be used when searching for nodes.
20
- Defaults to false because SSL usually requires certificates
21
- to be set up on the client side."],
22
- :ldaptls => [false,
23
- "Whether TLS should be used when searching for nodes.
24
- Defaults to false because TLS usually requires certificates
25
- to be set up on the client side."],
26
- :ldapserver => ["ldap",
27
- "The LDAP server. Only used if ``ldapnodes`` is enabled."],
28
- :ldapport => [389,
29
- "The LDAP port. Only used if ``ldapnodes`` is enabled."],
30
- :ldapstring => ["(&(objectclass=puppetClient)(cn=%s))",
31
- "The search string used to find an LDAP node."],
32
- :ldapattrs => ["puppetclass",
33
- "The LDAP attributes to use to define Puppet classes. Values
34
- should be comma-separated."],
35
- :ldapparentattr => ["parentnode",
36
- "The attribute to use to define the parent node."],
37
- :ldapuser => ["",
38
- "The user to use to connect to LDAP. Must be specified as a
39
- full DN."],
40
- :ldappassword => ["",
41
- "The password to use to connect to LDAP."],
42
- :ldapbase => ["",
43
- "The search base for LDAP searches. It's impossible to provide
44
- a meaningful default here, although the LDAP libraries might
45
- have one already set. Generally, it should be the 'ou=Hosts'
46
- branch under your main directory."]
47
- )
97
+ return @ldap
98
+ end
48
99
 
49
- Puppet.setdefaults(:puppetmaster,
50
- :storeconfigs => [false,
51
- "Whether to store each client's configuration. This
52
- requires ActiveRecord from Ruby on Rails."]
53
- )
100
+ # Make sure we don't have any remaining collections that specifically
101
+ # look for resources, because we want to consider those to be
102
+ # parse errors.
103
+ def check_resource_collections(scope)
104
+ remaining = []
105
+ scope.collections.each do |coll|
106
+ if r = coll.resources
107
+ if r.is_a?(Array)
108
+ remaining += r
109
+ else
110
+ remaining << r
111
+ end
112
+ end
113
+ end
114
+ unless remaining.empty?
115
+ raise Puppet::ParseError, "Failed to find virtual resources %s" %
116
+ remaining.join(', ')
117
+ end
118
+ end
54
119
 
55
- attr_accessor :ast
120
+ def clear
121
+ initparsevars
122
+ end
56
123
 
57
- class << self
58
- attr_writer :ldap
59
- end
60
- # just shorten the constant path a bit, using what amounts to an alias
61
- AST = Puppet::Parser::AST
62
-
63
- # Create an ldap connection. This is a class method so others can call
64
- # it and use the same variables and such.
65
- def self.ldap
66
- unless defined? @ldap and @ldap
67
- if Puppet[:ldapssl]
68
- @ldap = LDAP::SSLConn.new(Puppet[:ldapserver], Puppet[:ldapport])
69
- elsif Puppet[:ldaptls]
70
- @ldap = LDAP::SSLConn.new(
71
- Puppet[:ldapserver], Puppet[:ldapport], true
72
- )
73
- else
74
- @ldap = LDAP::Conn.new(Puppet[:ldapserver], Puppet[:ldapport])
124
+ # Iteratively evaluate all of the objects. This finds all of the objects
125
+ # that represent definitions and evaluates the definitions appropriately.
126
+ # It also adds defaults and overrides as appropriate.
127
+ def evaliterate(scope)
128
+ count = 0
129
+ loop do
130
+ count += 1
131
+ done = true
132
+ # First perform collections, so we can collect defined types.
133
+ if coll = scope.collections and ! coll.empty?
134
+ exceptwrap do
135
+ coll.each do |c|
136
+ # Only keep the loop going if we actually successfully
137
+ # collected something.
138
+ if o = c.evaluate
139
+ done = false
140
+ end
75
141
  end
76
- @ldap.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
77
- @ldap.set_option(LDAP::LDAP_OPT_REFERRALS, LDAP::LDAP_OPT_ON)
78
- @ldap.simple_bind(Puppet[:ldapuser], Puppet[:ldappassword])
79
142
  end
80
-
81
- return @ldap
82
143
  end
83
-
84
- # create our interpreter
85
- def initialize(hash)
86
- if @code = hash[:Code]
87
- @file = nil # to avoid warnings
88
- elsif ! @file = hash[:Manifest]
89
- raise Puppet::DevError, "You must provide code or a manifest"
144
+
145
+ # Then evaluate any defined types.
146
+ if ary = scope.unevaluated
147
+ ary.each do |resource|
148
+ resource.evaluate
90
149
  end
150
+ # If we evaluated, then loop through again.
151
+ done = false
152
+ end
153
+ break if done
154
+
155
+ if count > 1000
156
+ raise Puppet::ParseError, "Got 1000 class levels, which is unsupported"
157
+ end
158
+ end
159
+ end
91
160
 
92
- @lastchecked = 0
93
-
94
- if hash.include?(:UseNodes)
95
- @usenodes = hash[:UseNodes]
96
- else
97
- @usenodes = true
98
- end
161
+ # Evaluate a specific node.
162
+ def evalnode(client, scope, facts)
163
+ return unless self.usenodes
99
164
 
100
- # By default, we only search the parse tree.
101
- @nodesources = []
165
+ unless client
166
+ raise Puppet::Error,
167
+ "Cannot evaluate nodes with a nil client"
168
+ end
169
+ names = [client]
170
+
171
+ # Make sure both the fqdn and the short name of the
172
+ # host can be used in the manifest
173
+ if client =~ /\./
174
+ names << client.sub(/\..+/,'')
175
+ else
176
+ names << "#{client}.#{facts['domain']}"
177
+ end
102
178
 
103
- if Puppet[:ldapnodes]
104
- @nodesources << :ldap
105
- end
179
+ if names.empty?
180
+ raise Puppet::Error,
181
+ "Cannot evaluate nodes with a nil client"
182
+ end
106
183
 
107
- if hash[:NodeSources]
108
- hash[:NodeSources].each do |src|
109
- if respond_to? "nodesearch_#{src.to_s}"
110
- @nodesources << src.to_s.intern
111
- else
112
- Puppet.warning "Node source '#{src}' not supported"
113
- end
114
- end
115
- end
184
+ # Look up our node object.
185
+ if nodeclass = nodesearch(*names)
186
+ nodeclass.safeevaluate :scope => scope
187
+ else
188
+ raise Puppet::Error, "Could not find %s with names %s" %
189
+ [client, names.join(", ")]
190
+ end
191
+ end
116
192
 
117
- @setup = false
193
+ # Evaluate all of the code we can find that's related to our client.
194
+ def evaluate(client, facts)
118
195
 
119
- # Set it to either the value or nil. This is currently only used
120
- # by the cfengine module.
121
- @classes = hash[:Classes] || []
196
+ scope = Puppet::Parser::Scope.new(:interp => self) # no parent scope
197
+ scope.name = "top"
198
+ scope.type = "main"
122
199
 
123
- @local = hash[:Local] || false
200
+ scope.host = client || facts["hostname"] || Facter.value(:hostname)
124
201
 
125
- if hash.include?(:ForkSave)
126
- @forksave = hash[:ForkSave]
127
- else
128
- # This is just too dangerous right now. Sorry, it's going
129
- # to have to be slow.
130
- @forksave = false
131
- end
202
+ classes = @classes.dup
132
203
 
133
- if Puppet[:storeconfigs]
134
- Puppet::Rails.init
135
- end
204
+ # Okay, first things first. Set our facts.
205
+ scope.setfacts(facts)
136
206
 
137
- @files = []
207
+ # Everyone will always evaluate the top-level class, if there is one.
208
+ if klass = findclass("", "")
209
+ # Set the source, so objects can tell where they were defined.
210
+ scope.source = klass
211
+ klass.safeevaluate :scope => scope, :nosubscope => true
212
+ end
138
213
 
139
- # Create our parser object
140
- parsefiles
141
- end
214
+ # Next evaluate the node
215
+ evalnode(client, scope, facts)
142
216
 
143
- # Search for our node in the various locations. This only searches
144
- # locations external to the files; the scope is responsible for
145
- # searching the parse tree.
146
- def nodesearch(node)
147
- # At this point, stop at the first source that defines
148
- # the node
149
- @nodesources.each do |source|
150
- method = "nodesearch_%s" % source
151
- parent = nil
152
- nodeclasses = nil
153
- if self.respond_to? method
154
- parent, nodeclasses = self.send(method, node)
155
-
156
- if parent or (nodeclasses and !nodeclasses.empty?)
157
- Puppet.info "Found %s in %s" % [node, source]
158
- return parent, nodeclasses
159
- else
160
- # Look for a default node.
161
- parent, nodeclasses = self.send(method, "default")
162
- if parent or (nodeclasses and !nodeclasses.empty?)
163
- Puppet.info "Found default node for %s in %s" %
164
- [node, source]
165
- return parent, nodeclasses
166
- end
167
- end
168
- end
217
+ # If we were passed any classes, evaluate those.
218
+ if classes
219
+ classes.each do |klass|
220
+ if klassobj = findclass("", klass)
221
+ klassobj.safeevaluate :scope => scope
169
222
  end
223
+ end
224
+ end
170
225
 
171
- return nil, nil
226
+ # That was the first pass evaluation. Now iteratively evaluate
227
+ # until we've gotten rid of all of everything or thrown an error.
228
+ evaliterate(scope)
229
+
230
+ # Now make sure we fail if there's anything left to do
231
+ failonleftovers(scope)
232
+
233
+ # Now finish everything. This recursively calls finish on the
234
+ # contained scopes and resources.
235
+ scope.finish
236
+
237
+ # Store everything. We need to do this before translation, because
238
+ # it operates on resources, not transobjects.
239
+ if Puppet[:storeconfigs]
240
+ args = {
241
+ :resources => scope.resources,
242
+ :name => scope.host,
243
+ :facts => facts
244
+ }
245
+ unless scope.classlist.empty?
246
+ args[:classes] = scope.classlist
172
247
  end
173
248
 
174
- # Find the ldap node and extra the info, returning just
175
- # the critical data.
176
- def nodesearch_ldap(node)
177
- unless defined? @ldap and @ldap
178
- setup_ldap()
179
- unless @ldap
180
- Puppet.info "Skipping ldap source; no ldap connection"
181
- return nil, []
182
- end
183
- end
249
+ storeconfigs(args)
250
+ end
184
251
 
185
- if node =~ /\./
186
- node = node.sub(/\..+/, '')
187
- end
252
+ # Now, finally, convert our scope tree + resources into a tree of
253
+ # buckets and objects.
254
+ objects = scope.translate
188
255
 
189
- filter = Puppet[:ldapstring]
190
- attrs = Puppet[:ldapattrs].split("\s*,\s*")
191
- sattrs = attrs.dup
192
- pattr = nil
193
- if pattr = Puppet[:ldapparentattr]
194
- if pattr == ""
195
- pattr = nil
196
- else
197
- sattrs << pattr
198
- end
199
- end
256
+ # Add the class list
257
+ unless scope.classlist.empty?
258
+ objects.classes = scope.classlist
259
+ end
200
260
 
201
- if filter =~ /%s/
202
- filter = filter.gsub(/%s/, node)
203
- end
261
+ return objects
262
+ end
204
263
 
205
- parent = nil
206
- classes = []
207
-
208
- found = false
209
- count = 0
210
- begin
211
- # We're always doing a sub here; oh well.
212
- @ldap.search(Puppet[:ldapbase], 2, filter, sattrs) do |entry|
213
- found = true
214
- if pattr
215
- if values = entry.vals(pattr)
216
- if values.length > 1
217
- raise Puppet::Error,
218
- "Node %s has more than one parent: %s" %
219
- [node, values.inspect]
220
- end
221
- unless values.empty?
222
- parent = values.shift
223
- end
224
- end
225
- end
264
+ # Fail if there any overrides left to perform.
265
+ def failonleftovers(scope)
266
+ overrides = scope.overrides
267
+ unless overrides.empty?
268
+ fail Puppet::ParseError,
269
+ "Could not find object(s) %s" % overrides.collect { |o|
270
+ o.ref
271
+ }.join(", ")
272
+ end
226
273
 
227
- attrs.each { |attr|
228
- if values = entry.vals(attr)
229
- values.each do |v| classes << v end
230
- end
231
- }
232
- end
233
- rescue => detail
234
- if count == 0
235
- # Try reconnecting to ldap
236
- @ldap = nil
237
- setup_ldap()
238
- retry
239
- else
240
- raise Puppet::Error, "LDAP Search failed: %s" % detail
241
- end
242
- end
274
+ # Now check that there aren't any extra resource collections.
275
+ check_resource_collections(scope)
276
+ end
243
277
 
244
- classes.flatten!
278
+ # Find a class definition, relative to the current namespace.
279
+ def findclass(namespace, name)
280
+ fqfind namespace, name, @classtable
281
+ end
245
282
 
246
- return parent, classes
247
- end
283
+ # Find a component definition, relative to the current namespace.
284
+ def finddefine(namespace, name)
285
+ fqfind namespace, name, @definetable
286
+ end
248
287
 
249
- def parsedate
250
- parsefiles()
251
- @parsedate
252
- end
288
+ # The recursive method used to actually look these objects up.
289
+ def fqfind(namespace, name, table)
290
+ namespace = namespace.downcase
291
+ name = name.downcase
292
+ if name =~ /^::/ or namespace == ""
293
+ return table[name.sub(/^::/, '')]
294
+ end
295
+ ary = namespace.split("::")
253
296
 
254
- # Add a new file to check for updateness.
255
- def newfile(file)
256
- unless @files.find { |f| f.file == file }
257
- @files << Puppet::ParsedFile.new(file)
258
- end
297
+ while ary.length > 0
298
+ newname = (ary + [name]).join("::").sub(/^::/, '')
299
+ if obj = table[newname]
300
+ return obj
259
301
  end
260
302
 
261
- # evaluate our whole tree
262
- def run(client, facts)
263
- # We have to leave this for after initialization because there
264
- # seems to be a problem keeping ldap open after a fork.
265
- unless @setup
266
- @nodesources.each { |source|
267
- method = "setup_%s" % source.to_s
268
- if respond_to? method
269
- begin
270
- self.send(method)
271
- rescue => detail
272
- raise Puppet::Error,
273
- "Could not set up node source %s" % source
274
- end
275
- end
276
- }
277
- end
278
- parsefiles()
303
+ # Delete the second to last object, which reduces our namespace by one.
304
+ ary.pop
305
+ end
306
+
307
+ # If we've gotten to this point without finding it, see if the name
308
+ # exists at the top namespace
309
+ if obj = table[name]
310
+ return obj
311
+ end
312
+
313
+ return nil
314
+ end
315
+
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
279
360
 
280
- # Really, we should stick multiple names in here
281
- # but for now just make a simple array
282
- names = [client]
361
+ # create our interpreter
362
+ def initialize(hash)
363
+ if @code = hash[:Code]
364
+ @file = nil # to avoid warnings
365
+ elsif ! @file = hash[:Manifest]
366
+ devfail "You must provide code or a manifest"
367
+ end
283
368
 
284
- # Make sure both the fqdn and the short name of the
285
- # host can be used in the manifest
286
- if client =~ /\./
287
- names << client.sub(/\..+/,'')
369
+ if hash.include?(:UseNodes)
370
+ @usenodes = hash[:UseNodes]
371
+ else
372
+ @usenodes = true
373
+ end
374
+
375
+ # By default, we only search for parsed nodes.
376
+ @nodesources = []
377
+
378
+ if Puppet[:ldapnodes]
379
+ # 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
288
390
  else
289
- names << "#{client}.#{facts['domain']}"
391
+ Puppet.warning "Node source '#{src}' not supported"
290
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
402
+ end
291
403
 
292
- scope = Puppet::Parser::Scope.new() # no parent scope
293
- scope.name = "top"
294
- scope.type = "puppet"
295
- scope.interp = self
404
+ @setup = false
296
405
 
297
- classes = @classes.dup
406
+ initparsevars()
298
407
 
299
- args = {:ast => @ast, :facts => facts, :classes => classes}
408
+ # Set it to either the value or nil. This is currently only used
409
+ # by the cfengine module.
410
+ @classes = hash[:Classes] || []
300
411
 
301
- if @usenodes
302
- unless client
303
- raise Puppet::Error,
304
- "Cannot evaluate nodes with a nil client"
305
- end
412
+ @local = hash[:Local] || false
306
413
 
307
- args[:names] = names
414
+ if hash.include?(:ForkSave)
415
+ @forksave = hash[:ForkSave]
416
+ else
417
+ # This is just too dangerous right now. Sorry, it's going
418
+ # to have to be slow.
419
+ @forksave = false
420
+ end
308
421
 
309
- parent, nodeclasses = nodesearch(client)
422
+ # The class won't always be defined during testing.
423
+ if Puppet[:storeconfigs]
424
+ if Puppet.features.rails?
425
+ Puppet::Rails.init
426
+ else
427
+ raise Puppet::Error, "Rails is missing; cannot store configurations"
428
+ end
429
+ end
310
430
 
311
- args[:classes] += nodeclasses if nodeclasses
431
+ @files = []
312
432
 
313
- args[:parentnode] = parent if parent
433
+ # Create our parser object
434
+ parsefiles
435
+ end
314
436
 
315
- if nodeclasses or parent
316
- args[:searched] = true
437
+ # Initialize or reset the variables related to parsing.
438
+ def initparsevars
439
+ @classtable = {}
440
+ @namespace = "main"
441
+
442
+ @nodetable = {}
443
+
444
+ @definetable = {}
445
+ end
446
+
447
+ # Find the ldap node and extra the info, returning just
448
+ # the critical data.
449
+ def ldapsearch(node)
450
+ unless defined? @ldap and @ldap
451
+ setup_ldap()
452
+ unless @ldap
453
+ Puppet.info "Skipping ldap source; no ldap connection"
454
+ return nil, []
455
+ end
456
+ end
457
+
458
+ filter = Puppet[:ldapstring]
459
+ attrs = Puppet[:ldapattrs].split("\s*,\s*")
460
+ sattrs = attrs.dup
461
+ pattr = nil
462
+ if pattr = Puppet[:ldapparentattr]
463
+ if pattr == ""
464
+ pattr = nil
465
+ else
466
+ sattrs << pattr
467
+ end
468
+ end
469
+
470
+ if filter =~ /%s/
471
+ filter = filter.gsub(/%s/, node)
472
+ end
473
+
474
+ parent = nil
475
+ classes = []
476
+
477
+ found = false
478
+ count = 0
479
+ begin
480
+ # We're always doing a sub here; oh well.
481
+ @ldap.search(Puppet[:ldapbase], 2, filter, sattrs) do |entry|
482
+ found = true
483
+ if pattr
484
+ if values = entry.vals(pattr)
485
+ if values.length > 1
486
+ raise Puppet::Error,
487
+ "Node %s has more than one parent: %s" %
488
+ [node, values.inspect]
489
+ end
490
+ unless values.empty?
491
+ parent = values.shift
492
+ end
317
493
  end
318
494
  end
319
495
 
320
- begin
321
- objects = scope.evaluate(args)
322
- rescue Puppet::DevError, Puppet::Error, Puppet::ParseError => except
323
- raise
324
- rescue => except
325
- error = Puppet::DevError.new("%s: %s" %
326
- [except.class, except.message])
327
- error.backtrace = except.backtrace
328
- #if Puppet[:debug]
329
- # puts except.backtrace
330
- #end
331
- raise error
332
- end
496
+ attrs.each { |attr|
497
+ if values = entry.vals(attr)
498
+ values.each do |v| classes << v end
499
+ end
500
+ }
501
+ end
502
+ rescue => detail
503
+ if count == 0
504
+ # Try reconnecting to ldap
505
+ @ldap = nil
506
+ setup_ldap()
507
+ retry
508
+ else
509
+ raise Puppet::Error, "LDAP Search failed: %s" % detail
510
+ end
511
+ end
333
512
 
334
- if Puppet[:storeconfigs]
335
- storeconfigs(
336
- :objects => objects,
337
- :host => client,
338
- :facts => facts
339
- )
340
- end
513
+ classes.flatten!
514
+
515
+ if classes.empty?
516
+ classes = nil
517
+ end
341
518
 
342
- return objects
519
+ return parent, classes
520
+ end
521
+
522
+ # Split an fq name into a namespace and name
523
+ def namesplit(fullname)
524
+ ary = fullname.split("::")
525
+ n = ary.pop || ""
526
+ ns = ary.join("::")
527
+ return ns, n
528
+ end
529
+
530
+ # Create a new class, or merge with an existing class.
531
+ def newclass(fqname, options = {})
532
+ fqname = fqname.downcase
533
+ if @definetable.include?(fqname)
534
+ raise Puppet::ParseError, "Cannot redefine class %s as a definition" %
535
+ fqname
536
+ end
537
+ code = options[:code]
538
+ parent = options[:parent]
539
+
540
+ # If the class is already defined, then add code to it.
541
+ if other = @classtable[fqname]
542
+ # Make sure the parents match
543
+ 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])
343
545
  end
344
546
 
345
- # Connect to the LDAP Server
346
- def setup_ldap
347
- self.class.ldap = nil
348
- begin
349
- require 'ldap'
350
- rescue LoadError
351
- Puppet.notice(
352
- "Could not set up LDAP Connection: Missing ruby/ldap libraries"
353
- )
354
- @ldap = nil
355
- return
547
+ # This might be dangerous...
548
+ if parent and ! other.parentclass
549
+ other.parentclass = parent
550
+ end
551
+
552
+ # This might just be an empty, stub class.
553
+ if code
554
+ tmp = fqname
555
+ if tmp == ""
556
+ tmp = "main"
356
557
  end
357
- begin
358
- @ldap = self.class.ldap()
359
- rescue => detail
360
- raise Puppet::Error, "Could not connect to LDAP: %s" % detail
558
+
559
+ Puppet.debug @parser.addcontext("Adding code to %s" % tmp)
560
+ # Else, add our code to it.
561
+ if other.code and code
562
+ other.code.children += code.children
563
+ else
564
+ other.code ||= code
361
565
  end
362
566
  end
567
+ else
568
+ # Define it anew.
569
+ ns, name = namesplit(fqname)
570
+
571
+ # Note we're doing something somewhat weird here -- we're setting
572
+ # the class's namespace to its fully qualified name. This means
573
+ # anything inside that class starts looking in that namespace first.
574
+ args = {:type => name, :namespace => fqname, :fqname => fqname, :interp => self}
575
+ args[:code] = code if code
576
+ args[:parentclass] = parent if parent
577
+ @classtable[fqname] = @parser.ast AST::HostClass, args
578
+ end
579
+
580
+ return @classtable[fqname]
581
+ end
363
582
 
364
- def scope
365
- return @scope
583
+ # Create a new definition.
584
+ def newdefine(fqname, options = {})
585
+ fqname = fqname.downcase
586
+ if @classtable.include?(fqname)
587
+ raise Puppet::ParseError, "Cannot redefine class %s as a definition" %
588
+ fqname
589
+ end
590
+ # 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])
593
+ end
594
+
595
+ ns, name = namesplit(fqname)
596
+ args = {
597
+ :type => name,
598
+ :namespace => ns,
599
+ :arguments => options[:arguments],
600
+ :code => options[:code],
601
+ :fqname => fqname
602
+ }
603
+
604
+ [:code, :arguments].each do |param|
605
+ args[param] = options[param] if options[param]
606
+ end
607
+
608
+ @definetable[fqname] = @parser.ast AST::Component, args
609
+ end
610
+
611
+ # Create a new node. Nodes are special, because they're stored in a global
612
+ # table, not according to namespaces.
613
+ def newnode(names, options = {})
614
+ names = [names] unless names.instance_of?(Array)
615
+ names.collect do |name|
616
+ name = name.to_s.downcase
617
+ if other = @nodetable[name]
618
+ @parser.error("Node %s is already defined at %s:%s; cannot redefine" % [other.name, other.file, other.line])
366
619
  end
620
+ name = name.to_s if name.is_a?(Symbol)
621
+ args = {
622
+ :name => name,
623
+ }
624
+ if options[:code]
625
+ args[:code] = options[:code]
626
+ end
627
+ if options[:parent]
628
+ args[:parentclass] = options[:parent]
629
+ end
630
+ @nodetable[name] = @parser.ast(AST::Node, args)
631
+ @nodetable[name].fqname = name
632
+ @nodetable[name]
633
+ @nodetable[name].interp = self
634
+ @nodetable[name]
635
+ end
636
+ end
367
637
 
368
- private
638
+ # Add a new file to be checked when we're checking to see if we should be
639
+ # reparsed.
640
+ def newfile(*files)
641
+ files.each do |file|
642
+ unless file.is_a? Puppet::Util::LoadedFile
643
+ file = Puppet::Util::LoadedFile.new(file)
644
+ end
645
+ @files << file
646
+ end
647
+ end
369
648
 
370
- # Check whether any of our files have changed.
371
- def checkfiles
372
- if @files.find { |f| f.changed? }
373
- @parsedate = Time.now.to_i
649
+ # Search for our node in the various locations.
650
+ def nodesearch(*nodes)
651
+ 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
374
666
  end
375
667
  end
668
+ end
376
669
 
377
- # Parse the files, generating our parse tree. This automatically
378
- # reparses only if files are updated, so it's safe to call multiple
379
- # times.
380
- def parsefiles
381
- # First check whether there are updates to any non-puppet files
382
- # like templates. If we need to reparse, this will get quashed,
383
- # but it needs to be done first in case there's no reparse
384
- # but there are other file changes.
385
- checkfiles()
386
-
387
- # Check if the parser should reparse.
388
- if @file
389
- if defined? @parser
390
- unless @parser.reparse?
391
- @lastchecked = Time.now
392
- return false
393
- end
394
- end
670
+ # If they made it this far, we haven't found anything, so look for a
671
+ # default node.
672
+ unless nodes.include?("default")
673
+ if defobj = self.nodesearch("default")
674
+ Puppet.notice "Using default node for %s" % [nodes[0]]
675
+ return defobj
676
+ end
677
+ end
395
678
 
396
- unless FileTest.exists?(@file)
397
- if @ast
398
- return
399
- else
400
- raise Puppet::Error, "Manifest %s must exist" % @file
401
- end
679
+ return nil
680
+ end
681
+
682
+ # See if our node was defined in the code.
683
+ def nodesearch_code(name)
684
+ @nodetable[name]
685
+ end
686
+
687
+ # Look for external node definitions.
688
+ def nodesearch_external(name)
689
+ return nil unless Puppet[:external_nodes] != "none"
690
+
691
+ begin
692
+ output = Puppet::Util.execute([Puppet[:external_nodes], name])
693
+ rescue Puppet::ExecutionFailure => detail
694
+ if $?.exitstatus == 1
695
+ return nil
696
+ else
697
+ Puppet.err "Could not retrieve external node information for %s: %s" % [name, detail]
698
+ end
699
+ return nil
700
+ end
701
+
702
+ if output =~ /\A\s+\Z/ # all whitespace
703
+ puts "empty response for %s" % name
704
+ return nil
705
+ 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?
716
+ end
717
+
718
+ if args.empty?
719
+ Puppet.warning "Somehow got a node with no information"
720
+ return nil
721
+ else
722
+ return gennode(name, args, Puppet[:external_nodes])
723
+ end
724
+ end
725
+
726
+ # Look for our node in ldap.
727
+ 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
735
+ return nil
736
+ end
737
+ end
738
+
739
+ def parsedate
740
+ parsefiles()
741
+ @parsedate
742
+ end
743
+
744
+ # evaluate our whole tree
745
+ def run(client, facts)
746
+ # We have to leave this for after initialization because there
747
+ # seems to be a problem keeping ldap open after a fork.
748
+ 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)
402
755
  end
403
756
  end
757
+ }
758
+ end
759
+ parsefiles()
404
760
 
405
- if defined? @parser
406
- # If this isn't our first time parsing in this process,
407
- # note that we're reparsing.
408
- Puppet.info "Reloading files"
409
- end
410
- # should i be creating a new parser each time...?
411
- @parser = Puppet::Parser::Parser.new()
412
- if @code
413
- @parser.string = @code
761
+ # Evaluate all of the appropriate code.
762
+ objects = evaluate(client, facts)
763
+
764
+ # And return it all.
765
+ return objects
766
+ end
767
+
768
+ # Connect to the LDAP Server
769
+ def setup_ldap
770
+ self.class.ldap = nil
771
+ unless Puppet.features.ldap?
772
+ Puppet.notice(
773
+ "Could not set up LDAP Connection: Missing ruby/ldap libraries"
774
+ )
775
+ @ldap = nil
776
+ return
777
+ end
778
+
779
+ begin
780
+ @ldap = self.class.ldap()
781
+ rescue => detail
782
+ raise Puppet::Error, "Could not connect to LDAP: %s" % detail
783
+ end
784
+ end
785
+
786
+ def scope
787
+ return @scope
788
+ end
789
+
790
+ private
791
+
792
+ # Check whether any of our files have changed.
793
+ def checkfiles
794
+ if @files.find { |f| f.changed? }
795
+ @parsedate = Time.now.to_i
796
+ end
797
+ end
798
+
799
+ # Parse the files, generating our parse tree. This automatically
800
+ # reparses only if files are updated, so it's safe to call multiple
801
+ # times.
802
+ def parsefiles
803
+ # First check whether there are updates to any non-puppet files
804
+ # like templates. If we need to reparse, this will get quashed,
805
+ # but it needs to be done first in case there's no reparse
806
+ # but there are other file changes.
807
+ checkfiles()
808
+
809
+ # Check if the parser should reparse.
810
+ if @file
811
+ if defined? @parser
812
+ if stamp = @parser.reparse?
813
+ Puppet.notice "Reloading files"
414
814
  else
415
- @parser.file = @file
815
+ return false
416
816
  end
817
+ end
417
818
 
418
- if @local
419
- @ast = @parser.parse
819
+ unless FileTest.exists?(@file)
820
+ # If we've already parsed, then we're ok.
821
+ if findclass("", "")
822
+ return
420
823
  else
421
- benchmark(:info, "Parsed manifest") do
422
- @ast = @parser.parse
423
- end
824
+ raise Puppet::Error, "Manifest %s must exist" % @file
424
825
  end
826
+ end
827
+ end
828
+
829
+ # Reset our parse tables.
830
+ clear()
831
+
832
+ # Create a new parser, just to keep things fresh.
833
+ @parser = Puppet::Parser::Parser.new(self)
834
+ if @code
835
+ @parser.string = @code
836
+ else
837
+ @parser.file = @file
838
+ # Mark when we parsed, so we can check freshness
839
+ @parsedate = File.stat(@file).ctime.to_i
840
+ end
425
841
 
426
- # Mark when we parsed, so we can check freshness
427
- @parsedate = Time.now.to_i
428
- @lastchecked = Time.now
842
+ # Parsing stores all classes and defines and such in their
843
+ # various tables, so we don't worry about the return.
844
+ if @local
845
+ @parser.parse
846
+ else
847
+ benchmark(:info, "Parsed manifest") do
848
+ @parser.parse
429
849
  end
850
+ end
851
+ @parsedate = Time.now.to_i
852
+ end
430
853
 
431
- # Store the configs into the database.
432
- def storeconfigs(hash)
433
- unless defined? ActiveRecord
434
- require 'puppet/rails'
435
- unless defined? ActiveRecord
436
- raise LoadError,
437
- "storeconfigs is enabled but rails is unavailable"
438
- end
439
- end
854
+ # Store the configs into the database.
855
+ def storeconfigs(hash)
856
+ unless Puppet.features.rails?
857
+ raise Puppet::Error,
858
+ "storeconfigs is enabled but rails is unavailable"
859
+ end
440
860
 
441
- Puppet::Rails.init
861
+ unless ActiveRecord::Base.connected?
862
+ Puppet::Rails.connect
863
+ end
442
864
 
443
- # Fork the storage, since we don't need the client waiting
444
- # on that. How do I avoid this duplication?
445
- if @forksave
446
- fork {
447
- # We store all of the objects, even the collectable ones
448
- benchmark(:info, "Stored configuration for #{hash[:client]}") do
449
- # Try to batch things a bit, by putting them into
450
- # a transaction
451
- Puppet::Rails::Host.transaction do
452
- Puppet::Rails::Host.store(hash)
453
- end
454
- end
455
- }
456
- else
457
- # We store all of the objects, even the collectable ones
458
- benchmark(:info, "Stored configuration for #{hash[:client]}") do
459
- Puppet::Rails::Host.transaction do
460
- Puppet::Rails::Host.store(hash)
461
- end
865
+ # Fork the storage, since we don't need the client waiting
866
+ # on that. How do I avoid this duplication?
867
+ if @forksave
868
+ fork {
869
+ # We store all of the objects, even the collectable ones
870
+ benchmark(:info, "Stored configuration for #{hash[:name]}") do
871
+ # Try to batch things a bit, by putting them into
872
+ # a transaction
873
+ Puppet::Rails::Host.transaction do
874
+ Puppet::Rails::Host.store(hash)
462
875
  end
463
876
  end
464
-
465
- # Now that we've stored everything, we need to strip out
466
- # the collectable objects so that they are not sent on
467
- # to the host
468
- hash[:objects].collectstrip!
877
+ }
878
+ else
879
+ begin
880
+ # We store all of the objects, even the collectable ones
881
+ benchmark(:info, "Stored configuration for #{hash[:name]}") do
882
+ Puppet::Rails::Host.transaction do
883
+ Puppet::Rails::Host.store(hash)
884
+ end
885
+ end
886
+ rescue => detail
887
+ if Puppet[:trace]
888
+ puts detail.backtrace
889
+ end
890
+ Puppet.err "Could not store configs: %s" % detail.to_s
469
891
  end
470
892
  end
471
893
  end
472
894
  end
473
895
 
474
- # $Id: interpreter.rb 1421 2006-07-21 23:12:51Z luke $
896
+ # $Id: interpreter.rb 2432 2007-04-30 15:38:06Z luke $