puppet 0.24.4 → 0.24.5

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 (316) hide show
  1. data/CHANGELOG +170 -0
  2. data/Rakefile +6 -4
  3. data/bin/filebucket +3 -2
  4. data/bin/puppet +7 -4
  5. data/bin/puppetca +32 -14
  6. data/bin/puppetd +12 -34
  7. data/bin/puppetmasterd +3 -2
  8. data/bin/puppetrun +5 -43
  9. data/bin/ralsh +2 -2
  10. data/conf/debian/README.source +2 -0
  11. data/conf/debian/TODO.Debian +1 -0
  12. data/conf/debian/changelog +257 -0
  13. data/conf/debian/compat +1 -0
  14. data/conf/debian/control +45 -0
  15. data/conf/debian/copyright +17 -0
  16. data/conf/debian/docs +1 -0
  17. data/conf/debian/fileserver.conf +12 -0
  18. data/conf/debian/puppet.NEWS +63 -0
  19. data/conf/debian/puppet.conf +8 -0
  20. data/conf/debian/puppet.dirs +7 -0
  21. data/conf/debian/puppet.files +6 -0
  22. data/conf/debian/puppet.init +64 -0
  23. data/conf/debian/puppet.logrotate +11 -0
  24. data/conf/debian/puppet.postinst +9 -0
  25. data/conf/debian/puppet.postrm +21 -0
  26. data/conf/debian/puppet.preinst +25 -0
  27. data/conf/debian/puppetmaster.files +4 -0
  28. data/conf/debian/puppetmaster.init +58 -0
  29. data/conf/debian/rules +115 -0
  30. data/conf/debian/watch +2 -0
  31. data/conf/gentoo/init.d/puppet +1 -1
  32. data/conf/gentoo/init.d/puppetmaster +32 -31
  33. data/conf/redhat/client.init +10 -2
  34. data/conf/redhat/puppet.spec +4 -1
  35. data/conf/redhat/server.init +9 -1
  36. data/examples/{code/allatonce → allatonce} +0 -0
  37. data/examples/{code/assignments → assignments} +0 -0
  38. data/examples/{code/components → components} +0 -0
  39. data/examples/{root/etc → etc}/init.d/sleeper +0 -0
  40. data/examples/{root/etc → etc}/otherfile +0 -0
  41. data/examples/{root/etc → etc}/puppet/fileserver.conf +0 -0
  42. data/examples/{root/etc → etc}/puppet/namespaceauth.conf +0 -0
  43. data/examples/{root/etc → etc}/puppet/puppet.conf +0 -0
  44. data/examples/{root/etc → etc}/puppet/tagmail.conf +0 -0
  45. data/examples/{code/execs → execs} +0 -0
  46. data/examples/{code/file.bl → file.bl} +0 -0
  47. data/examples/{code/filedefaults → filedefaults} +0 -0
  48. data/examples/{code/fileparsing → fileparsing} +0 -0
  49. data/examples/{code/filerecursion → filerecursion} +0 -0
  50. data/examples/{code/functions → functions} +0 -0
  51. data/examples/{code/groups → groups} +0 -0
  52. data/examples/{code/head → head} +0 -0
  53. data/examples/{code/importing → importing} +0 -0
  54. data/examples/{code/mac_automount.pp → mac_automount.pp} +0 -0
  55. data/examples/{code/mac_dscl.pp → mac_dscl.pp} +0 -0
  56. data/examples/{code/mac_dscl_revert.pp → mac_dscl_revert.pp} +0 -0
  57. data/examples/{code/mac_netinfo.pp → mac_netinfo.pp} +0 -0
  58. data/examples/{code/mac_pkgdmg.pp → mac_pkgdmg.pp} +0 -0
  59. data/examples/{code/modules → modules}/sample-module.pp +0 -0
  60. data/examples/{code/modules → modules}/sample-module/README.txt +0 -0
  61. data/examples/{code/modules → modules}/sample-module/lib/puppet/parser/functions/hostname_to_dn.rb +0 -0
  62. data/examples/{code/modules → modules}/sample-module/manifests/init.pp +0 -0
  63. data/examples/{code/modules → modules}/sample-module/templates/sample.erb +0 -0
  64. data/examples/{code/nodes → nodes} +0 -0
  65. data/examples/{code/one → one} +0 -0
  66. data/examples/{code/relationships → relationships} +0 -0
  67. data/examples/{code/selectors → selectors} +0 -0
  68. data/examples/{code/simpletests → simpletests} +0 -0
  69. data/examples/{code/svncommit → svncommit} +0 -0
  70. data/ext/autotest/Rakefile +8 -0
  71. data/ext/autotest/config +43 -0
  72. data/ext/autotest/readme.rst +16 -0
  73. data/{examples/root → ext}/bin/sleeper +1 -1
  74. data/ext/emacs/puppet-mode.el +246 -184
  75. data/ext/ldap/puppet.schema +7 -2
  76. data/ext/module_puppet +4 -3
  77. data/ext/nagios/check_puppet.rb +117 -0
  78. data/ext/puppetlast +40 -0
  79. data/install.rb +12 -3
  80. data/lib/puppet.rb +1 -44
  81. data/lib/puppet/defaults.rb +23 -10
  82. data/lib/puppet/dsl.rb +2 -2
  83. data/lib/puppet/executables/client/certhandler.rb +77 -0
  84. data/lib/puppet/external/nagios.rb +1 -1
  85. data/lib/puppet/external/nagios/base.rb +60 -46
  86. data/lib/puppet/file_serving/indirection_hooks.rb +4 -2
  87. data/lib/puppet/file_serving/metadata.rb +0 -9
  88. data/lib/puppet/file_serving/terminus_helper.rb +4 -4
  89. data/lib/puppet/indirector.rb +26 -28
  90. data/lib/puppet/indirector/catalog/compiler.rb +6 -28
  91. data/lib/puppet/indirector/checksum/file.rb +2 -2
  92. data/lib/puppet/indirector/direct_file_server.rb +7 -7
  93. data/lib/puppet/indirector/envelope.rb +13 -0
  94. data/lib/puppet/indirector/exec.rb +2 -2
  95. data/lib/puppet/indirector/facts/facter.rb +2 -2
  96. data/lib/puppet/indirector/file.rb +17 -14
  97. data/lib/puppet/indirector/file_metadata/file.rb +2 -2
  98. data/lib/puppet/indirector/file_server.rb +14 -14
  99. data/lib/puppet/indirector/indirection.rb +113 -48
  100. data/lib/puppet/indirector/ldap.rb +13 -25
  101. data/lib/puppet/indirector/memory.rb +7 -7
  102. data/lib/puppet/indirector/module_files.rb +14 -14
  103. data/lib/puppet/indirector/node/exec.rb +3 -10
  104. data/lib/puppet/indirector/node/ldap.rb +138 -41
  105. data/lib/puppet/indirector/node/plain.rb +1 -8
  106. data/lib/puppet/indirector/node/rest.rb +1 -1
  107. data/lib/puppet/indirector/plain.rb +2 -2
  108. data/lib/puppet/indirector/report/processor.rb +2 -2
  109. data/lib/puppet/indirector/request.rb +42 -0
  110. data/lib/puppet/indirector/rest.rb +51 -3
  111. data/lib/puppet/indirector/terminus.rb +0 -27
  112. data/lib/puppet/indirector/yaml.rb +12 -17
  113. data/lib/puppet/metatype/attributes.rb +3 -7
  114. data/lib/puppet/metatype/evaluation.rb +2 -2
  115. data/lib/puppet/module.rb +6 -2
  116. data/lib/puppet/network/client/master.rb +29 -81
  117. data/lib/puppet/network/handler/master.rb +12 -43
  118. data/lib/puppet/network/http.rb +8 -6
  119. data/lib/puppet/network/http/handler.rb +42 -32
  120. data/lib/puppet/network/http/mongrel.rb +8 -9
  121. data/lib/puppet/network/http/mongrel/rest.rb +42 -15
  122. data/lib/puppet/network/http/webrick.rb +27 -16
  123. data/lib/puppet/network/http/webrick/rest.rb +38 -14
  124. data/lib/puppet/network/http_pool.rb +3 -2
  125. data/lib/puppet/network/server.rb +24 -22
  126. data/lib/puppet/network/xmlrpc/client.rb +6 -1
  127. data/lib/puppet/node.rb +38 -79
  128. data/lib/puppet/node/catalog.rb +9 -0
  129. data/lib/puppet/node/facts.rb +9 -1
  130. data/lib/puppet/parser/ast/function.rb +1 -1
  131. data/lib/puppet/parser/collector.rb +6 -0
  132. data/lib/puppet/parser/compiler.rb +1 -1
  133. data/lib/puppet/parser/functions.rb +25 -1
  134. data/lib/puppet/parser/interpreter.rb +2 -17
  135. data/lib/puppet/parser/parser.rb +4 -4
  136. data/lib/puppet/parser/parser_support.rb +6 -2
  137. data/lib/puppet/parser/resource.rb +6 -0
  138. data/lib/puppet/parser/templatewrapper.rb +9 -0
  139. data/lib/puppet/pgraph.rb +1 -1
  140. data/lib/puppet/property.rb +0 -1
  141. data/lib/puppet/provider.rb +9 -95
  142. data/lib/puppet/provider/confine.rb +77 -0
  143. data/lib/puppet/provider/confine/exists.rb +22 -0
  144. data/lib/puppet/provider/confine/false.rb +19 -0
  145. data/lib/puppet/provider/confine/feature.rb +17 -0
  146. data/lib/puppet/provider/confine/true.rb +20 -0
  147. data/lib/puppet/provider/confine/variable.rb +42 -0
  148. data/lib/puppet/provider/confine_collection.rb +47 -0
  149. data/lib/puppet/provider/confiner.rb +20 -0
  150. data/lib/puppet/provider/cron/crontab.rb +6 -2
  151. data/lib/puppet/provider/group/groupadd.rb +1 -1
  152. data/lib/puppet/provider/group/ldap.rb +48 -0
  153. data/lib/puppet/provider/ldap.rb +137 -0
  154. data/lib/puppet/provider/nameservice.rb +1 -2
  155. data/lib/puppet/provider/nameservice/objectadd.rb +2 -5
  156. data/lib/puppet/provider/package/dpkg.rb +16 -1
  157. data/lib/puppet/provider/package/freebsd.rb +15 -4
  158. data/lib/puppet/provider/package/gem.rb +33 -12
  159. data/lib/puppet/provider/package/pkgdmg.rb +1 -60
  160. data/lib/puppet/provider/package/ports.rb +6 -1
  161. data/lib/puppet/provider/package/rpm.rb +14 -13
  162. data/lib/puppet/provider/package/urpmi.rb +3 -3
  163. data/lib/puppet/provider/service/base.rb +4 -4
  164. data/lib/puppet/provider/service/debian.rb +1 -1
  165. data/lib/puppet/provider/service/init.rb +5 -3
  166. data/lib/puppet/provider/service/redhat.rb +35 -7
  167. data/lib/puppet/provider/ssh_authorized_key/parsed.rb +69 -0
  168. data/lib/puppet/provider/user/ldap.rb +133 -0
  169. data/lib/puppet/provider/user/useradd.rb +1 -1
  170. data/lib/puppet/rails/database/001_add_created_at_to_all_tables.rb +14 -14
  171. data/lib/puppet/rails/database/schema.rb +9 -0
  172. data/lib/puppet/rails/resource.rb +1 -0
  173. data/lib/puppet/reference/providers.rb +8 -2
  174. data/lib/puppet/reference/report.rb +23 -0
  175. data/lib/puppet/reports/rrdgraph.rb +4 -2
  176. data/lib/puppet/sslcertificates/ca.rb +9 -4
  177. data/lib/puppet/sslcertificates/support.rb +26 -2
  178. data/lib/puppet/transaction.rb +11 -16
  179. data/lib/puppet/transaction/change.rb +94 -0
  180. data/lib/puppet/transaction/event.rb +21 -0
  181. data/lib/puppet/transaction/report.rb +4 -0
  182. data/lib/puppet/type.rb +0 -2
  183. data/lib/puppet/type/file/ensure.rb +0 -5
  184. data/lib/puppet/type/file/group.rb +13 -7
  185. data/lib/puppet/type/file/source.rb +8 -15
  186. data/lib/puppet/type/file/target.rb +2 -0
  187. data/lib/puppet/type/group.rb +1 -1
  188. data/lib/puppet/type/mount.rb +4 -2
  189. data/lib/puppet/type/nagios_hostescalation.rb +3 -0
  190. data/lib/puppet/type/nagios_servicegroup.rb +3 -0
  191. data/lib/puppet/type/ssh_authorized_key.rb +56 -0
  192. data/lib/puppet/type/user.rb +3 -0
  193. data/lib/puppet/type/yumrepo.rb +0 -1
  194. data/lib/puppet/util.rb +1 -1
  195. data/lib/puppet/util/ldap.rb +5 -0
  196. data/lib/puppet/util/ldap/connection.rb +69 -0
  197. data/lib/puppet/util/ldap/generator.rb +45 -0
  198. data/lib/puppet/util/ldap/manager.rb +281 -0
  199. data/lib/puppet/util/posix.rb +2 -2
  200. data/lib/puppet/util/resource_template.rb +61 -0
  201. data/lib/puppet/util/settings.rb +63 -3
  202. data/lib/puppet/util/storage.rb +4 -0
  203. data/lib/puppet/util/warnings.rb +7 -0
  204. data/man/man8/filebucket.8 +116 -0
  205. data/man/man8/pi.8 +34 -0
  206. data/man/man8/puppet.8 +78 -0
  207. data/man/man8/puppet.conf.8 +1747 -0
  208. data/man/man8/puppetca.8 +118 -0
  209. data/man/man8/puppetd.8 +184 -0
  210. data/man/man8/puppetdoc.8 +62 -0
  211. data/man/man8/puppetmasterd.8 +87 -0
  212. data/man/man8/puppetrun.8 +151 -0
  213. data/man/man8/ralsh.8 +135 -0
  214. data/test/README +24 -0
  215. data/test/certmgr/support.rb +28 -1
  216. data/test/data/failers/badclassnoparam +10 -0
  217. data/test/data/failers/badclassparam +10 -0
  218. data/test/data/failers/badcompnoparam +9 -0
  219. data/test/data/failers/badcompparam +9 -0
  220. data/test/data/failers/badtypeparam +3 -0
  221. data/test/data/failers/noobjectrvalue +1 -0
  222. data/test/data/providers/cron/crontab.allthree +17 -0
  223. data/test/data/providers/cron/crontab.envNcomment +12 -0
  224. data/test/data/providers/cron/crontab.envNname +11 -0
  225. data/test/data/providers/cron/crontab.multirecords +12 -0
  226. data/test/data/providers/cron/crontab_collections.yaml +44 -0
  227. data/test/data/providers/cron/crontab_multiple_with_env.yaml +54 -0
  228. data/test/data/providers/cron/crontab_sample_records.yaml +272 -0
  229. data/test/data/providers/cron/examples/freebsd +2 -0
  230. data/test/data/providers/cron/examples/one +14 -0
  231. data/test/data/providers/cron/examples/openbsd +20 -0
  232. data/test/data/providers/package/testpackages.yaml +65 -0
  233. data/test/data/providers/ssh_authorized_key/parsed/authorized_keys +5 -0
  234. data/test/data/reports/1.yaml +108 -0
  235. data/test/data/reports/2.yaml +108 -0
  236. data/test/data/reports/tagmail_failers.conf +3 -0
  237. data/test/data/reports/tagmail_passers.conf +30 -0
  238. data/test/data/snippets/aliastest.pp +16 -0
  239. data/test/data/snippets/argumentdefaults +14 -0
  240. data/test/data/snippets/casestatement.pp +58 -0
  241. data/test/data/snippets/classheirarchy.pp +15 -0
  242. data/test/data/snippets/classincludes.pp +17 -0
  243. data/test/data/snippets/classpathtest +11 -0
  244. data/test/data/snippets/collection.pp +10 -0
  245. data/test/data/snippets/collection_within_virtual_definitions.pp +20 -0
  246. data/test/data/snippets/componentmetaparams.pp +11 -0
  247. data/test/data/snippets/componentrequire.pp +8 -0
  248. data/test/data/snippets/deepclassheirarchy.pp +23 -0
  249. data/test/data/snippets/defineoverrides.pp +17 -0
  250. data/test/data/snippets/emptyclass.pp +9 -0
  251. data/test/data/snippets/emptyexec.pp +3 -0
  252. data/test/data/snippets/falsevalues.pp +3 -0
  253. data/test/data/snippets/filecreate +11 -0
  254. data/test/data/snippets/fqdefinition.pp +5 -0
  255. data/test/data/snippets/fqparents.pp +11 -0
  256. data/test/data/snippets/implicititeration +15 -0
  257. data/test/data/snippets/multipleinstances +7 -0
  258. data/test/data/snippets/multisubs.pp +13 -0
  259. data/test/data/snippets/namevartest +9 -0
  260. data/test/data/snippets/scopetest +13 -0
  261. data/test/data/snippets/selectorvalues.pp +42 -0
  262. data/test/data/snippets/simpledefaults +5 -0
  263. data/test/data/snippets/simpleselector +38 -0
  264. data/test/data/snippets/singleary.pp +19 -0
  265. data/test/data/snippets/singlequote.pp +11 -0
  266. data/test/data/snippets/singleselector.pp +22 -0
  267. data/test/data/snippets/subclass_name_duplication.pp +11 -0
  268. data/test/data/snippets/tag.pp +9 -0
  269. data/test/data/snippets/tagged.pp +35 -0
  270. data/test/data/snippets/virtualresources.pp +14 -0
  271. data/test/data/types/hosts/1 +3 -0
  272. data/test/data/types/hosts/2 +13 -0
  273. data/test/data/types/hosts/solaris +5 -0
  274. data/test/data/types/mailalias/file1 +183 -0
  275. data/test/data/types/mount/freebsd.fstab +7 -0
  276. data/test/data/types/mount/linux.fstab +11 -0
  277. data/test/data/types/mount/solaris.fstab +11 -0
  278. data/test/data/types/port/1 +533 -0
  279. data/test/data/types/port/darwin +11866 -0
  280. data/test/data/types/ssh_authorized_key/1 +2 -0
  281. data/test/data/types/sshkey/1 +21 -0
  282. data/test/data/types/yumrepos/fedora-devel.repo +26 -0
  283. data/test/data/types/yumrepos/fedora.repo +9 -0
  284. data/test/language/parser.rb +8 -1
  285. data/test/lib/puppettest/runnable_test.rb +3 -0
  286. data/test/lib/puppettest/support/utils.rb +1 -1
  287. data/test/lib/rake/puppet_testtask.rb +3 -0
  288. data/test/lib/stubba.rb +1 -1
  289. data/test/network/client/ca.rb +1 -0
  290. data/test/network/client/master.rb +13 -127
  291. data/test/network/handler/master.rb +61 -80
  292. data/test/other/provider.rb +0 -45
  293. data/test/other/transactions.rb +53 -15
  294. data/test/rails/host.rb +0 -37
  295. data/test/ral/providers/cron/crontab.rb +32 -3
  296. data/test/ral/providers/provider.rb +28 -7
  297. data/test/ral/type/filesources.rb +2 -18
  298. data/test/ral/type/sshkey.rb +0 -1
  299. data/test/ral/type/user.rb +6 -0
  300. data/test/test +241 -0
  301. metadata +289 -113
  302. data/examples/root/etc/configfile +0 -0
  303. data/examples/root/etc/debian-passwd +0 -29
  304. data/examples/root/etc/debian-syslog.conf +0 -71
  305. data/lib/puppet/event.rb +0 -28
  306. data/lib/puppet/network/handler/configuration.rb +0 -184
  307. data/lib/puppet/network/http/mongrel/xmlrpc.rb +0 -4
  308. data/lib/puppet/network/http/webrick/xmlrpc.rb +0 -4
  309. data/lib/puppet/propertychange.rb +0 -141
  310. data/lib/puppet/provider/interface/redhat.rb +0 -250
  311. data/lib/puppet/provider/interface/sunos.rb +0 -133
  312. data/lib/puppet/type/interface.rb +0 -60
  313. data/lib/puppet/util/variables.rb +0 -38
  314. data/test/network/handler/configuration.rb +0 -160
  315. data/test/other/propertychange.rb +0 -140
  316. data/test/util/loadedfile.rb +0 -121
@@ -14,24 +14,24 @@ class Puppet::Indirector::ModuleFiles < Puppet::Indirector::Terminus
14
14
  include Puppet::FileServing::TerminusHelper
15
15
 
16
16
  # Is the client allowed access to this key with this method?
17
- def authorized?(method, key, options = {})
18
- return false unless [:find, :search].include?(method)
17
+ def authorized?(request)
18
+ return false unless [:find, :search].include?(request.method)
19
19
 
20
- uri = key2uri(key)
20
+ uri = key2uri(request.key)
21
21
 
22
22
  # Make sure our file path starts with /modules, so that we authorize
23
23
  # against the 'modules' mount.
24
24
  path = uri.path =~ /^\/modules/ ? uri.path : "/modules" + uri.path
25
25
 
26
- configuration.authorized?(path, :node => options[:node], :ipaddress => options[:ipaddress])
26
+ configuration.authorized?(path, :node => request.node, :ipaddress => request.ip)
27
27
  end
28
28
 
29
29
  # Find our key in a module.
30
- def find(key, options = {})
31
- return nil unless path = find_path(key, options)
30
+ def find(request)
31
+ return nil unless path = find_path(request)
32
32
 
33
- result = model.new(key, :path => path)
34
- result.links = options[:links] if options[:links]
33
+ result = model.new(request.key, :path => path)
34
+ result.links = request.options[:links] if request.options[:links]
35
35
  return result
36
36
  end
37
37
 
@@ -41,9 +41,9 @@ class Puppet::Indirector::ModuleFiles < Puppet::Indirector::Terminus
41
41
  end
42
42
 
43
43
  # Search for a list of files.
44
- def search(key, options = {})
45
- return nil unless path = find_path(key, options)
46
- path2instances(key, path, options)
44
+ def search(request)
45
+ return nil unless path = find_path(request)
46
+ path2instances(request, path)
47
47
  end
48
48
 
49
49
  private
@@ -63,15 +63,15 @@ class Puppet::Indirector::ModuleFiles < Puppet::Indirector::Terminus
63
63
  end
64
64
 
65
65
  # The abstracted method for turning a key into a path; used by both :find and :search.
66
- def find_path(key, options)
67
- uri = key2uri(key)
66
+ def find_path(request)
67
+ uri = key2uri(request.key)
68
68
 
69
69
  # Strip off /modules if it's there -- that's how requests get routed to this terminus.
70
70
  # Also, strip off the leading slash if present.
71
71
  module_name, relative_path = uri.path.sub(/^\/modules\b/, '').sub(%r{^/}, '').split(File::Separator, 2)
72
72
 
73
73
  # And use the environment to look up the module.
74
- return nil unless mod = find_module(module_name, options[:node])
74
+ return nil unless mod = find_module(module_name, request.node)
75
75
 
76
76
  path = File.join(mod.files, relative_path)
77
77
 
@@ -15,20 +15,13 @@ class Puppet::Node::Exec < Puppet::Indirector::Exec
15
15
  end
16
16
 
17
17
  # Look for external node definitions.
18
- def find(name)
18
+ def find(request)
19
19
  output = super or return nil
20
20
 
21
21
  # Translate the output to ruby.
22
- result = translate(name, output)
22
+ result = translate(request.key, output)
23
23
 
24
- return create_node(name, result)
25
- end
26
-
27
- # Use the version of the facts, since we assume that's the main thing
28
- # that changes. If someone wants their own way of defining version,
29
- # they can easily provide their own, um, version of this class.
30
- def version(name)
31
- Puppet::Node::Facts.version(name)
24
+ return create_node(request.key, result)
32
25
  end
33
26
 
34
27
  private
@@ -3,7 +3,9 @@ require 'puppet/indirector/ldap'
3
3
 
4
4
  class Puppet::Node::Ldap < Puppet::Indirector::Ldap
5
5
  desc "Search in LDAP for node configuration information. See
6
- the `LdapNodes`:trac: page for more information."
6
+ the `LdapNodes`:trac: page for more information. This will first
7
+ search for whatever the certificate name is, then (if that name
8
+ contains a '.') for the short name, then 'default'."
7
9
 
8
10
  # The attributes that Puppet class information is stored in.
9
11
  def class_attributes
@@ -11,43 +13,53 @@ class Puppet::Node::Ldap < Puppet::Indirector::Ldap
11
13
  x = Puppet[:ldapclassattrs].split(/\s*,\s*/)
12
14
  end
13
15
 
14
- # Look for our node in ldap.
15
- def find(name)
16
- return nil unless information = super
17
- node = Puppet::Node.new(name)
16
+ # Separate this out so it's relatively atomic. It's tempting to call
17
+ # process() instead of name2hash() here, but it ends up being
18
+ # difficult to test because all exceptions get caught by ldapsearch.
19
+ # LAK:NOTE Unfortunately, the ldap support is too stupid to throw anything
20
+ # but LDAP::ResultError, even on bad connections, so we are rough handed
21
+ # with our error handling.
22
+ def name2hash(name)
23
+ info = nil
24
+ ldapsearch(search_filter(name)) { |entry| info = entry2hash(entry) }
25
+ return info
26
+ end
18
27
 
19
- parent_info = nil
20
- parent = information[:parent]
21
- parents = [name]
22
- while parent
23
- if parents.include?(parent)
24
- raise ArgumentError, "Found loop in LDAP node parents; %s appears twice" % parent
25
- end
26
- parents << parent
28
+ # Look for our node in ldap.
29
+ def find(request)
30
+ names = [request.key]
31
+ if request.key.include?(".") # we assume it's an fqdn
32
+ names << request.key.sub(/\..+/, '')
33
+ end
34
+ names << "default"
27
35
 
28
- ldapsearch(parent) { |entry| parent_info = process(parent, entry) }
36
+ node = nil
37
+ names.each do |name|
38
+ next unless info = name2hash(name)
29
39
 
30
- unless parent_info
31
- raise Puppet::Error.new("Could not find parent node '%s'" % parent)
32
- end
33
- information[:classes] += parent_info[:classes]
34
- parent_info[:parameters].each do |param, value|
35
- # Specifically test for whether it's set, so false values are handled
36
- # correctly.
37
- information[:parameters][param] = value unless information[:parameters].include?(param)
38
- end
40
+ break if node = info2node(request.key, info)
41
+ end
39
42
 
40
- information[:environment] ||= parent_info[:environment]
43
+ return node
44
+ end
41
45
 
42
- parent = parent_info[:parent]
46
+ # Find more than one node. LAK:NOTE This is a bit of a clumsy API, because the 'search'
47
+ # method currently *requires* a key. It seems appropriate in some cases but not others,
48
+ # and I don't really know how to get rid of it as a requirement but allow it when desired.
49
+ def search(request)
50
+ if classes = request.options[:class]
51
+ classes = [classes] unless classes.is_a?(Array)
52
+ filter = "(&(objectclass=puppetClient)(puppetclass=" + classes.join(")(puppetclass=") + "))"
53
+ else
54
+ filter = "(objectclass=puppetClient)"
43
55
  end
44
56
 
45
- node.classes = information[:classes].uniq unless information[:classes].empty?
46
- node.parameters = information[:parameters] unless information[:parameters].empty?
47
- node.environment = information[:environment] if information[:environment]
48
- node.fact_merge
57
+ infos = []
58
+ ldapsearch(filter) { |entry| infos << entry2hash(entry) }
49
59
 
50
- return node
60
+ return infos.collect do |info|
61
+ info2node(info[:name], info)
62
+ end
51
63
  end
52
64
 
53
65
  # The parent attribute, if we have one.
@@ -59,15 +71,21 @@ class Puppet::Node::Ldap < Puppet::Indirector::Ldap
59
71
  end
60
72
  end
61
73
 
62
- # Process the found entry. We assume that we don't just want the
63
- # ldap object.
64
- def process(name, entry)
74
+ # The attributes that Puppet will stack as array over the full
75
+ # hierarchy.
76
+ def stacked_attributes
77
+ Puppet[:ldapstackedattrs].split(/\s*,\s*/)
78
+ end
79
+
80
+ # Convert the found entry into a simple hash.
81
+ def entry2hash(entry)
65
82
  result = {}
83
+ result[:name] = entry.dn.split(',')[0].split("=")[1]
66
84
  if pattr = parent_attribute
67
85
  if values = entry.vals(pattr)
68
86
  if values.length > 1
69
87
  raise Puppet::Error,
70
- "Node %s has more than one parent: %s" % [name, values.inspect]
88
+ "Node entry %s specifies more than one parent: %s" % [entry.dn, values.inspect]
71
89
  end
72
90
  unless values.empty?
73
91
  result[:parent] = values.shift
@@ -81,19 +99,46 @@ class Puppet::Node::Ldap < Puppet::Indirector::Ldap
81
99
  values.each do |v| result[:classes] << v end
82
100
  end
83
101
  }
102
+ result[:classes].uniq!
103
+
104
+ result[:stacked] = []
105
+ stacked_params = stacked_attributes
106
+ stacked_params.each { |attr|
107
+ if values = entry.vals(attr)
108
+ result[:stacked] = result[:stacked] + values
109
+ end
110
+ }
111
+
84
112
 
85
113
  result[:parameters] = entry.to_hash.inject({}) do |hash, ary|
86
- if ary[1].length == 1
87
- hash[ary[0]] = ary[1].shift
88
- else
89
- hash[ary[0]] = ary[1]
114
+ unless stacked_params.include?(ary[0]) # don't add our stacked parameters to the main param list
115
+ if ary[1].length == 1
116
+ hash[ary[0]] = ary[1].shift
117
+ else
118
+ hash[ary[0]] = ary[1]
119
+ end
90
120
  end
91
121
  hash
92
122
  end
93
123
 
94
124
  result[:environment] = result[:parameters]["environment"] if result[:parameters]["environment"]
95
125
 
96
- return result
126
+ result[:stacked_parameters] = {}
127
+
128
+ if result[:stacked]
129
+ result[:stacked].each do |value|
130
+ param = value.split('=', 2)
131
+ result[:stacked_parameters][param[0]] = param[1]
132
+ end
133
+ end
134
+
135
+ if result[:stacked_parameters]
136
+ result[:stacked_parameters].each do |param, value|
137
+ result[:parameters][param] = value unless result[:parameters].include?(param)
138
+ end
139
+ end
140
+
141
+ result
97
142
  end
98
143
 
99
144
  # Default to all attributes.
@@ -124,7 +169,59 @@ class Puppet::Node::Ldap < Puppet::Indirector::Ldap
124
169
  filter
125
170
  end
126
171
 
127
- def version(name)
128
- Puppet::Node::Facts.version(name)
172
+ private
173
+
174
+ # Add our hash of ldap information to the node instance.
175
+ def add_to_node(node, information)
176
+ node.classes = information[:classes].uniq unless information[:classes].nil? or information[:classes].empty?
177
+ node.parameters = information[:parameters] unless information[:parameters].nil? or information[:parameters].empty?
178
+ node.environment = information[:environment] if information[:environment]
179
+ end
180
+
181
+ # Find information for our parent and merge it into the current info.
182
+ def find_and_merge_parent(parent, information)
183
+ unless parent_info = name2hash(parent)
184
+ raise Puppet::Error.new("Could not find parent node '%s'" % parent)
185
+ end
186
+ information[:classes] += parent_info[:classes]
187
+ parent_info[:parameters].each do |param, value|
188
+ # Specifically test for whether it's set, so false values are handled
189
+ # correctly.
190
+ information[:parameters][param] = value unless information[:parameters].include?(param)
191
+ end
192
+
193
+ information[:environment] ||= parent_info[:environment]
194
+
195
+ parent_info[:parent]
196
+ end
197
+
198
+ # Take a name and a hash, and return a node instance.
199
+ def info2node(name, info)
200
+ merge_parent(info) if info[:parent]
201
+
202
+ node = Puppet::Node.new(name)
203
+
204
+ add_to_node(node, info)
205
+
206
+ node.fact_merge
207
+
208
+ node
209
+ end
210
+
211
+ def merge_parent(info)
212
+ parent_info = nil
213
+ parent = info[:parent]
214
+
215
+ # Preload the parent array with the node name.
216
+ parents = [info[:name]]
217
+ while parent
218
+ if parents.include?(parent)
219
+ raise ArgumentError, "Found loop in LDAP node parents; %s appears twice" % parent
220
+ end
221
+ parents << parent
222
+ parent = find_and_merge_parent(parent, info)
223
+ end
224
+
225
+ return info
129
226
  end
130
227
  end
@@ -11,16 +11,9 @@ class Puppet::Node::Plain < Puppet::Indirector::Plain
11
11
  node instance before it is returned."
12
12
 
13
13
  # Just return an empty node.
14
- def find(name)
14
+ def find(request)
15
15
  node = super
16
16
  node.fact_merge
17
17
  node
18
18
  end
19
-
20
- # Use the version of the facts, since we assume that's the main thing
21
- # that changes. If someone wants their own way of defining version,
22
- # they can easily provide their own, um, version of this class.
23
- def version(name)
24
- Puppet::Node::Facts.version(name)
25
- end
26
19
  end
@@ -1,7 +1,7 @@
1
1
  require 'puppet/node'
2
2
  require 'puppet/indirector/rest'
3
3
 
4
- class Puppet::Node::REST < Puppet::Indirector::REST
4
+ class Puppet::Node::Rest < Puppet::Indirector::REST
5
5
  desc "This will eventually be a REST-based mechanism for finding nodes. It is currently non-functional."
6
6
  # TODO/FIXME
7
7
  end
@@ -3,7 +3,7 @@ require 'puppet/indirector/terminus'
3
3
  # An empty terminus type, meant to just return empty objects.
4
4
  class Puppet::Indirector::Plain < Puppet::Indirector::Terminus
5
5
  # Just return nothing.
6
- def find(name)
7
- indirection.model.new(name)
6
+ def find(request)
7
+ indirection.model.new(request.key)
8
8
  end
9
9
  end
@@ -10,8 +10,8 @@ class Puppet::Transaction::Report::Processor < Puppet::Indirector::Code
10
10
  Puppet.settings.use(:main, :reporting, :metrics)
11
11
  end
12
12
 
13
- def save(report)
14
- process(report)
13
+ def save(request)
14
+ process(request.instance)
15
15
  end
16
16
 
17
17
  private
@@ -0,0 +1,42 @@
1
+ require 'puppet/indirector'
2
+
3
+ # Provide any attributes or functionality needed for indirected
4
+ # instances.
5
+ class Puppet::Indirector::Request
6
+ attr_accessor :indirection_name, :key, :method, :options, :instance, :node, :ip, :authenticated
7
+
8
+ # Is this an authenticated request?
9
+ def authenticated?
10
+ # Double negative, so we just get true or false
11
+ ! ! authenticated
12
+ end
13
+
14
+ def initialize(indirection_name, method, key, options = {})
15
+ options ||= {}
16
+ raise ArgumentError, "Request options must be a hash, not %s" % options.class unless options.is_a?(Hash)
17
+
18
+ @indirection_name, @method = indirection_name, method
19
+
20
+ @options = options.inject({}) do |result, ary|
21
+ param, value = ary
22
+ if respond_to?(param.to_s + "=")
23
+ send(param.to_s + "=", value)
24
+ else
25
+ result[param] = value
26
+ end
27
+ result
28
+ end
29
+
30
+ if key.is_a?(String) or key.is_a?(Symbol)
31
+ @key = key
32
+ else
33
+ @instance = key
34
+ @key = @instance.name
35
+ end
36
+ end
37
+
38
+ # Look up the indirection based on the name provided.
39
+ def indirection
40
+ Puppet::Indirector::Indirection.instance(@indirection_name)
41
+ end
42
+ end
@@ -1,8 +1,56 @@
1
- require 'puppet/indirector/rest'
1
+ require 'net/http'
2
+ require 'uri'
2
3
 
3
4
  # Access objects via REST
4
5
  class Puppet::Indirector::REST < Puppet::Indirector::Terminus
5
- def find(name, options = {})
6
- indirection.model.new(name)
6
+
7
+ def rest_connection_details
8
+ { :host => Puppet[:server], :port => Puppet[:masterport].to_i }
9
+ end
10
+
11
+ def network_fetch(path)
12
+ network {|conn| conn.get("/#{path}").body }
13
+ end
14
+
15
+ def network_delete(path)
16
+ network {|conn| conn.delete("/#{path}").body }
17
+ end
18
+
19
+ def network_put(path, data)
20
+ network {|conn| conn.put("/#{path}", data).body }
21
+ end
22
+
23
+ def find(request)
24
+ network_result = network_fetch("#{indirection.name}/#{request.key}")
25
+ raise YAML.load(network_result) if exception?(network_result)
26
+ indirection.model.from_yaml(network_result)
27
+ end
28
+
29
+ def search(request)
30
+ network_results = network_fetch("#{indirection.name}s/#{request.key}")
31
+ raise YAML.load(network_results) if exception?(network_results)
32
+ YAML.load(network_results.to_s).collect {|result| indirection.model.from_yaml(result) }
33
+ end
34
+
35
+ def destroy(request)
36
+ network_result = network_delete("#{indirection.name}/#{request.key}")
37
+ raise YAML.load(network_result) if exception?(network_result)
38
+ YAML.load(network_result.to_s)
39
+ end
40
+
41
+ def save(request)
42
+ network_result = network_put("#{indirection.name}/", request.instance.to_yaml)
43
+ raise YAML.load(network_result) if exception?(network_result)
44
+ indirection.model.from_yaml(network_result)
45
+ end
46
+
47
+ private
48
+
49
+ def network(&block)
50
+ Net::HTTP.start(rest_connection_details[:host], rest_connection_details[:port]) {|conn| yield(conn) }
51
+ end
52
+
53
+ def exception?(yaml_string)
54
+ yaml_string =~ %r{--- !ruby/exception}
7
55
  end
8
56
  end