puppet 3.1.1 → 3.2.0.rc1

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 (477) hide show
  1. data/CONTRIBUTING.md +2 -2
  2. data/Gemfile +32 -19
  3. data/README_DEVELOPER.md +332 -14
  4. data/Rakefile +9 -5
  5. data/ext/build_defaults.yaml +2 -3
  6. data/ext/debian/changelog.erb +6 -0
  7. data/ext/debian/control +6 -6
  8. data/ext/envpuppet +4 -4
  9. data/ext/project_data.yaml +1 -0
  10. data/ext/puppet-nm-dispatcher +13 -0
  11. data/ext/redhat/puppet.spec.erb +17 -0
  12. data/ext/suse/client.init +1 -1
  13. data/ext/systemd/puppetagent.service +2 -2
  14. data/ext/systemd/puppetmaster.service +2 -2
  15. data/lib/hiera/scope.rb +29 -11
  16. data/lib/hiera_puppet.rb +1 -3
  17. data/lib/puppet/agent.rb +3 -3
  18. data/lib/puppet/application.rb +2 -2
  19. data/lib/puppet/application/agent.rb +27 -12
  20. data/lib/puppet/application/apply.rb +11 -1
  21. data/lib/puppet/application/describe.rb +1 -1
  22. data/lib/puppet/application/doc.rb +13 -9
  23. data/lib/puppet/application/filebucket.rb +0 -1
  24. data/lib/puppet/application/kick.rb +1 -0
  25. data/lib/puppet/application/master.rb +16 -8
  26. data/lib/puppet/daemon.rb +19 -64
  27. data/lib/puppet/defaults.rb +61 -5
  28. data/lib/puppet/error.rb +15 -4
  29. data/lib/puppet/external/nagios/grammar.ry +1 -1
  30. data/lib/puppet/external/nagios/makefile +1 -1
  31. data/lib/puppet/external/nagios/parser.rb +185 -618
  32. data/lib/puppet/external/pson/pure/parser.rb +47 -1
  33. data/lib/puppet/face/certificate.rb +3 -3
  34. data/lib/puppet/face/module.rb +1 -1
  35. data/lib/puppet/face/module/changes.rb +3 -1
  36. data/lib/puppet/face/module/uninstall.rb +1 -1
  37. data/lib/puppet/face/node/clean.rb +5 -5
  38. data/lib/puppet/feature/base.rb +3 -1
  39. data/lib/puppet/feature/libuser.rb +8 -0
  40. data/lib/puppet/file_serving/fileset.rb +9 -1
  41. data/lib/puppet/forge.rb +28 -5
  42. data/lib/puppet/forge/errors.rb +34 -0
  43. data/lib/puppet/forge/repository.rb +1 -1
  44. data/lib/puppet/indirector.rb +4 -1
  45. data/lib/puppet/indirector/catalog/compiler.rb +37 -30
  46. data/lib/puppet/indirector/facts/inventory_active_record.rb +1 -0
  47. data/lib/puppet/indirector/indirection.rb +28 -15
  48. data/lib/puppet/indirector/rest.rb +18 -10
  49. data/lib/puppet/interface.rb +11 -4
  50. data/lib/puppet/interface/action.rb +1 -3
  51. data/lib/puppet/interface/action_builder.rb +0 -3
  52. data/lib/puppet/interface/action_manager.rb +0 -3
  53. data/lib/puppet/interface/face_collection.rb +0 -2
  54. data/lib/puppet/interface/option.rb +0 -2
  55. data/lib/puppet/interface/option_builder.rb +0 -2
  56. data/lib/puppet/interface/option_manager.rb +0 -2
  57. data/lib/puppet/metatype/manager.rb +1 -1
  58. data/lib/puppet/module_tool.rb +1 -0
  59. data/lib/puppet/module_tool/applications/application.rb +0 -3
  60. data/lib/puppet/module_tool/applications/builder.rb +8 -20
  61. data/lib/puppet/module_tool/applications/checksummer.rb +1 -1
  62. data/lib/puppet/module_tool/applications/installer.rb +1 -0
  63. data/lib/puppet/module_tool/applications/unpacker.rb +3 -11
  64. data/lib/puppet/module_tool/checksums.rb +1 -1
  65. data/lib/puppet/module_tool/errors/installer.rb +18 -1
  66. data/lib/puppet/module_tool/modulefile.rb +2 -2
  67. data/lib/puppet/module_tool/skeleton/templates/generator/Modulefile.erb +1 -1
  68. data/lib/puppet/module_tool/tar.rb +17 -0
  69. data/lib/puppet/module_tool/tar/gnu.rb +9 -0
  70. data/lib/puppet/module_tool/tar/mini.rb +39 -0
  71. data/lib/puppet/module_tool/tar/solaris.rb +5 -0
  72. data/lib/puppet/network/http.rb +1 -0
  73. data/lib/puppet/network/http/connection.rb +9 -23
  74. data/lib/puppet/network/http/handler.rb +38 -7
  75. data/lib/puppet/network/http/rack/rest.rb +14 -3
  76. data/lib/puppet/network/http/webrick.rb +3 -1
  77. data/lib/puppet/network/http/webrick/rest.rb +11 -2
  78. data/lib/puppet/node/environment.rb +3 -1
  79. data/lib/puppet/parameter.rb +32 -29
  80. data/lib/puppet/parameter/package_options.rb +1 -1
  81. data/lib/puppet/parameter/path.rb +1 -1
  82. data/lib/puppet/parameter/value.rb +1 -1
  83. data/lib/puppet/parameter/value_collection.rb +7 -3
  84. data/lib/puppet/parser/ast.rb +3 -1
  85. data/lib/puppet/parser/ast/arithmetic_operator.rb +56 -12
  86. data/lib/puppet/parser/ast/astarray.rb +1 -1
  87. data/lib/puppet/parser/ast/block_expression.rb +41 -0
  88. data/lib/puppet/parser/ast/function.rb +13 -2
  89. data/lib/puppet/parser/ast/lambda.rb +107 -0
  90. data/lib/puppet/parser/ast/leaf.rb +1 -2
  91. data/lib/puppet/parser/ast/method_call.rb +77 -0
  92. data/lib/puppet/parser/ast/vardef.rb +7 -0
  93. data/lib/puppet/parser/compiler.rb +27 -16
  94. data/lib/puppet/parser/e_parser_adapter.rb +120 -0
  95. data/lib/puppet/parser/files.rb +7 -6
  96. data/lib/puppet/parser/functions.rb +10 -8
  97. data/lib/puppet/parser/functions/collect.rb +43 -0
  98. data/lib/puppet/parser/functions/each.rb +96 -0
  99. data/lib/puppet/parser/functions/foreach.rb +96 -0
  100. data/lib/puppet/parser/functions/fqdn_rand.rb +2 -2
  101. data/lib/puppet/parser/functions/hiera.rb +20 -2
  102. data/lib/puppet/parser/functions/hiera_array.rb +21 -2
  103. data/lib/puppet/parser/functions/hiera_hash.rb +23 -2
  104. data/lib/puppet/parser/functions/hiera_include.rb +33 -2
  105. data/lib/puppet/parser/functions/inline_template.rb +4 -4
  106. data/lib/puppet/parser/functions/reduce.rb +74 -0
  107. data/lib/puppet/parser/functions/reject.rb +46 -0
  108. data/lib/puppet/parser/functions/select.rb +46 -0
  109. data/lib/puppet/parser/functions/slice.rb +96 -0
  110. data/lib/puppet/parser/functions/template.rb +2 -2
  111. data/lib/puppet/parser/grammar.ra +7 -4
  112. data/lib/puppet/parser/lexer.rb +10 -0
  113. data/lib/puppet/parser/methods.rb +69 -0
  114. data/lib/puppet/parser/parser.rb +855 -808
  115. data/lib/puppet/parser/parser_factory.rb +62 -0
  116. data/lib/puppet/parser/parser_support.rb +8 -2
  117. data/lib/puppet/parser/scope.rb +153 -47
  118. data/lib/puppet/parser/templatewrapper.rb +28 -21
  119. data/lib/puppet/parser/type_loader.rb +3 -1
  120. data/lib/puppet/pops.rb +40 -0
  121. data/lib/puppet/pops/adaptable.rb +190 -0
  122. data/lib/puppet/pops/adapters.rb +65 -0
  123. data/lib/puppet/pops/containment.rb +37 -0
  124. data/lib/puppet/pops/issues.rb +258 -0
  125. data/lib/puppet/pops/label_provider.rb +71 -0
  126. data/lib/puppet/pops/model/ast_transformer.rb +636 -0
  127. data/lib/puppet/pops/model/ast_tree_dumper.rb +378 -0
  128. data/lib/puppet/pops/model/factory.rb +804 -0
  129. data/lib/puppet/pops/model/model.rb +567 -0
  130. data/lib/puppet/pops/model/model_label_provider.rb +75 -0
  131. data/lib/puppet/pops/model/model_tree_dumper.rb +352 -0
  132. data/lib/puppet/pops/model/tree_dumper.rb +59 -0
  133. data/lib/puppet/pops/parser/egrammar.ra +723 -0
  134. data/lib/puppet/pops/parser/eparser.rb +2300 -0
  135. data/lib/puppet/pops/parser/grammar.ra +746 -0
  136. data/lib/puppet/pops/parser/lexer.rb +842 -0
  137. data/lib/puppet/pops/parser/makefile +13 -0
  138. data/lib/puppet/pops/parser/parser_support.rb +203 -0
  139. data/lib/puppet/pops/patterns.rb +35 -0
  140. data/lib/puppet/pops/utils.rb +104 -0
  141. data/lib/puppet/pops/validation.rb +297 -0
  142. data/lib/puppet/pops/validation/checker3_1.rb +551 -0
  143. data/lib/puppet/pops/validation/validator_factory_3_1.rb +41 -0
  144. data/lib/puppet/pops/visitable.rb +6 -0
  145. data/lib/puppet/pops/visitor.rb +50 -0
  146. data/lib/puppet/property.rb +37 -28
  147. data/lib/puppet/property/ensure.rb +2 -2
  148. data/lib/puppet/property/ordered_list.rb +1 -1
  149. data/lib/puppet/provider.rb +26 -30
  150. data/lib/puppet/provider/aixobject.rb +45 -44
  151. data/lib/puppet/provider/augeas/augeas.rb +0 -1
  152. data/lib/puppet/provider/confiner.rb +1 -1
  153. data/lib/puppet/provider/cron/crontab.rb +107 -67
  154. data/lib/puppet/provider/group/groupadd.rb +59 -3
  155. data/lib/puppet/provider/interface/cisco.rb +4 -4
  156. data/lib/puppet/provider/mount/parsed.rb +1 -1
  157. data/lib/puppet/provider/nameservice.rb +22 -6
  158. data/lib/puppet/provider/nameservice/pw.rb +1 -1
  159. data/lib/puppet/provider/package/aix.rb +28 -4
  160. data/lib/puppet/provider/package/gem.rb +0 -2
  161. data/lib/puppet/provider/package/macports.rb +1 -1
  162. data/lib/puppet/provider/package/nim.rb +249 -4
  163. data/lib/puppet/provider/package/opkg.rb +77 -0
  164. data/lib/puppet/provider/package/pacman.rb +2 -2
  165. data/lib/puppet/provider/package/rpm.rb +30 -16
  166. data/lib/puppet/provider/package/yum.rb +3 -3
  167. data/lib/puppet/provider/parsedfile.rb +80 -3
  168. data/lib/puppet/provider/selmodule/semodule.rb +2 -2
  169. data/lib/puppet/provider/service/debian.rb +0 -4
  170. data/lib/puppet/provider/service/freebsd.rb +2 -2
  171. data/lib/puppet/provider/service/gentoo.rb +0 -9
  172. data/lib/puppet/provider/service/init.rb +27 -2
  173. data/lib/puppet/provider/service/launchd.rb +1 -1
  174. data/lib/puppet/provider/service/openwrt.rb +36 -0
  175. data/lib/puppet/provider/service/redhat.rb +0 -9
  176. data/lib/puppet/provider/service/src.rb +38 -4
  177. data/lib/puppet/provider/service/systemd.rb +2 -2
  178. data/lib/puppet/provider/service/upstart.rb +1 -8
  179. data/lib/puppet/provider/user/aix.rb +4 -10
  180. data/lib/puppet/provider/user/pw.rb +6 -10
  181. data/lib/puppet/provider/user/useradd.rb +129 -31
  182. data/lib/puppet/provider/vlan/cisco.rb +4 -4
  183. data/lib/puppet/reference/function.rb +2 -2
  184. data/lib/puppet/reference/indirection.rb +46 -5
  185. data/lib/puppet/reference/metaparameter.rb +2 -2
  186. data/lib/puppet/reports.rb +5 -5
  187. data/lib/puppet/reports/rrdgraph.rb +4 -4
  188. data/lib/puppet/reports/tagmail.rb +1 -1
  189. data/lib/puppet/resource.rb +1 -1
  190. data/lib/puppet/resource/type.rb +13 -11
  191. data/lib/puppet/scheduler.rb +16 -0
  192. data/lib/puppet/scheduler/job.rb +53 -0
  193. data/lib/puppet/scheduler/scheduler.rb +45 -0
  194. data/lib/puppet/scheduler/splay_job.rb +32 -0
  195. data/lib/puppet/scheduler/timer.rb +13 -0
  196. data/lib/puppet/settings/base_setting.rb +1 -1
  197. data/lib/puppet/simple_graph.rb +4 -4
  198. data/lib/puppet/ssl/base.rb +12 -2
  199. data/lib/puppet/ssl/certificate.rb +4 -1
  200. data/lib/puppet/ssl/certificate_request.rb +4 -1
  201. data/lib/puppet/ssl/certificate_revocation_list.rb +4 -1
  202. data/lib/puppet/ssl/configuration.rb +32 -0
  203. data/lib/puppet/ssl/host.rb +18 -21
  204. data/lib/puppet/ssl/key.rb +4 -1
  205. data/lib/puppet/ssl/validator.rb +116 -0
  206. data/lib/puppet/transaction.rb +1 -1
  207. data/lib/puppet/transaction/event.rb +3 -10
  208. data/lib/puppet/transaction/event_manager.rb +8 -1
  209. data/lib/puppet/transaction/report.rb +17 -16
  210. data/lib/puppet/type.rb +77 -69
  211. data/lib/puppet/type/cron.rb +20 -8
  212. data/lib/puppet/type/exec.rb +9 -3
  213. data/lib/puppet/type/file.rb +95 -21
  214. data/lib/puppet/type/file/content.rb +1 -1
  215. data/lib/puppet/type/file/mode.rb +7 -1
  216. data/lib/puppet/type/file/source.rb +2 -2
  217. data/lib/puppet/type/group.rb +11 -0
  218. data/lib/puppet/type/scheduled_task.rb +5 -1
  219. data/lib/puppet/type/service.rb +1 -1
  220. data/lib/puppet/type/ssh_authorized_key.rb +2 -2
  221. data/lib/puppet/type/user.rb +24 -6
  222. data/lib/puppet/util.rb +12 -2
  223. data/lib/puppet/util/classgen.rb +4 -4
  224. data/lib/puppet/util/colors.rb +55 -0
  225. data/lib/puppet/util/command_line/trollop.rb +4 -4
  226. data/lib/puppet/util/errors.rb +39 -3
  227. data/lib/puppet/util/fileparsing.rb +5 -0
  228. data/lib/puppet/util/filetype.rb +11 -9
  229. data/lib/puppet/util/instrumentation/instrumentable.rb +2 -2
  230. data/lib/puppet/util/libuser.conf +15 -0
  231. data/lib/puppet/util/libuser.rb +12 -0
  232. data/lib/puppet/util/monkey_patches.rb +48 -0
  233. data/lib/puppet/util/network_device.rb +1 -1
  234. data/lib/puppet/util/network_device/base.rb +2 -2
  235. data/lib/puppet/util/network_device/cisco/device.rb +29 -19
  236. data/lib/puppet/util/network_device/config.rb +5 -2
  237. data/lib/puppet/util/network_device/ipcalc.rb +1 -1
  238. data/lib/puppet/util/network_device/transport/ssh.rb +4 -3
  239. data/lib/puppet/util/network_device/transport/telnet.rb +4 -2
  240. data/lib/puppet/util/plugins.rb +4 -4
  241. data/lib/puppet/util/posix.rb +1 -1
  242. data/lib/puppet/util/profiler.rb +28 -0
  243. data/lib/puppet/util/profiler/logging.rb +47 -0
  244. data/lib/puppet/util/profiler/none.rb +8 -0
  245. data/lib/puppet/util/profiler/object_counts.rb +17 -0
  246. data/lib/puppet/util/profiler/wall_clock.rb +34 -0
  247. data/lib/puppet/util/provider_features.rb +1 -1
  248. data/lib/puppet/util/rdoc/parser.rb +5 -5
  249. data/lib/puppet/util/ssl.rb +38 -0
  250. data/lib/puppet/util/subclass_loader.rb +1 -5
  251. data/lib/puppet/util/windows.rb +1 -0
  252. data/lib/puppet/util/windows/process.rb +3 -0
  253. data/lib/puppet/util/windows/root_certs.rb +86 -0
  254. data/lib/puppet/util/windows/security.rb +1 -0
  255. data/lib/puppet/version.rb +1 -1
  256. data/spec/fixtures/integration/provider/cron/crontab/create_normal_entry +19 -0
  257. data/spec/fixtures/integration/provider/cron/crontab/create_special_entry +18 -0
  258. data/spec/fixtures/integration/provider/cron/crontab/crontab_user1 +15 -0
  259. data/spec/fixtures/integration/provider/cron/crontab/crontab_user2 +4 -0
  260. data/spec/fixtures/integration/provider/cron/crontab/modify_entry +13 -0
  261. data/spec/fixtures/integration/provider/cron/crontab/moved_cronjob_input1 +15 -0
  262. data/spec/fixtures/integration/provider/cron/crontab/moved_cronjob_input2 +6 -0
  263. data/spec/fixtures/integration/provider/cron/crontab/remove_named_resource +12 -0
  264. data/spec/fixtures/integration/provider/cron/crontab/remove_unnamed_resource +14 -0
  265. data/spec/fixtures/unit/pops/parser/lexer/aliastest.pp +16 -0
  266. data/spec/fixtures/unit/pops/parser/lexer/append.pp +11 -0
  267. data/spec/fixtures/unit/pops/parser/lexer/argumentdefaults.pp +14 -0
  268. data/spec/fixtures/unit/pops/parser/lexer/arithmetic_expression.pp +8 -0
  269. data/spec/fixtures/unit/pops/parser/lexer/arraytrailingcomma.pp +3 -0
  270. data/spec/fixtures/unit/pops/parser/lexer/casestatement.pp +65 -0
  271. data/spec/fixtures/unit/pops/parser/lexer/classheirarchy.pp +15 -0
  272. data/spec/fixtures/unit/pops/parser/lexer/classincludes.pp +17 -0
  273. data/spec/fixtures/unit/pops/parser/lexer/classpathtest.pp +11 -0
  274. data/spec/fixtures/unit/pops/parser/lexer/collection.pp +10 -0
  275. data/spec/fixtures/unit/pops/parser/lexer/collection_override.pp +8 -0
  276. data/spec/fixtures/unit/pops/parser/lexer/collection_within_virtual_definitions.pp +20 -0
  277. data/spec/fixtures/unit/pops/parser/lexer/componentmetaparams.pp +11 -0
  278. data/spec/fixtures/unit/pops/parser/lexer/componentrequire.pp +8 -0
  279. data/spec/fixtures/unit/pops/parser/lexer/deepclassheirarchy.pp +23 -0
  280. data/spec/fixtures/unit/pops/parser/lexer/defineoverrides.pp +17 -0
  281. data/spec/fixtures/unit/pops/parser/lexer/emptyclass.pp +9 -0
  282. data/spec/fixtures/unit/pops/parser/lexer/emptyexec.pp +3 -0
  283. data/spec/fixtures/unit/pops/parser/lexer/emptyifelse.pp +9 -0
  284. data/spec/fixtures/unit/pops/parser/lexer/falsevalues.pp +3 -0
  285. data/spec/fixtures/unit/pops/parser/lexer/filecreate.pp +11 -0
  286. data/spec/fixtures/unit/pops/parser/lexer/fqdefinition.pp +5 -0
  287. data/spec/fixtures/unit/pops/parser/lexer/fqparents.pp +11 -0
  288. data/spec/fixtures/unit/pops/parser/lexer/funccomma.pp +5 -0
  289. data/spec/fixtures/unit/pops/parser/lexer/hash.pp +33 -0
  290. data/spec/fixtures/unit/pops/parser/lexer/ifexpression.pp +12 -0
  291. data/spec/fixtures/unit/pops/parser/lexer/implicititeration.pp +15 -0
  292. data/spec/fixtures/unit/pops/parser/lexer/multilinecomments.pp +10 -0
  293. data/spec/fixtures/unit/pops/parser/lexer/multipleclass.pp +9 -0
  294. data/spec/fixtures/unit/pops/parser/lexer/multipleinstances.pp +7 -0
  295. data/spec/fixtures/unit/pops/parser/lexer/multisubs.pp +13 -0
  296. data/spec/fixtures/unit/pops/parser/lexer/namevartest.pp +9 -0
  297. data/spec/fixtures/unit/pops/parser/lexer/scopetest.pp +13 -0
  298. data/spec/fixtures/unit/pops/parser/lexer/selectorvalues.pp +49 -0
  299. data/spec/fixtures/unit/pops/parser/lexer/simpledefaults.pp +5 -0
  300. data/spec/fixtures/unit/pops/parser/lexer/simpleselector.pp +38 -0
  301. data/spec/fixtures/unit/pops/parser/lexer/singleary.pp +19 -0
  302. data/spec/fixtures/unit/pops/parser/lexer/singlequote.pp +11 -0
  303. data/spec/fixtures/unit/pops/parser/lexer/singleselector.pp +22 -0
  304. data/spec/fixtures/unit/pops/parser/lexer/subclass_name_duplication.pp +11 -0
  305. data/spec/fixtures/unit/pops/parser/lexer/tag.pp +9 -0
  306. data/spec/fixtures/unit/pops/parser/lexer/tagged.pp +35 -0
  307. data/spec/fixtures/unit/pops/parser/lexer/virtualresources.pp +14 -0
  308. data/spec/fixtures/unit/provider/cron/crontab/single_line.yaml +4 -4
  309. data/spec/fixtures/unit/provider/cron/crontab/vixie_header.txt +3 -0
  310. data/spec/fixtures/unit/provider/cron/parsed/managed +6 -0
  311. data/spec/fixtures/unit/provider/cron/parsed/simple +9 -0
  312. data/spec/fixtures/unit/provider/parsedfile/simple.txt +4 -0
  313. data/spec/fixtures/unit/provider/service/systemd/list_units +18 -0
  314. data/spec/integration/parser/collector_spec.rb +1 -1
  315. data/spec/integration/parser/compiler_spec.rb +252 -227
  316. data/spec/integration/parser/parser_spec.rb +171 -53
  317. data/spec/integration/parser/scope_spec.rb +1 -1
  318. data/spec/integration/provider/cron/crontab_spec.rb +187 -0
  319. data/spec/integration/provider/service/systemd_spec.rb +20 -0
  320. data/spec/integration/type/file_spec.rb +21 -21
  321. data/spec/integration/type/package_spec.rb +1 -1
  322. data/spec/lib/puppet_spec/database.rb +2 -5
  323. data/spec/spec_helper.rb +6 -1
  324. data/spec/unit/application/apply_spec.rb +16 -1
  325. data/spec/unit/application/describe_spec.rb +1 -1
  326. data/spec/unit/application/doc_spec.rb +55 -32
  327. data/spec/unit/application/kick_spec.rb +8 -6
  328. data/spec/unit/application/master_spec.rb +4 -4
  329. data/spec/unit/daemon_spec.rb +1 -1
  330. data/spec/unit/forge/errors_spec.rb +40 -0
  331. data/spec/unit/forge/repository_spec.rb +11 -1
  332. data/spec/unit/forge_spec.rb +13 -3
  333. data/spec/unit/hiera/backend/puppet_backend_spec.rb +1 -0
  334. data/spec/unit/hiera/scope_spec.rb +48 -25
  335. data/spec/unit/indirector/catalog/active_record_spec.rb +6 -3
  336. data/spec/unit/indirector/catalog/compiler_spec.rb +3 -28
  337. data/spec/unit/indirector/catalog/static_compiler_spec.rb +1 -1
  338. data/spec/unit/indirector/facts/inventory_active_record_spec.rb +154 -150
  339. data/spec/unit/indirector/indirection_spec.rb +5 -0
  340. data/spec/unit/indirector/resource/active_record_spec.rb +5 -22
  341. data/spec/unit/indirector_spec.rb +7 -1
  342. data/spec/unit/interface/action_builder_spec.rb +1 -1
  343. data/spec/unit/interface/action_manager_spec.rb +0 -2
  344. data/spec/unit/interface/action_spec.rb +1 -1
  345. data/spec/unit/interface/documentation_spec.rb +0 -2
  346. data/spec/unit/interface/face_collection_spec.rb +1 -1
  347. data/spec/unit/interface/option_builder_spec.rb +1 -1
  348. data/spec/unit/interface/option_spec.rb +0 -1
  349. data/spec/unit/module_spec.rb +17 -19
  350. data/spec/unit/module_tool/application_spec.rb +1 -3
  351. data/spec/unit/module_tool/applications/builder_spec.rb +38 -0
  352. data/spec/unit/module_tool/applications/checksummer_spec.rb +134 -0
  353. data/spec/unit/module_tool/applications/installer_spec.rb +71 -91
  354. data/spec/unit/module_tool/applications/searcher_spec.rb +1 -3
  355. data/spec/unit/module_tool/applications/uninstaller_spec.rb +18 -26
  356. data/spec/unit/module_tool/applications/unpacker_spec.rb +19 -52
  357. data/spec/unit/module_tool/tar/gnu_spec.rb +19 -0
  358. data/spec/unit/module_tool/tar/mini_spec.rb +59 -0
  359. data/spec/unit/module_tool/tar/solaris_spec.rb +19 -0
  360. data/spec/unit/network/http/connection_spec.rb +17 -2
  361. data/spec/unit/network/http/handler_spec.rb +195 -167
  362. data/spec/unit/network/http/rack/rest_spec.rb +26 -4
  363. data/spec/unit/network/http/webrick/rest_spec.rb +28 -1
  364. data/spec/unit/network/http/webrick_spec.rb +12 -3
  365. data/spec/unit/node/environment_spec.rb +421 -404
  366. data/spec/unit/parser/ast/arithmetic_operator_spec.rb +98 -2
  367. data/spec/unit/parser/collector_spec.rb +4 -4
  368. data/spec/unit/parser/compiler_spec.rb +13 -13
  369. data/spec/unit/parser/eparser_adapter_spec.rb +407 -0
  370. data/spec/unit/parser/functions/extlookup_spec.rb +20 -17
  371. data/spec/unit/parser/functions/fqdn_rand_spec.rb +5 -0
  372. data/spec/unit/parser/functions/hiera_include_spec.rb +0 -2
  373. data/spec/unit/parser/functions/hiera_spec.rb +0 -2
  374. data/spec/unit/parser/functions_spec.rb +27 -15
  375. data/spec/unit/parser/methods/collect_spec.rb +110 -0
  376. data/spec/unit/parser/methods/each_spec.rb +91 -0
  377. data/spec/unit/parser/methods/foreach_spec.rb +91 -0
  378. data/spec/unit/parser/methods/reduce_spec.rb +67 -0
  379. data/spec/unit/parser/methods/reject_spec.rb +73 -0
  380. data/spec/unit/parser/methods/select_spec.rb +79 -0
  381. data/spec/unit/parser/methods/shared.rb +61 -0
  382. data/spec/unit/parser/methods/slice_spec.rb +97 -0
  383. data/spec/unit/parser/parser_spec.rb +2 -2
  384. data/spec/unit/parser/scope_spec.rb +39 -16
  385. data/spec/unit/parser/templatewrapper_spec.rb +6 -5
  386. data/spec/unit/parser/type_loader_spec.rb +191 -165
  387. data/spec/unit/pops/adaptable_spec.rb +143 -0
  388. data/spec/unit/pops/containment_spec.rb +25 -0
  389. data/spec/unit/pops/factory_rspec_helper.rb +77 -0
  390. data/spec/unit/pops/factory_spec.rb +329 -0
  391. data/spec/unit/pops/issues_spec.rb +26 -0
  392. data/spec/unit/pops/label_provider_spec.rb +42 -0
  393. data/spec/unit/pops/model/ast_transformer_spec.rb +65 -0
  394. data/spec/unit/pops/model/model_spec.rb +37 -0
  395. data/spec/unit/pops/parser/lexer_spec.rb +884 -0
  396. data/spec/unit/pops/parser/parse_basic_expressions_spec.rb +248 -0
  397. data/spec/unit/pops/parser/parse_calls_spec.rb +93 -0
  398. data/spec/unit/pops/parser/parse_conditionals_spec.rb +159 -0
  399. data/spec/unit/pops/parser/parse_containers_spec.rb +175 -0
  400. data/spec/unit/pops/parser/parse_resource_spec.rb +228 -0
  401. data/spec/unit/pops/parser/parser_rspec_helper.rb +11 -0
  402. data/spec/unit/pops/parser/parser_spec.rb +15 -0
  403. data/spec/unit/pops/parser/rgen_sanitycheck_spec.rb +16 -0
  404. data/spec/unit/pops/transformer/transform_basic_expressions_spec.rb +243 -0
  405. data/spec/unit/pops/transformer/transform_calls_spec.rb +80 -0
  406. data/spec/unit/pops/transformer/transform_conditionals_spec.rb +132 -0
  407. data/spec/unit/pops/transformer/transform_containers_spec.rb +182 -0
  408. data/spec/unit/pops/transformer/transform_resource_spec.rb +185 -0
  409. data/spec/unit/pops/transformer/transformer_rspec_helper.rb +27 -0
  410. data/spec/unit/pops/visitor_spec.rb +94 -0
  411. data/spec/unit/property_spec.rb +11 -0
  412. data/spec/unit/provider/augeas/augeas_spec.rb +3 -0
  413. data/spec/unit/provider/cron/crontab_spec.rb +97 -7
  414. data/spec/unit/provider/cron/parsed_spec.rb +325 -0
  415. data/spec/unit/provider/exec/posix_spec.rb +1 -1
  416. data/spec/unit/provider/group/groupadd_spec.rb +33 -3
  417. data/spec/unit/provider/group/pw_spec.rb +5 -5
  418. data/spec/unit/provider/nameservice_spec.rb +304 -0
  419. data/spec/unit/provider/package/aix_spec.rb +53 -11
  420. data/spec/unit/provider/package/aptrpm_spec.rb +6 -0
  421. data/spec/unit/provider/package/gem_spec.rb +6 -11
  422. data/spec/unit/provider/package/nim_spec.rb +216 -7
  423. data/spec/unit/provider/package/opkg_spec.rb +180 -0
  424. data/spec/unit/provider/package/rpm_spec.rb +149 -3
  425. data/spec/unit/provider/package/yum_spec.rb +6 -5
  426. data/spec/unit/provider/parsedfile_spec.rb +122 -28
  427. data/spec/unit/provider/service/freebsd_spec.rb +18 -0
  428. data/spec/unit/provider/service/init_spec.rb +108 -87
  429. data/spec/unit/provider/service/launchd_spec.rb +2 -2
  430. data/spec/unit/provider/service/openwrt_spec.rb +109 -0
  431. data/spec/unit/provider/service/src_spec.rb +117 -41
  432. data/spec/unit/provider/service/systemd_spec.rb +125 -17
  433. data/spec/unit/provider/service/upstart_spec.rb +1 -1
  434. data/spec/unit/provider/user/aix_spec.rb +42 -0
  435. data/spec/unit/provider/user/directoryservice_spec.rb +1 -0
  436. data/spec/unit/provider/user/pw_spec.rb +24 -12
  437. data/spec/unit/provider/user/user_role_add_spec.rb +1 -1
  438. data/spec/unit/provider/user/useradd_spec.rb +179 -15
  439. data/spec/unit/resource/type_spec.rb +3 -3
  440. data/spec/unit/scheduler/job_spec.rb +79 -0
  441. data/spec/unit/scheduler/scheduler_spec.rb +129 -0
  442. data/spec/unit/scheduler/splay_job_spec.rb +35 -0
  443. data/spec/unit/ssl/base_spec.rb +3 -9
  444. data/spec/unit/ssl/certificate_authority_spec.rb +1 -0
  445. data/spec/unit/ssl/certificate_request_spec.rb +3 -1
  446. data/spec/unit/ssl/certificate_spec.rb +3 -1
  447. data/spec/unit/ssl/configuration_spec.rb +74 -0
  448. data/spec/unit/ssl/host_spec.rb +28 -7
  449. data/spec/unit/ssl/validator_spec.rb +311 -0
  450. data/spec/unit/transaction/event_manager_spec.rb +49 -0
  451. data/spec/unit/transaction/event_spec.rb +20 -5
  452. data/spec/unit/transaction/report_spec.rb +8 -0
  453. data/spec/unit/type/cron_spec.rb +9 -0
  454. data/spec/unit/type/exec_spec.rb +11 -0
  455. data/spec/unit/type/file/content_spec.rb +20 -20
  456. data/spec/unit/type/file/mode_spec.rb +6 -0
  457. data/spec/unit/type/file/source_spec.rb +9 -7
  458. data/spec/unit/type/file_spec.rb +22 -3
  459. data/spec/unit/type/service_spec.rb +34 -21
  460. data/spec/unit/type_spec.rb +46 -1
  461. data/spec/unit/util/backups_spec.rb +2 -2
  462. data/spec/unit/util/execution_spec.rb +4 -1
  463. data/spec/unit/util/filetype_spec.rb +6 -0
  464. data/spec/unit/util/monkey_patches_spec.rb +18 -0
  465. data/spec/unit/util/network_device/cisco/device_spec.rb +37 -0
  466. data/spec/unit/util/network_device/config_spec.rb +14 -0
  467. data/spec/unit/util/network_device_spec.rb +3 -3
  468. data/spec/unit/util/profiler/logging_spec.rb +81 -0
  469. data/spec/unit/util/profiler/none_spec.rb +12 -0
  470. data/spec/unit/util/profiler/object_counts_spec.rb +14 -0
  471. data/spec/unit/util/profiler/wall_clock_spec.rb +13 -0
  472. data/spec/unit/util/pson_spec.rb +5 -0
  473. data/spec/unit/util/ssl_spec.rb +51 -0
  474. data/spec/unit/util/windows/root_certs_spec.rb +15 -0
  475. data/spec/unit/util_spec.rb +28 -0
  476. metadata +2593 -2307
  477. data/spec/unit/module_tool/applications/application_spec.rb +0 -19
@@ -0,0 +1,71 @@
1
+ # Provides a label for an object.
2
+ # This simple implementation calls #to_s on the given object, and handles articles 'a/an/the'.
3
+ #
4
+ class Puppet::Pops::LabelProvider
5
+ VOWELS = %w{a e i o u y}
6
+ SKIPPED_CHARACTERS = %w{" '}
7
+ A = "a"
8
+ AN = "an"
9
+
10
+ # Provides a label for the given object by calling `to_s` on the object.
11
+ # The intent is for this method to be overridden in concrete label providers.
12
+ def label o
13
+ o.to_s
14
+ end
15
+
16
+ # Produces a label for the given text with indefinite article (a/an)
17
+ def a_an o
18
+ text = label(o)
19
+ "#{article(text)} #{text}"
20
+ end
21
+
22
+ # Produces a label for the given text with indefinite article (A/An)
23
+ def a_an_uc o
24
+ text = label(o)
25
+ "#{article(text).capitalize} #{text}"
26
+ end
27
+
28
+ # Produces a label for the given text with *definitie article* (the).
29
+ def the o
30
+ "the #{label(o)}"
31
+ end
32
+
33
+ # Produces a label for the given text with *definitie article* (The).
34
+ def the_uc o
35
+ "The #{label(o)}"
36
+ end
37
+
38
+ private
39
+
40
+ # Produces an *indefinite article* (a/an) for the given text ('a' if
41
+ # it starts with a vowel) This is obviously flawed in the general
42
+ # sense as may labels have punctuation at the start and this method
43
+ # does not translate punctuation to English words. Also, if a vowel is
44
+ # pronounced as a consonant, the article should not be "an".
45
+ #
46
+ def article s
47
+ article_for_letter(first_letter_of(s))
48
+ end
49
+
50
+ def first_letter_of(string)
51
+ char = string[0,1]
52
+ if SKIPPED_CHARACTERS.include? char
53
+ char = string[1,1]
54
+ end
55
+
56
+ if char == ""
57
+ raise Puppet::DevError, "<#{string}> does not appear to contain a word"
58
+ end
59
+
60
+ char
61
+ end
62
+
63
+ def article_for_letter(letter)
64
+ downcased = letter.downcase
65
+ if VOWELS.include? downcased
66
+ AN
67
+ else
68
+ A
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,636 @@
1
+ require 'puppet/parser/ast'
2
+
3
+ # The receiver of `import(file)` calls; once per imported file, or nil if imports are ignored
4
+ #
5
+ # Transforms a Pops::Model to classic Puppet AST.
6
+ # TODO: Documentation is currently skipped completely (it is only used for Rdoc)
7
+ #
8
+ class Puppet::Pops::Model::AstTransformer
9
+ AST = Puppet::Parser::AST
10
+ Model = Puppet::Pops::Model
11
+
12
+ attr_reader :importer
13
+ def initialize(source_file = "unknown-file", importer=nil)
14
+ @@transform_visitor ||= Puppet::Pops::Visitor.new(nil,"transform",0,0)
15
+ @@query_transform_visitor ||= Puppet::Pops::Visitor.new(nil,"query",0,0)
16
+ @@hostname_transform_visitor ||= Puppet::Pops::Visitor.new(nil,"hostname",0,0)
17
+ @importer = importer
18
+ @source_file = source_file
19
+ end
20
+
21
+ # Initialize klass from o (location) and hash (options to created instance).
22
+ # The object o is used to compute a source location. It may be nil. Source position is merged into
23
+ # the given options (non surgically). If o is non-nil, the first found source position going up
24
+ # the containment hierarchy is set. I.e. callers should pass nil if a source position is not wanted
25
+ # or known to be unobtainable for the object.
26
+ #
27
+ # @param o [Object, nil] object from which source position / location is obtained, may be nil
28
+ # @param klass [Class<Puppet::Parser::AST>] the ast class to create an instance of
29
+ # @param hash [Hash] hash with options for the class to create
30
+ #
31
+ def ast(o, klass, hash={})
32
+ # create and pass hash with file and line information
33
+ klass.new(merge_location(hash, o))
34
+ end
35
+
36
+ def merge_location(hash, o)
37
+ if o
38
+ pos = {}
39
+ source_pos = Puppet::Pops::Utils.find_adapter(o, Puppet::Pops::Adapters::SourcePosAdapter)
40
+ if source_pos
41
+ pos[:line] = source_pos.line
42
+ pos[:pos] = source_pos.pos
43
+ end
44
+ pos[:file] = @source_file if @source_file
45
+ hash = hash.merge(pos)
46
+ end
47
+ hash
48
+ end
49
+
50
+ # Transforms pops expressions into AST 3.1 statements/expressions
51
+ def transform(o)
52
+ @@transform_visitor.visit_this(self,o)
53
+ end
54
+
55
+ # Transforms pops expressions into AST 3.1 query expressions
56
+ def query(o)
57
+ @@query_transform_visitor.visit_this(self, o)
58
+ end
59
+
60
+ # Transforms pops expressions into AST 3.1 hostnames
61
+ def hostname(o)
62
+ @@hostname_transform_visitor.visit_this(self, o)
63
+ end
64
+
65
+ def transform_LiteralNumber(o)
66
+ s = case o.radix
67
+ when 10
68
+ o.value.to_s
69
+ when 8
70
+ "0%o" % o.value
71
+ when 16
72
+ "0x%X" % o.value
73
+ else
74
+ "bad radix:" + o.value.to_s
75
+ end
76
+
77
+ # Numbers are Names in the AST !! (Name a.k.a BareWord)
78
+ ast o, AST::Name, :value => s
79
+ end
80
+
81
+ # Transforms all literal values to string (override for those that should not be AST::String)
82
+ #
83
+ def transform_LiteralValue(o)
84
+ ast o, AST::String, :value => o.value.to_s
85
+ end
86
+
87
+ def transform_LiteralBoolean(o)
88
+ ast o, AST::Boolean, :value => o.value
89
+ end
90
+
91
+ def transform_Factory(o)
92
+ transform(o.current)
93
+ end
94
+
95
+ def transform_ArithmeticExpression(o)
96
+ ast o, AST::ArithmeticOperator, :lval => transform(o.left_expr), :rval=>transform(o.right_expr),
97
+ :operator => o.operator.to_s
98
+ end
99
+
100
+ def transform_Array(o)
101
+ ast nil, AST::ASTArray, :children => o.collect {|x| transform(x) }
102
+ end
103
+
104
+ # Puppet AST only allows:
105
+ # * variable[expression] => Hasharray Access
106
+ # * NAME [expressions] => Resource Reference(s)
107
+ # * type [epxressions] => Resource Reference(s)
108
+ # * HashArrayAccesses[expression] => HasharrayAccesses
109
+ #
110
+ # i.e. it is not possible to do `func()[3]`, `[1,2,3][$x]`, `{foo=>10, bar=>20}[$x]` etc. since
111
+ # LHS is not an expression
112
+ #
113
+ # Validation for 3.x semantics should validate the illegal cases. This transformation may fail,
114
+ # or ignore excess information if the expressions are not correct.
115
+ # This means that the transformation does not have to evaluate the lhs to detect the target expression.
116
+ #
117
+ # Hm, this seems to have changed, the LHS (variable) is evaluated if evaluateable, else it is used as is.
118
+ #
119
+ def transform_AccessExpression(o)
120
+ case o.left_expr
121
+ when Model::QualifiedName
122
+ ast o, AST::ResourceReference, :type => o.left_expr.value, :title => transform(o.keys)
123
+
124
+ when Model::QualifiedReference
125
+ ast o, AST::ResourceReference, :type => o.left_expr.value, :title => transform(o.keys)
126
+
127
+ when Model::VariableExpression
128
+ ast o, AST::HashOrArrayAccess, :variable => transform(o.left_expr), :key => transform(o.keys()[0])
129
+
130
+ else
131
+ ast o, AST::HashOrArrayAccess, :variable => transform(o.left_expr), :key => transform(o.keys()[0])
132
+ end
133
+ end
134
+
135
+ # Puppet AST has a complicated structure
136
+ # LHS can not be an expression, it must be a type (which is downcased).
137
+ # type = a downcased QualifiedName
138
+ #
139
+ def transform_CollectExpression(o)
140
+ raise "LHS is not a type" unless o.type_expr.is_a? Model::QualifiedReference
141
+ type = o.type_expr.value().downcase()
142
+ args = { :type => type }
143
+
144
+ # This somewhat peculiar encoding is used by the 3.1 AST.
145
+ query = transform(o.query)
146
+ if query.is_a? Symbol
147
+ args[:form] = query
148
+ else
149
+ args[:form] = query.form
150
+ args[:query] = query
151
+ query.type = type
152
+ end
153
+
154
+ if o.operations.size > 0
155
+ args[:override] = transform(o.operations)
156
+ end
157
+ ast o, AST::Collection, args
158
+ end
159
+
160
+ def transform_ExportedQuery(o)
161
+ if is_nop?(o.expr)
162
+ result = :exported
163
+ else
164
+ result = query(o.expr)
165
+ result.form = :exported
166
+ end
167
+ result
168
+ end
169
+
170
+ def transform_VirtualQuery(o)
171
+ if is_nop?(o.expr)
172
+ result = :virtual
173
+ else
174
+ result = query(o.expr)
175
+ result.form = :virtual
176
+ end
177
+ result
178
+ end
179
+
180
+ # Ensures transformation fails if a 3.1 non supported object is encountered in a query expression
181
+ #
182
+ def query_Object(o)
183
+ raise "Not a valid expression in a collection query: "+o.class.name
184
+ end
185
+
186
+ # Puppet AST only allows == and !=, and left expr is restricted, but right value is an expression
187
+ #
188
+ def query_ComparisonExpression(o)
189
+ if [:'==', :'!='].include? o.operator
190
+ ast o, AST::CollExpr, :test1 => query(o.left_expr), :oper => o.operator.to_s, :test2 => transform(o.right_expr)
191
+ else
192
+ raise "Not a valid comparison operator in a collection query: " + o.operator.to_s
193
+ end
194
+ end
195
+
196
+ def query_AndExpression(o)
197
+ ast o, AST::CollExpr, :test1 => query(o.left_expr), :oper => 'and', :test2 => query(o.right_expr)
198
+ end
199
+
200
+ def query_OrExpression(o)
201
+ ast o, AST::CollExpr, :test1 => query(o.left_expr), :oper => 'or', :test2 => query(o.right_expr)
202
+ end
203
+
204
+ def query_ParenthesizedExpression(o)
205
+ result = query(o.expr) # produces CollExpr
206
+ result.parens = true
207
+ result
208
+ end
209
+
210
+ def query_VariableExpression(o)
211
+ transform(o)
212
+ end
213
+
214
+ def query_QualifiedName(o)
215
+ transform(o)
216
+ end
217
+
218
+ def query_LiteralNumber(o)
219
+ transform(o) # number to string in correct radix
220
+ end
221
+
222
+ def query_LiteralString(o)
223
+ transform(o)
224
+ end
225
+
226
+ def query_LiteralBoolean(o)
227
+ transform(o)
228
+ end
229
+
230
+ def transform_QualifiedName(o)
231
+ ast o, AST::Name, :value => o.value
232
+ end
233
+
234
+ def transform_QualifiedReference(o)
235
+ ast o, AST::Type, :value => o.value
236
+ end
237
+
238
+ def transform_ComparisonExpression(o)
239
+ ast o, AST::ComparisonOperator, :operator => o.operator.to_s, :lval => transform(o.left_expr), :rval => transform(o.right_expr)
240
+ end
241
+
242
+ def transform_AndExpression(o)
243
+ ast o, AST::BooleanOperator, :operator => 'and', :lval => transform(o.left_expr), :rval => transform(o.right_expr)
244
+ end
245
+
246
+ def transform_OrExpression(o)
247
+ ast o, AST::BooleanOperator, :operator => 'or', :lval => transform(o.left_expr), :rval => transform(o.right_expr)
248
+ end
249
+
250
+ def transform_InExpression(o)
251
+ ast o, AST::InOperator, :lval => transform(o.left_expr), :rval => transform(o.right_expr)
252
+ end
253
+
254
+ # This is a complex transformation from a modeled import to a Nop result (where the import took place),
255
+ # and calls to perform import/parsing etc. during the transformation.
256
+ # When testing syntax, the @importer does not have to be set, but it is not possible to check
257
+ # the actual import without inventing a new AST::ImportExpression with nop effect when evaluating.
258
+ def transform_ImportExpression(o)
259
+ if importer
260
+ o.files.each {|f|
261
+ unless f.is_a? Model::LiteralString
262
+ raise "Illegal import file expression. Must be a single quoted string"
263
+ end
264
+ importer.import(f.value)
265
+ }
266
+ end
267
+ # Crazy stuff
268
+ # Transformation of "import" needs to parse the other files at the time of transformation.
269
+ # Then produce a :nop, since nothing should be evaluated.
270
+ ast o, AST::Nop, {}
271
+ end
272
+
273
+ def transform_InstanceReferences(o)
274
+ ast o, AST::ResourceReference, :type => o.type_name.value, :title => transform(o.names)
275
+ end
276
+
277
+ # Assignment in AST 3.1 is to variable or hasharray accesses !!! See Bug #16116
278
+ def transform_AssignmentExpression(o)
279
+ args = {:value => transform(o.right_expr) }
280
+ args[:append] = true if o.operator == :'+='
281
+
282
+ args[:name] = case o.left_expr
283
+ when Model::VariableExpression
284
+ ast o, AST::Name, {:value => o.left_expr.expr.value }
285
+ when Model::AccessExpression
286
+ transform(o.left_expr)
287
+ else
288
+ raise "LHS is not an expression that can be assigned to"
289
+ end
290
+ ast o, AST::VarDef, args
291
+ end
292
+
293
+ # Produces (name => expr) or (name +> expr)
294
+ def transform_AttributeOperation(o)
295
+ args = { :value => transform(o.value_expr) }
296
+ args[:add] = true if o.operator == :'+>'
297
+ args[:param] = o.attribute_name
298
+ ast o, AST::ResourceParam, args
299
+ end
300
+
301
+ def transform_LiteralList(o)
302
+ # Uses default transform of Ruby Array to ASTArray
303
+ transform(o.values)
304
+ end
305
+
306
+ # Literal hash has strange behavior in Puppet 3.1. See Bug #19426, and this implementation is bug
307
+ # compatible
308
+ def transform_LiteralHash(o)
309
+ if o.entries.size == 0
310
+ ast o, AST::ASTHash, {:value=> {}}
311
+ else
312
+ value = {}
313
+ o.entries.each {|x| value.merge! transform(x) }
314
+ ast o, AST::ASTHash, {:value=> value}
315
+ end
316
+ end
317
+
318
+ # Transforms entry into a hash (they are later merged with strange effects: Bug #19426).
319
+ # Puppet 3.x only allows:
320
+ # * NAME
321
+ # * quotedtext
322
+ # As keys (quoted text can be an interpolated string which is compared as a key in a less than satisfactory way).
323
+ #
324
+ def transform_KeyedEntry(o)
325
+ value = transform(o.value)
326
+ key = case o.key
327
+ when Model::QualifiedName
328
+ o.key.value
329
+ when Model::LiteralString
330
+ transform o.key
331
+ when Model::LiteralNumber
332
+ transform o.key
333
+ when Model::ConcatenatedString
334
+ transform o.key
335
+ else
336
+ raise "Illegal hash key expression of type (#{o.key.class})"
337
+ end
338
+ {key => value}
339
+ end
340
+
341
+ def transform_MatchExpression(o)
342
+ ast o, AST::MatchOperator, :operator => o.operator.to_s, :lval => transform(o.left_expr), :rval => transform(o.right_expr)
343
+ end
344
+
345
+ def transform_LiteralString(o)
346
+ ast o, AST::String, :value => o.value
347
+ end
348
+
349
+ # Literal text in a concatenated string
350
+ def transform_LiteralText(o)
351
+ ast o, AST::String, :value => o.value
352
+ end
353
+
354
+ def transform_LambdaExpression(o)
355
+ astargs = { :parameters => o.parameters.collect {|p| transform(p) } }
356
+ astargs.merge!({ :children => transform(o.body) }) if o.body # do not want children if it is nil/nop
357
+ ast o, AST::Lambda, astargs
358
+ end
359
+
360
+ def transform_LiteralDefault(o)
361
+ ast o, AST::Default, :value => :default
362
+ end
363
+
364
+ def transform_LiteralUndef(o)
365
+ ast o, AST::Undef, :value => :undef
366
+ end
367
+
368
+ def transform_LiteralRegularExpression(o)
369
+ ast o, AST::Regex, :value => o.value
370
+ end
371
+
372
+ def transform_Nop(o)
373
+ ast o, AST::Nop
374
+ end
375
+
376
+ # In the 3.1. grammar this is a hash that is merged with other elements to form a method call
377
+ # Also in 3.1. grammar there are restrictions on the LHS (that are only there for grammar issues).
378
+ #
379
+ def transform_NamedAccessExpression(o)
380
+ receiver = transform(o.left_expr)
381
+ name = o.right_expr
382
+ raise "Unacceptable function/method name" unless name.is_a? Model::QualifiedName
383
+ {:receiver => receiver, :name => name.value}
384
+ end
385
+
386
+ def transform_NilClass(o)
387
+ ast o, AST::Nop, {}
388
+ end
389
+
390
+ def transform_NotExpression(o)
391
+ ast o, AST::Not, :value => transform(o.expr)
392
+ end
393
+
394
+ def transform_VariableExpression(o)
395
+ # assumes the expression is a QualifiedName
396
+ ast o, AST::Variable, :value => o.expr.value
397
+ end
398
+
399
+ # In Puppet 3.1, the ConcatenatedString is responsible for the evaluation and stringification of
400
+ # expression segments. Expressions and Strings are kept in an array.
401
+ def transform_TextExpression(o)
402
+ transform(o.expr)
403
+ end
404
+
405
+ def transform_UnaryMinusExpression(o)
406
+ ast o, AST::Minus, :value => transform(o.expr)
407
+ end
408
+
409
+ # Puppet 3.1 representation of a BlockExpression is an AST::Array - this makes it impossible to differentiate
410
+ # between a LiteralArray and a Sequence. (Should it return the collected array, or the last expression?)
411
+ # (A BlockExpression has now been introduced in the AST to solve this).
412
+ #
413
+ def transform_BlockExpression(o)
414
+ children = []
415
+ # remove nops resulting from import
416
+ o.statements.each {|s| r = transform(s); children << r unless is_nop?(r) }
417
+ ast o, AST::BlockExpression, :children => children # o.statements.collect {|s| transform(s) }
418
+ end
419
+
420
+ # Interpolated strings are kept in an array of AST (string or other expression).
421
+ def transform_ConcatenatedString(o)
422
+ ast o, AST::Concat, :value => o.segments.collect {|x| transform(x)}
423
+ end
424
+
425
+ def transform_HostClassDefinition(o)
426
+ parameters = o.parameters.collect {|p| transform(p) }
427
+ args = {
428
+ :arguments => parameters,
429
+ :parent => o.parent_class,
430
+ }
431
+ args[:code] = transform(o.body) unless is_nop?(o.body)
432
+ Puppet::Parser::AST::Hostclass.new(o.name, merge_location(args, o))
433
+ end
434
+
435
+ def transform_NodeDefinition(o)
436
+ # o.host_matches are expressions, and 3.1 AST requires special object AST::HostName
437
+ # where a HostName is one of NAME, STRING, DEFAULT or Regexp - all of these are strings except regexp
438
+ #
439
+ args = {
440
+ :code => transform(o.body)
441
+ }
442
+ args[:parent] = transform(o.parent) unless is_nop?(o.parent)
443
+ Puppet::Parser::AST::Node.new(hostname(o.host_matches), merge_location(args, o))
444
+ end
445
+
446
+ # Transforms Array of host matching expressions into a (Ruby) array of AST::HostName
447
+ def hostname_Array(o)
448
+ o.collect {|x| ast x, AST::HostName, :value => hostname(x) }
449
+ end
450
+
451
+ def hostname_LiteralValue(o)
452
+ return o.value
453
+ end
454
+
455
+ def hostname_QualifiedName(o)
456
+ return o.value
457
+ end
458
+
459
+ def hostname_LiteralNumber(o)
460
+ transform(o) # Number to string with correct radix
461
+ end
462
+
463
+ def hostname_LiteralDefault(o)
464
+ return 'default'
465
+ end
466
+
467
+ def hostname_LiteralRegularExpression(o)
468
+ ast o, AST::Regex, :value => o.value
469
+ end
470
+
471
+ def hostname_Object(o)
472
+ raise "Illegal expression - unacceptable as a node name"
473
+ end
474
+
475
+ def transform_RelationshipExpression(o)
476
+ Puppet::Parser::AST::Relationship.new(transform(o.left_expr), transform(o.right_expr), o.operator.to_s, merge_location({}, o))
477
+ end
478
+
479
+ def transform_ResourceTypeDefinition(o)
480
+ parameters = o.parameters.collect {|p| transform(p) }
481
+ args = { :arguments => parameters }
482
+ args[:code] = transform(o.body) unless is_nop?(o.body)
483
+
484
+ Puppet::Parser::AST::Definition.new(o.name, merge_location(args, o))
485
+ end
486
+
487
+ # Transformation of ResourceOverrideExpression is slightly more involved than a straight forward
488
+ # transformation.
489
+ # A ResourceOverrideExppression has "resources" which should be an AccessExpression
490
+ # on the form QualifiedName[expressions], or QualifiedReference[expressions] to be valid.
491
+ # It also has a set of attribute operations.
492
+ #
493
+ # The AST equivalence is an AST::ResourceOverride with a ResourceReference as its LHS, and
494
+ # a set of Parameters.
495
+ # ResourceReference has type as a string, and the expressions representing
496
+ # the "titles" to be an ASTArray.
497
+ #
498
+ def transform_ResourceOverrideExpression(o)
499
+ resource_ref = o.resources
500
+ raise "Unacceptable expression for resource override" unless resource_ref.is_a? Model::AccessExpression
501
+
502
+ type = case resource_ref.left_expr
503
+ when Model::QualifiedName
504
+ # This is deprecated "Resource references should now be capitalized" - this is caught elsewhere
505
+ resource_ref.left_expr.value
506
+ when Model::QualifiedReference
507
+ resource_ref.left_expr.value
508
+ else
509
+ raise "Unacceptable expression for resource override; need NAME or CLASSREF"
510
+ end
511
+
512
+ result_ref = ast o, AST::ResourceReference, :type => type, :title => transform(resource_ref.keys)
513
+
514
+ # title is one or more expressions, if more than one it should be an ASTArray
515
+ ast o, AST::ResourceOverride, :object => result_ref, :parameters => transform(o.operations)
516
+ end
517
+
518
+ # Parameter is a parameter in a definition of some kind.
519
+ # It is transformed to an array on the form `[name]´, or `[name, value]´.
520
+ def transform_Parameter(o)
521
+ if o.value
522
+ [o.name, transform(o.value)]
523
+ else
524
+ [o.name]
525
+ end
526
+ end
527
+
528
+ # For non query expressions, parentheses can be dropped in the resulting AST.
529
+ def transform_ParenthesizedExpression(o)
530
+ transform(o.expr)
531
+ end
532
+
533
+ def transform_IfExpression(o)
534
+ args = { :test => transform(o.test), :statements => transform(o.then_expr) }
535
+ args[:else] = transform(o.else_expr) # Tests say Nop should be there (unless is_nop? o.else_expr), probably not needed
536
+ result = ast o, AST::IfStatement, args
537
+ end
538
+
539
+ # Unless is not an AST object, instead an AST::IfStatement is used with an AST::Not around the test
540
+ #
541
+ def transform_UnlessExpression(o)
542
+ args = { :test => ast(o, AST::Not, :value => transform(o.test)),
543
+ :statements => transform(o.then_expr) }
544
+ # AST 3.1 does not allow else on unless in the grammar, but it is ok since unless is encoded as a if !x
545
+ args.merge!({:else => transform(o.else_expr)}) unless is_nop?(o.else_expr)
546
+ result = ast o, AST::IfStatement, args
547
+ end
548
+
549
+ # Puppet 3.1 AST only supports calling a function by name (it is not possible to produce a function
550
+ # that is then called).
551
+ # rval_required (for an expression)
552
+ # functor_expr (lhs - the "name" expression)
553
+ # arguments - list of arguments
554
+ #
555
+ def transform_CallNamedFunctionExpression(o)
556
+ name = o.functor_expr
557
+ raise "Unacceptable expression for name of function" unless name.is_a? Model::QualifiedName
558
+ args = {
559
+ :name => name.value,
560
+ :arguments => transform(o.arguments),
561
+ :ftype => o.rval_required ? :rvalue : :statement
562
+ }
563
+ args[:pblock] = transform(o.lambda) if o.lambda
564
+ ast o, AST::Function, args
565
+ end
566
+
567
+ # Transformation of CallMethodExpression handles a NamedAccessExpression functor and
568
+ # turns this into a 3.1 AST::MethodCall.
569
+ #
570
+ def transform_CallMethodExpression(o)
571
+ name = o.functor_expr
572
+ raise "Unacceptable expression for name of function" unless name.is_a? Model::NamedAccessExpression
573
+ # transform of NamedAccess produces a hash, add arguments to it
574
+ astargs = transform(name).merge(:arguments => transform(o.arguments))
575
+ astargs.merge!(:lambda => transform(o.lambda)) if o.lambda # do not want a Nop as the lambda
576
+ ast o, AST::MethodCall, astargs
577
+
578
+ end
579
+
580
+ def transform_CaseExpression(o)
581
+ # Expects expression, AST::ASTArray of AST
582
+ ast o, AST::CaseStatement, :test => transform(o.test), :options => transform(o.options)
583
+ end
584
+
585
+ def transform_CaseOption(o)
586
+ ast o, AST::CaseOpt, :value => transform(o.values), :statements => transform(o.then_expr)
587
+ end
588
+
589
+ def transform_ResourceBody(o)
590
+ # expects AST, AST::ASTArray of AST
591
+ ast o, AST::ResourceInstance, :title => transform(o.title), :parameters => transform(o.operations)
592
+ end
593
+
594
+ def transform_ResourceDefaultsExpression(o)
595
+ ast o, AST::ResourceDefaults, :type => o.type_ref.value, :parameters => transform(o.operations)
596
+ end
597
+
598
+ # Transformation of ResourceExpression requires calling a method on the resulting
599
+ # AST::Resource if it is virtual or exported
600
+ #
601
+ def transform_ResourceExpression(o)
602
+ raise "Unacceptable type name expression" unless o.type_name.is_a? Model::QualifiedName
603
+ resource = ast o, AST::Resource, :type => o.type_name.value, :instances => transform(o.bodies)
604
+ resource.send("#{o.form}=", true) unless o.form == :regular
605
+ resource
606
+ end
607
+
608
+ # Transformation of SelectorExpression is limited to certain types of expressions.
609
+ # This is probably due to constraints in the old grammar rather than any real concerns.
610
+ def transform_SelectorExpression(o)
611
+ case o.left_expr
612
+ when Model::CallNamedFunctionExpression
613
+ when Model::AccessExpression
614
+ when Model::VariableExpression
615
+ when Model::ConcatenatedString
616
+ else
617
+ raise "Unacceptable select expression" unless o.left_expr.kind_of? Model::Literal
618
+ end
619
+ ast o, AST::Selector, :param => transform(o.left_expr), :values => transform(o.selectors)
620
+ end
621
+
622
+ def transform_SelectorEntry(o)
623
+ ast o, AST::ResourceParam, :param => transform(o.matching_expr), :value => transform(o.value_expr)
624
+ end
625
+
626
+ def transform_Object(o)
627
+ raise "Unacceptable transform - found an Object without a rule: #{o.class}"
628
+ end
629
+
630
+ # Nil, nop
631
+ # Bee bopp a luh-lah, a bop bop boom.
632
+ #
633
+ def is_nop?(o)
634
+ o.nil? || o.is_a?(Model::Nop)
635
+ end
636
+ end