puppet 5.3.7 → 5.4.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puppet might be problematic. Click here for more details.

Files changed (454) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +42 -29
  3. data/README.md +8 -6
  4. data/ext/cert_inspector +2 -2
  5. data/ext/envpuppet +1 -1
  6. data/ext/gentoo/init.d/puppetmaster +4 -4
  7. data/ext/ips/puppet-agent +11 -11
  8. data/ext/ips/puppet-master +11 -11
  9. data/ext/puppet-test +1 -2
  10. data/ext/redhat/client.init +2 -2
  11. data/ext/redhat/logrotate +1 -1
  12. data/ext/solaris/smf/puppet +11 -11
  13. data/ext/solaris/smf/svc-puppetd +5 -5
  14. data/ext/solaris/smf/svc-puppetmasterd +5 -5
  15. data/ext/windows/service/daemon.rb +1 -1
  16. data/install.rb +2 -3
  17. data/lib/puppet/agent.rb +1 -1
  18. data/lib/puppet/application/cert.rb +1 -3
  19. data/lib/puppet/application/describe.rb +0 -1
  20. data/lib/puppet/application/device.rb +12 -99
  21. data/lib/puppet/application/filebucket.rb +32 -11
  22. data/lib/puppet/application/lookup.rb +1 -11
  23. data/lib/puppet/application/script.rb +261 -0
  24. data/lib/puppet/configurer.rb +3 -4
  25. data/lib/puppet/configurer/plugin_handler.rb +26 -9
  26. data/lib/puppet/context.rb +1 -1
  27. data/lib/puppet/datatypes.rb +213 -0
  28. data/lib/puppet/datatypes/error.rb +21 -0
  29. data/lib/puppet/datatypes/impl/error.rb +40 -0
  30. data/lib/puppet/defaults.rb +51 -20
  31. data/lib/puppet/environments.rb +17 -0
  32. data/lib/puppet/error.rb +17 -0
  33. data/lib/puppet/etc.rb +2 -2
  34. data/lib/puppet/external/pson/pure/generator.rb +1 -1
  35. data/lib/puppet/external/pson/pure/parser.rb +1 -1
  36. data/lib/puppet/face/config.rb +45 -0
  37. data/lib/puppet/face/epp.rb +3 -3
  38. data/lib/puppet/face/help/action.erb +3 -0
  39. data/lib/puppet/face/module/build.rb +1 -0
  40. data/lib/puppet/face/module/generate.rb +5 -0
  41. data/lib/puppet/face/module/install.rb +1 -0
  42. data/lib/puppet/face/module/search.rb +6 -2
  43. data/lib/puppet/face/module/uninstall.rb +1 -0
  44. data/lib/puppet/face/module/upgrade.rb +1 -0
  45. data/lib/puppet/face/parser.rb +0 -1
  46. data/lib/puppet/face/plugin.rb +1 -3
  47. data/lib/puppet/feature/base.rb +1 -1
  48. data/lib/puppet/feature/bolt.rb +3 -0
  49. data/lib/puppet/file_bucket/dipper.rb +1 -2
  50. data/lib/puppet/file_serving/http_metadata.rb +1 -1
  51. data/lib/puppet/file_system/uniquefile.rb +2 -2
  52. data/lib/puppet/forge.rb +6 -0
  53. data/lib/puppet/functions.rb +70 -88
  54. data/lib/puppet/functions/all.rb +6 -2
  55. data/lib/puppet/functions/annotate.rb +1 -1
  56. data/lib/puppet/functions/any.rb +7 -3
  57. data/lib/puppet/functions/contain.rb +6 -0
  58. data/lib/puppet/functions/convert_to.rb +32 -0
  59. data/lib/puppet/functions/defined.rb +0 -3
  60. data/lib/puppet/functions/each.rb +10 -6
  61. data/lib/puppet/functions/filter.rb +16 -10
  62. data/lib/puppet/functions/find_file.rb +0 -1
  63. data/lib/puppet/functions/include.rb +6 -0
  64. data/lib/puppet/functions/map.rb +12 -9
  65. data/lib/puppet/functions/module_directory.rb +41 -0
  66. data/lib/puppet/functions/new.rb +1 -4
  67. data/lib/puppet/functions/regsubst.rb +1 -1
  68. data/lib/puppet/functions/require.rb +6 -0
  69. data/lib/puppet/generate/type.rb +1 -1
  70. data/lib/puppet/gettext/config.rb +2 -2
  71. data/lib/puppet/gettext/stubs.rb +1 -1
  72. data/lib/puppet/indirector/catalog/compiler.rb +0 -1
  73. data/lib/puppet/indirector/file_bucket_file/file.rb +6 -2
  74. data/lib/puppet/indirector/file_server.rb +1 -1
  75. data/lib/puppet/indirector/node/ldap.rb +19 -3
  76. data/lib/puppet/indirector/request.rb +10 -6
  77. data/lib/puppet/indirector/rest.rb +11 -12
  78. data/lib/puppet/info_service/class_information_service.rb +1 -1
  79. data/lib/puppet/interface/action.rb +11 -0
  80. data/lib/puppet/interface/action_builder.rb +8 -0
  81. data/lib/puppet/interface/option_manager.rb +1 -1
  82. data/lib/puppet/loaders.rb +2 -0
  83. data/lib/puppet/module.rb +6 -2
  84. data/lib/puppet/module_tool/applications/builder.rb +4 -0
  85. data/lib/puppet/module_tool/applications/installer.rb +3 -0
  86. data/lib/puppet/module_tool/applications/uninstaller.rb +3 -0
  87. data/lib/puppet/module_tool/applications/unpacker.rb +1 -1
  88. data/lib/puppet/module_tool/applications/upgrader.rb +3 -0
  89. data/lib/puppet/module_tool/installed_modules.rb +1 -1
  90. data/lib/puppet/module_tool/metadata.rb +0 -1
  91. data/lib/puppet/network/authstore.rb +1 -1
  92. data/lib/puppet/network/http/api/indirected_routes.rb +1 -1
  93. data/lib/puppet/network/http/connection.rb +1 -9
  94. data/lib/puppet/network/http/factory.rb +0 -3
  95. data/lib/puppet/network/http/webrick.rb +1 -0
  96. data/lib/puppet/network/rights.rb +1 -1
  97. data/lib/puppet/node.rb +53 -0
  98. data/lib/puppet/node/environment.rb +1 -1
  99. data/lib/puppet/parameter/boolean.rb +1 -1
  100. data/lib/puppet/parser.rb +1 -0
  101. data/lib/puppet/parser/abstract_compiler.rb +36 -0
  102. data/lib/puppet/parser/ast/branch.rb +1 -1
  103. data/lib/puppet/parser/ast/pops_bridge.rb +8 -52
  104. data/lib/puppet/parser/compiler.rb +4 -54
  105. data/lib/puppet/parser/functions.rb +0 -1
  106. data/lib/puppet/parser/functions/create_resources.rb +6 -0
  107. data/lib/puppet/parser/functions/fqdn_rand.rb +6 -2
  108. data/lib/puppet/parser/functions/inline_template.rb +6 -0
  109. data/lib/puppet/parser/functions/new.rb +47 -32
  110. data/lib/puppet/parser/functions/realize.rb +6 -0
  111. data/lib/puppet/parser/functions/return.rb +1 -22
  112. data/lib/puppet/parser/functions/reverse_each.rb +1 -1
  113. data/lib/puppet/parser/functions/scanf.rb +1 -1
  114. data/lib/puppet/parser/functions/sha256.rb +5 -0
  115. data/lib/puppet/parser/functions/tag.rb +6 -0
  116. data/lib/puppet/parser/functions/tagged.rb +6 -0
  117. data/lib/puppet/parser/functions/template.rb +5 -0
  118. data/lib/puppet/parser/scope.rb +28 -4
  119. data/lib/puppet/parser/script_compiler.rb +118 -0
  120. data/lib/puppet/parser/type_loader.rb +1 -1
  121. data/lib/puppet/pops.rb +1 -1
  122. data/lib/puppet/pops/evaluator/access_operator.rb +38 -4
  123. data/lib/puppet/pops/evaluator/closure.rb +12 -4
  124. data/lib/puppet/pops/evaluator/compare_operator.rb +4 -4
  125. data/lib/puppet/pops/evaluator/epp_evaluator.rb +13 -0
  126. data/lib/puppet/pops/evaluator/evaluator_impl.rb +38 -10
  127. data/lib/puppet/pops/evaluator/literal_evaluator.rb +1 -1
  128. data/lib/puppet/pops/evaluator/runtime3_converter.rb +1 -1
  129. data/lib/puppet/pops/evaluator/runtime3_support.rb +2 -3
  130. data/lib/puppet/pops/functions/dispatch.rb +6 -5
  131. data/lib/puppet/pops/functions/function.rb +2 -2
  132. data/lib/puppet/pops/issues.rb +34 -2
  133. data/lib/puppet/pops/loader/base_loader.rb +10 -0
  134. data/lib/puppet/pops/loader/dependency_loader.rb +7 -0
  135. data/lib/puppet/pops/loader/loader.rb +21 -2
  136. data/lib/puppet/pops/loader/loader_paths.rb +180 -30
  137. data/lib/puppet/pops/loader/module_loaders.rb +202 -33
  138. data/lib/puppet/pops/loader/puppet_plan_instantiator.rb +84 -0
  139. data/lib/puppet/pops/loader/puppet_resource_type_impl_instantiator.rb +9 -9
  140. data/lib/puppet/pops/loader/ruby_data_type_instantiator.rb +40 -0
  141. data/lib/puppet/pops/loader/runtime3_type_loader.rb +6 -1
  142. data/lib/puppet/pops/loader/static_loader.rb +23 -8
  143. data/lib/puppet/pops/loader/task_instantiator.rb +69 -0
  144. data/lib/puppet/pops/loader/type_definition_instantiator.rb +4 -0
  145. data/lib/puppet/pops/loaders.rb +122 -11
  146. data/lib/puppet/pops/lookup/data_dig_function_provider.rb +1 -1
  147. data/lib/puppet/pops/lookup/interpolation.rb +1 -1
  148. data/lib/puppet/pops/lookup/lookup_adapter.rb +0 -1
  149. data/lib/puppet/pops/model/ast.pp +3 -0
  150. data/lib/puppet/pops/model/ast.rb +34 -1
  151. data/lib/puppet/pops/model/factory.rb +30 -3
  152. data/lib/puppet/pops/model/model_label_provider.rb +1 -0
  153. data/lib/puppet/pops/model/model_tree_dumper.rb +12 -1
  154. data/lib/puppet/pops/model/tree_dumper.rb +1 -1
  155. data/lib/puppet/pops/parser/code_merger.rb +2 -2
  156. data/lib/puppet/pops/parser/egrammar.ra +44 -15
  157. data/lib/puppet/pops/parser/eparser.rb +1687 -1571
  158. data/lib/puppet/pops/parser/epp_support.rb +1 -3
  159. data/lib/puppet/pops/parser/evaluating_parser.rb +1 -1
  160. data/lib/puppet/pops/parser/interpolation_support.rb +2 -2
  161. data/lib/puppet/pops/parser/lexer2.rb +4 -4
  162. data/lib/puppet/pops/parser/lexer_support.rb +2 -2
  163. data/lib/puppet/pops/parser/locatable.rb +1 -1
  164. data/lib/puppet/pops/parser/locator.rb +7 -13
  165. data/lib/puppet/pops/parser/parser_support.rb +3 -3
  166. data/lib/puppet/pops/parser/slurp_support.rb +0 -3
  167. data/lib/puppet/pops/pcore.rb +45 -0
  168. data/lib/puppet/pops/resource/param.rb +1 -1
  169. data/lib/puppet/pops/resource/resource_type_impl.rb +1 -1
  170. data/lib/puppet/pops/serialization/abstract_reader.rb +4 -0
  171. data/lib/puppet/pops/serialization/abstract_writer.rb +6 -0
  172. data/lib/puppet/pops/serialization/extension.rb +1 -0
  173. data/lib/puppet/pops/serialization/from_data_converter.rb +64 -10
  174. data/lib/puppet/pops/serialization/json_path.rb +2 -1
  175. data/lib/puppet/pops/serialization/object.rb +3 -4
  176. data/lib/puppet/pops/serialization/serializer.rb +2 -1
  177. data/lib/puppet/pops/serialization/to_data_converter.rb +7 -3
  178. data/lib/puppet/pops/time/timespan.rb +1 -1
  179. data/lib/puppet/pops/types/iterable.rb +38 -9
  180. data/lib/puppet/pops/types/p_init_type.rb +1 -1
  181. data/lib/puppet/pops/types/p_meta_type.rb +4 -0
  182. data/lib/puppet/pops/types/p_object_type.rb +146 -14
  183. data/lib/puppet/pops/types/p_object_type_extension.rb +218 -0
  184. data/lib/puppet/pops/types/p_sem_ver_range_type.rb +0 -1
  185. data/lib/puppet/pops/types/p_sem_ver_type.rb +10 -2
  186. data/lib/puppet/pops/types/p_type_set_type.rb +0 -1
  187. data/lib/puppet/pops/types/p_uri_type.rb +190 -0
  188. data/lib/puppet/pops/types/puppet_object.rb +15 -1
  189. data/lib/puppet/pops/types/ruby_generator.rb +46 -54
  190. data/lib/puppet/pops/types/string_converter.rb +22 -1
  191. data/lib/puppet/pops/types/type_acceptor.rb +1 -1
  192. data/lib/puppet/pops/types/type_calculator.rb +13 -4
  193. data/lib/puppet/pops/types/type_factory.rb +29 -5
  194. data/lib/puppet/pops/types/type_formatter.rb +67 -4
  195. data/lib/puppet/pops/types/type_parser.rb +92 -4
  196. data/lib/puppet/pops/types/type_with_members.rb +43 -0
  197. data/lib/puppet/pops/types/types.rb +212 -80
  198. data/lib/puppet/pops/validation/checker4_0.rb +10 -6
  199. data/lib/puppet/pops/validation/tasks_checker.rb +60 -0
  200. data/lib/puppet/pops/validation/validator_factory_4_0.rb +6 -1
  201. data/lib/puppet/property.rb +1 -1
  202. data/lib/puppet/provider.rb +18 -8
  203. data/lib/puppet/provider/augeas/augeas.rb +3 -4
  204. data/lib/puppet/provider/exec.rb +0 -2
  205. data/lib/puppet/provider/group/groupadd.rb +25 -1
  206. data/lib/puppet/provider/group/windows_adsi.rb +7 -4
  207. data/lib/puppet/provider/mount.rb +25 -8
  208. data/lib/puppet/provider/nameservice.rb +9 -4
  209. data/lib/puppet/provider/nameservice/directoryservice.rb +3 -3
  210. data/lib/puppet/provider/nameservice/objectadd.rb +13 -24
  211. data/lib/puppet/provider/nameservice/pw.rb +14 -14
  212. data/lib/puppet/provider/package/appdmg.rb +0 -1
  213. data/lib/puppet/provider/package/apple.rb +0 -1
  214. data/lib/puppet/provider/package/gem.rb +2 -2
  215. data/lib/puppet/provider/package/macports.rb +2 -2
  216. data/lib/puppet/provider/package/pkg.rb +3 -0
  217. data/lib/puppet/provider/package/pkgdmg.rb +0 -1
  218. data/lib/puppet/provider/package/portage.rb +0 -1
  219. data/lib/puppet/provider/package/yum.rb +23 -8
  220. data/lib/puppet/provider/package/zypper.rb +2 -2
  221. data/lib/puppet/provider/scheduled_task/win32_taskscheduler.rb +2 -2
  222. data/lib/puppet/provider/service/init.rb +1 -0
  223. data/lib/puppet/provider/service/launchd.rb +6 -7
  224. data/lib/puppet/provider/service/redhat.rb +3 -2
  225. data/lib/puppet/provider/service/systemd.rb +2 -2
  226. data/lib/puppet/provider/ssh_authorized_key/parsed.rb +1 -1
  227. data/lib/puppet/provider/user/aix.rb +3 -2
  228. data/lib/puppet/provider/user/openbsd.rb +1 -1
  229. data/lib/puppet/provider/user/pw.rb +1 -1
  230. data/lib/puppet/provider/user/user_role_add.rb +7 -1
  231. data/lib/puppet/provider/user/useradd.rb +36 -6
  232. data/lib/puppet/provider/user/windows_adsi.rb +1 -1
  233. data/lib/puppet/provider/yumrepo/inifile.rb +2 -4
  234. data/lib/puppet/provider/zfs/zfs.rb +23 -3
  235. data/lib/puppet/provider/zpool/zpool.rb +1 -1
  236. data/lib/puppet/reference/configuration.rb +0 -2
  237. data/lib/puppet/reference/type.rb +0 -1
  238. data/lib/puppet/resource.rb +1 -2
  239. data/lib/puppet/resource/catalog.rb +1 -1
  240. data/lib/puppet/resource/status.rb +0 -1
  241. data/lib/puppet/resource/type.rb +4 -4
  242. data/lib/puppet/resource/type_collection.rb +1 -1
  243. data/lib/puppet/settings/base_setting.rb +1 -1
  244. data/lib/puppet/settings/environment_conf.rb +0 -1
  245. data/lib/puppet/settings/ini_file.rb +66 -12
  246. data/lib/puppet/ssl/certificate_authority.rb +1 -1
  247. data/lib/puppet/ssl/certificate_request.rb +2 -2
  248. data/lib/puppet/ssl/certificate_revocation_list.rb +2 -1
  249. data/lib/puppet/ssl/certificate_signer.rb +11 -0
  250. data/lib/puppet/ssl/host.rb +2 -2
  251. data/lib/puppet/syntax_checkers/base64.rb +1 -1
  252. data/lib/puppet/transaction.rb +37 -14
  253. data/lib/puppet/transaction/report.rb +3 -1
  254. data/lib/puppet/type.rb +17 -4
  255. data/lib/puppet/type/cron.rb +1 -1
  256. data/lib/puppet/type/exec.rb +5 -4
  257. data/lib/puppet/type/file.rb +3 -3
  258. data/lib/puppet/type/file/checksum.rb +7 -1
  259. data/lib/puppet/type/file/checksum_value.rb +4 -3
  260. data/lib/puppet/type/group.rb +3 -0
  261. data/lib/puppet/type/k5login.rb +101 -0
  262. data/lib/puppet/type/macauthorization.rb +1 -1
  263. data/lib/puppet/type/mount.rb +6 -2
  264. data/lib/puppet/type/tidy.rb +6 -4
  265. data/lib/puppet/type/user.rb +26 -39
  266. data/lib/puppet/type/yumrepo.rb +9 -0
  267. data/lib/puppet/type/zfs.rb +4 -0
  268. data/lib/puppet/util.rb +8 -15
  269. data/lib/puppet/util/character_encoding.rb +2 -2
  270. data/lib/puppet/util/checksums.rb +82 -1
  271. data/lib/puppet/util/errors.rb +0 -2
  272. data/lib/puppet/util/filetype.rb +2 -2
  273. data/lib/puppet/util/json_lockfile.rb +1 -1
  274. data/lib/puppet/util/log.rb +1 -1
  275. data/lib/puppet/util/log/destinations.rb +10 -1
  276. data/lib/puppet/util/monkey_patches.rb +1 -1
  277. data/lib/puppet/util/network_device/cisco/device.rb +5 -5
  278. data/lib/puppet/util/network_device/config.rb +2 -3
  279. data/lib/puppet/util/platform.rb +13 -0
  280. data/lib/puppet/util/plist.rb +4 -4
  281. data/lib/puppet/util/rdoc/generators/puppet_generator.rb +2 -2
  282. data/lib/puppet/util/rdoc/parser/puppet_parser_rdoc2.rb +1 -1
  283. data/lib/puppet/util/reference.rb +8 -1
  284. data/lib/puppet/util/windows/adsi.rb +18 -15
  285. data/lib/puppet/util/windows/principal.rb +6 -7
  286. data/lib/puppet/util/windows/process.rb +1 -1
  287. data/lib/puppet/util/windows/registry.rb +2 -2
  288. data/lib/puppet/util/windows/sid.rb +7 -62
  289. data/lib/puppet/vendor/deep_merge/README.md +2 -2
  290. data/lib/puppet/vendor/pathspec/lib/pathspec/gitignorespec.rb +18 -18
  291. data/lib/puppet/vendor/semantic_puppet/lib/semantic_puppet/version.rb +2 -2
  292. data/lib/puppet/vendor/semantic_puppet/lib/semantic_puppet/version_range.rb +5 -5
  293. data/lib/puppet/vendor/semantic_puppet/locales/config.yaml +1 -1
  294. data/lib/puppet/version.rb +1 -1
  295. data/lib/puppet_pal.rb +874 -0
  296. data/locales/ja/puppet.po +140 -163
  297. data/locales/puppet.pot +940 -597
  298. data/man/man5/puppet.conf.5 +16 -91
  299. data/man/man8/puppet-agent.8 +2 -6
  300. data/man/man8/puppet-apply.8 +2 -2
  301. data/man/man8/puppet-ca.8 +1 -1
  302. data/man/man8/puppet-catalog.8 +1 -1
  303. data/man/man8/puppet-cert.8 +1 -1
  304. data/man/man8/puppet-certificate.8 +1 -1
  305. data/man/man8/puppet-certificate_request.8 +1 -1
  306. data/man/man8/puppet-certificate_revocation_list.8 +1 -1
  307. data/man/man8/puppet-config.8 +1 -1
  308. data/man/man8/puppet-describe.8 +1 -1
  309. data/man/man8/puppet-device.8 +11 -33
  310. data/man/man8/puppet-doc.8 +1 -1
  311. data/man/man8/puppet-epp.8 +1 -1
  312. data/man/man8/puppet-facts.8 +1 -1
  313. data/man/man8/puppet-filebucket.8 +4 -22
  314. data/man/man8/puppet-generate.8 +1 -1
  315. data/man/man8/puppet-help.8 +1 -1
  316. data/man/man8/puppet-key.8 +1 -1
  317. data/man/man8/puppet-lookup.8 +1 -1
  318. data/man/man8/puppet-man.8 +1 -1
  319. data/man/man8/puppet-master.8 +1 -1
  320. data/man/man8/puppet-module.8 +2 -11
  321. data/man/man8/puppet-node.8 +1 -1
  322. data/man/man8/puppet-parser.8 +1 -1
  323. data/man/man8/puppet-plugin.8 +1 -1
  324. data/man/man8/puppet-report.8 +1 -1
  325. data/man/man8/puppet-resource.8 +1 -1
  326. data/man/man8/puppet-status.8 +1 -1
  327. data/man/man8/puppet.8 +2 -2
  328. data/spec/integration/application/lookup_spec.rb +0 -21
  329. data/spec/integration/parser/compiler_spec.rb +18 -0
  330. data/spec/integration/parser/script_compiler_spec.rb +113 -0
  331. data/spec/integration/provider/mount_spec.rb +2 -0
  332. data/spec/integration/type/file_spec.rb +11 -3
  333. data/spec/integration/util/windows/adsi_spec.rb +1 -86
  334. data/spec/integration/util/windows/principal_spec.rb +1 -10
  335. data/spec/shared_contexts/checksum.rb +4 -1
  336. data/spec/shared_contexts/digests.rb +46 -1
  337. data/spec/shared_contexts/types_setup.rb +8 -3
  338. data/spec/unit/agent_spec.rb +2 -2
  339. data/spec/unit/application/cert_spec.rb +5 -17
  340. data/spec/unit/application/device_spec.rb +2 -96
  341. data/spec/unit/application/filebucket_spec.rb +18 -4
  342. data/spec/unit/configurer/plugin_handler_spec.rb +5 -32
  343. data/spec/unit/configurer_spec.rb +3 -3
  344. data/spec/unit/datatypes_spec.rb +304 -0
  345. data/spec/unit/defaults_spec.rb +41 -20
  346. data/spec/unit/face/config_spec.rb +46 -1
  347. data/spec/unit/face/epp_face_spec.rb +7 -3
  348. data/spec/unit/face/module/search_spec.rb +11 -0
  349. data/spec/unit/face/parser_spec.rb +2 -2
  350. data/spec/unit/file_bucket/dipper_spec.rb +12 -1
  351. data/spec/unit/forge/module_release_spec.rb +70 -0
  352. data/spec/unit/functions/break_spec.rb +34 -2
  353. data/spec/unit/functions/contain_spec.rb +1 -0
  354. data/spec/unit/functions/convert_to_spec.rb +22 -0
  355. data/spec/unit/functions/epp_spec.rb +5 -0
  356. data/spec/unit/functions/include_spec.rb +15 -0
  357. data/spec/unit/functions/module_directory_spec.rb +43 -0
  358. data/spec/unit/functions/new_spec.rb +14 -14
  359. data/spec/unit/functions/require_spec.rb +2 -0
  360. data/spec/unit/functions/shared.rb +12 -0
  361. data/spec/unit/functions/step_spec.rb +1 -1
  362. data/spec/unit/functions4_spec.rb +49 -4
  363. data/spec/unit/indirector/catalog/compiler_spec.rb +3 -3
  364. data/spec/unit/indirector/file_bucket_file/file_spec.rb +148 -94
  365. data/spec/unit/indirector/node/ldap_spec.rb +15 -12
  366. data/spec/unit/indirector/rest_spec.rb +0 -43
  367. data/spec/unit/interface/action_spec.rb +33 -0
  368. data/spec/unit/module_tool/applications/builder_spec.rb +7 -0
  369. data/spec/unit/module_tool/applications/installer_spec.rb +8 -0
  370. data/spec/unit/module_tool/applications/uninstaller_spec.rb +8 -0
  371. data/spec/unit/module_tool/applications/upgrader_spec.rb +6 -0
  372. data/spec/unit/network/http/connection_spec.rb +1 -1
  373. data/spec/unit/network/http/factory_spec.rb +28 -35
  374. data/spec/unit/parser/compiler_spec.rb +0 -8
  375. data/spec/unit/parser/environment_compiler_spec.rb +36 -0
  376. data/spec/unit/parser/functions/create_resources_spec.rb +9 -0
  377. data/spec/unit/parser/functions/inline_template_spec.rb +7 -0
  378. data/spec/unit/parser/functions/realize_spec.rb +9 -0
  379. data/spec/unit/parser/functions/tag_spec.rb +7 -0
  380. data/spec/unit/parser/functions/tagged_spec.rb +25 -0
  381. data/spec/unit/parser/functions/template_spec.rb +8 -0
  382. data/spec/unit/parser/scope_spec.rb +19 -0
  383. data/spec/unit/pops/evaluator/conditionals_spec.rb +1 -1
  384. data/spec/unit/pops/loaders/loader_spec.rb +516 -0
  385. data/spec/unit/pops/loaders/loaders_spec.rb +11 -0
  386. data/spec/unit/pops/loaders/module_loaders_spec.rb +43 -0
  387. data/spec/unit/pops/loaders/static_loader_spec.rb +15 -7
  388. data/spec/unit/pops/model/model_spec.rb +5 -0
  389. data/spec/unit/pops/parser/lexer2_spec.rb +15 -0
  390. data/spec/unit/pops/parser/locator_spec.rb +20 -0
  391. data/spec/unit/pops/parser/parse_basic_expressions_spec.rb +33 -0
  392. data/spec/unit/pops/parser/parse_calls_spec.rb +28 -0
  393. data/spec/unit/pops/parser/parse_conditionals_spec.rb +12 -0
  394. data/spec/unit/pops/parser/parse_plan_spec.rb +48 -0
  395. data/spec/unit/pops/serialization/packer_spec.rb +8 -0
  396. data/spec/unit/pops/serialization/serialization_spec.rb +30 -0
  397. data/spec/unit/pops/serialization/to_from_hr_spec.rb +31 -0
  398. data/spec/unit/pops/types/error_spec.rb +207 -0
  399. data/spec/unit/pops/types/p_init_type_spec.rb +98 -0
  400. data/spec/unit/pops/types/p_object_type_spec.rb +275 -10
  401. data/spec/unit/pops/types/p_uri_type_spec.rb +191 -0
  402. data/spec/unit/pops/types/ruby_generator_spec.rb +82 -44
  403. data/spec/unit/pops/types/task_spec.rb +353 -0
  404. data/spec/unit/pops/types/type_calculator_spec.rb +76 -5
  405. data/spec/unit/pops/types/type_formatter_spec.rb +31 -13
  406. data/spec/unit/pops/types/type_parser_spec.rb +13 -1
  407. data/spec/unit/pops/types/types_spec.rb +60 -0
  408. data/spec/unit/pops/validator/validator_spec.rb +76 -0
  409. data/spec/unit/provider/group/groupadd_spec.rb +77 -1
  410. data/spec/unit/provider/group/pw_spec.rb +4 -4
  411. data/spec/unit/provider/group/windows_adsi_spec.rb +22 -79
  412. data/spec/unit/provider/mount_spec.rb +18 -5
  413. data/spec/unit/provider/nameservice_spec.rb +5 -5
  414. data/spec/unit/provider/package/dnf_spec.rb +2 -2
  415. data/spec/unit/provider/package/gem_spec.rb +1 -1
  416. data/spec/unit/provider/package/pkg_spec.rb +3 -0
  417. data/spec/unit/provider/package/yum_spec.rb +40 -0
  418. data/spec/unit/provider/service/launchd_spec.rb +2 -1
  419. data/spec/unit/provider/service/redhat_spec.rb +5 -0
  420. data/spec/unit/provider/service/systemd_spec.rb +1 -1
  421. data/spec/unit/provider/user/hpux_spec.rb +2 -2
  422. data/spec/unit/provider/user/openbsd_spec.rb +2 -2
  423. data/spec/unit/provider/user/pw_spec.rb +14 -14
  424. data/spec/unit/provider/user/user_role_add_spec.rb +19 -2
  425. data/spec/unit/provider/user/useradd_spec.rb +188 -22
  426. data/spec/unit/provider/user/windows_adsi_spec.rb +4 -4
  427. data/spec/unit/provider/zfs/zfs_spec.rb +55 -1
  428. data/spec/unit/provider_spec.rb +48 -0
  429. data/spec/unit/puppet_pal_2pec.rb +1005 -0
  430. data/spec/unit/puppet_pal_spec.rb +11 -0
  431. data/spec/unit/settings/ini_file_spec.rb +313 -2
  432. data/spec/unit/ssl/certificate_request_spec.rb +42 -1
  433. data/spec/unit/ssl/certificate_revocation_list_spec.rb +2 -1
  434. data/spec/unit/transaction/report_spec.rb +1 -0
  435. data/spec/unit/transaction_spec.rb +112 -21
  436. data/spec/unit/type/file/checksum_spec.rb +20 -0
  437. data/spec/unit/type/file_spec.rb +8 -0
  438. data/spec/unit/type/group_spec.rb +8 -0
  439. data/spec/unit/type/k5login_spec.rb +22 -1
  440. data/spec/unit/type/scheduled_task_spec.rb +15 -0
  441. data/spec/unit/type/user_spec.rb +11 -1
  442. data/spec/unit/type/yumrepo_spec.rb +5 -0
  443. data/spec/unit/util/checksums_spec.rb +3 -3
  444. data/spec/unit/util/log/destinations_spec.rb +14 -0
  445. data/spec/unit/util/network_device/cisco/device_spec.rb +1 -1
  446. data/spec/unit/util/plist_spec.rb +3 -3
  447. data/spec/unit/util/windows/adsi_spec.rb +27 -31
  448. data/spec/unit/util/windows/sid_spec.rb +15 -86
  449. data/spec/unit/util_spec.rb +17 -3
  450. data/tasks/manpages.rake +1 -1
  451. metadata +216 -178
  452. data/lib/puppet/bindings.rb +0 -148
  453. data/lib/puppet/configurer/downloader_factory.rb +0 -44
  454. data/spec/unit/configurer/downloader_factory_spec.rb +0 -129
@@ -14,9 +14,7 @@ module Loader
14
14
  # modules" to determine which module loader to use for each individual module. (There could be differences in
15
15
  # internal layout etc.)
16
16
  #
17
- # A module loader is also not aware of the mapping of name to relative paths - this is performed by the
18
- # included module PathBasedInstantatorConfig which knows about the map from type/name to
19
- # relative path, and the logic that can instantiate what is expected to be found in the content of that path.
17
+ # A module loader is also not aware of the mapping of name to relative paths.
20
18
  #
21
19
  # @api private
22
20
  #
@@ -27,30 +25,34 @@ module ModuleLoaders
27
25
  # to search up the path from this source file's __FILE__ location until it finds the base of
28
26
  # puppet.
29
27
  #
30
- puppet_lib = File.join(File.dirname(__FILE__), '../../..')
31
- ModuleLoaders::FileBased.new(parent_loader,
28
+ puppet_lib = File.realpath(File.join(File.dirname(__FILE__), '../../..'))
29
+ LibRootedFileBased.new(parent_loader,
32
30
  loaders,
33
31
  nil,
34
32
  puppet_lib, # may or may not have a 'lib' above 'puppet'
35
33
  'puppet_system',
36
- [:func_4x] # only load ruby functions from "puppet"
34
+ [:func_4x, :datatype] # only load ruby functions and types from "puppet"
37
35
  )
38
36
  end
39
37
 
40
38
  def self.environment_loader_from(parent_loader, loaders, env_path)
41
- ModuleLoaders::FileBased.new(parent_loader,
42
- loaders,
43
- ENVIRONMENT,
44
- File.join(env_path, 'lib'),
45
- ENVIRONMENT
46
- )
39
+ if env_path.nil? || env_path.empty?
40
+ EmptyLoader.new(parent_loader, ENVIRONMENT)
41
+ else
42
+ FileBased.new(parent_loader,
43
+ loaders,
44
+ ENVIRONMENT,
45
+ env_path,
46
+ ENVIRONMENT
47
+ )
48
+ end
47
49
  end
48
50
 
49
51
  def self.module_loader_from(parent_loader, loaders, module_name, module_path)
50
52
  ModuleLoaders::FileBased.new(parent_loader,
51
53
  loaders,
52
54
  module_name,
53
- File.join(module_path, 'lib'),
55
+ module_path,
54
56
  module_name
55
57
  )
56
58
  end
@@ -64,6 +66,20 @@ module ModuleLoaders
64
66
  )
65
67
  end
66
68
 
69
+ class EmptyLoader < BaseLoader
70
+ def find(typed_name)
71
+ return nil
72
+ end
73
+
74
+ def private_loader
75
+ @private_loader ||= self
76
+ end
77
+
78
+ def private_loader=(loader)
79
+ @private_loader = loader
80
+ end
81
+ end
82
+
67
83
  class AbstractPathBasedModuleLoader < BaseLoader
68
84
 
69
85
  # The name of the module, or nil, if this is a global "component"
@@ -92,6 +108,8 @@ module ModuleLoaders
92
108
  def initialize(parent_loader, loaders, module_name, path, loader_name, loadables)
93
109
  super parent_loader, loader_name
94
110
 
111
+ raise ArgumentError, 'path based loader cannot be instantiated without a path' if path.nil? || path.empty?
112
+
95
113
  @module_name = module_name
96
114
  @path = path
97
115
  @smart_paths = LoaderPaths::SmartPaths.new(self)
@@ -108,6 +126,33 @@ module ModuleLoaders
108
126
  @loadables
109
127
  end
110
128
 
129
+ def discover(type, error_collector = nil, name_authority = Pcore::RUNTIME_NAME_AUTHORITY, &block)
130
+ global = global?
131
+ if name_authority == Pcore::RUNTIME_NAME_AUTHORITY
132
+ smart_paths.effective_paths(type).each do |sp|
133
+ relative_paths(sp).each do |rp|
134
+ tp = sp.typed_name(type, name_authority, rp, global ? nil : @module_name)
135
+ next unless sp.valid_name?(tp)
136
+ begin
137
+ load_typed(tp) unless block_given? && !block.yield(tp)
138
+ rescue StandardError => e
139
+ if error_collector.nil?
140
+ Puppet.warn_once(:unloadable_entity, tp.to_s, e.message)
141
+ else
142
+ err = Puppet::DataTypes::Error.new(
143
+ Issues::LOADER_FAILURE.format(:type => type),
144
+ 'PUPPET_LOADER_FAILURE',
145
+ { 'original_error' => e.message },
146
+ Issues::LOADER_FAILURE.issue_code)
147
+ error_collector << err unless error_collector.include?(err)
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end
153
+ super
154
+ end
155
+
111
156
  # Finds typed/named entity in this module
112
157
  # @param typed_name [TypedName] the type/name to find
113
158
  # @return [Loader::NamedEntry, nil found/created entry, or nil if not found
@@ -131,18 +176,42 @@ module ModuleLoaders
131
176
  else
132
177
  # The name is in the global name space.
133
178
 
134
- # The only globally name-spaced elements that may be loaded from modules are functions and resource types
135
179
  case typed_name.type
136
- when :function
137
- when :resource_type
138
- when :resource_type_pp
139
- when :type
180
+ when :function, :resource_type, :resource_type_pp
181
+ # Can be defined in module using a global name. No action required
182
+
183
+ when :plan
184
+ if !global?
185
+ # Global name must be the name of the module
186
+ return nil unless name_parts[0] == module_name
187
+
188
+ # Look for the special 'init' plan.
189
+ origin, smart_path = find_existing_path(init_plan_name)
190
+ return smart_path.nil? ? nil : instantiate(smart_path, typed_name, origin)
191
+ end
192
+
193
+ when :task
140
194
  if !global?
141
- # Global name can only be the module typeset
195
+ # Global name must be the name of the module
142
196
  return nil unless name_parts[0] == module_name
143
197
 
198
+ # Look for the special 'init' Task
199
+ origin, smart_path = find_existing_path(init_task_name)
200
+ return smart_path.nil? ? nil : instantiate(smart_path, typed_name, origin)
201
+ end
202
+
203
+ when :type
204
+ if !global?
205
+ # Global name must be the name of the module
206
+ unless name_parts[0] == module_name
207
+ # Check for ruby defined data type in global namespace before giving up
208
+ origin, smart_path = find_existing_path(typed_name)
209
+ return smart_path.is_a?(LoaderPaths::DataTypePath) ? instantiate(smart_path, typed_name, origin) : nil
210
+ end
211
+
212
+ # Look for the special 'init_typeset' TypeSet
144
213
  origin, smart_path = find_existing_path(init_typeset_name)
145
- return nil unless smart_path
214
+ return nil if smart_path.nil?
146
215
 
147
216
  value = smart_path.instantiator.create(self, typed_name, origin, get_contents(origin))
148
217
  if value.is_a?(Types::PTypeSetType)
@@ -165,11 +234,7 @@ module ModuleLoaders
165
234
  # The result is an array (that may be empty).
166
235
  # Find the file to instantiate, and instantiate the entity if file is found
167
236
  origin, smart_path = find_existing_path(typed_name)
168
- if smart_path
169
- value = smart_path.instantiator.create(self, typed_name, origin, get_contents(origin))
170
- # cache the entry and return it
171
- return set_entry(typed_name, value, origin)
172
- end
237
+ return instantiate(smart_path, typed_name, origin) unless smart_path.nil?
173
238
 
174
239
  return nil unless typed_name.type == :type && typed_name.qualified?
175
240
 
@@ -191,6 +256,16 @@ module ModuleLoaders
191
256
  nil
192
257
  end
193
258
 
259
+ def instantiate(smart_path, typed_name, origin)
260
+ if origin.is_a?(Array)
261
+ value = smart_path.instantiator.create(self, typed_name, origin)
262
+ else
263
+ value = smart_path.instantiator.create(self, typed_name, origin, get_contents(origin))
264
+ end
265
+ # cache the entry and return it
266
+ set_entry(typed_name, value, origin)
267
+ end
268
+
194
269
  # Abstract method that subclasses override that checks if it is meaningful to search using a generic smart path.
195
270
  # This optimization is performed to not be tricked into searching an empty directory over and over again.
196
271
  # The implementation may perform a deep search for file content other than directories and cache this in
@@ -210,12 +285,22 @@ module ModuleLoaders
210
285
  # Abstract method that subclasses override to answer if the given relative path exists, and if so returns that path
211
286
  #
212
287
  # @param resolved_path [String] a path resolved by a smart path against the loader's root (if it has one)
213
- # @return [Boolean] true if the file exists
288
+ # @return [String, nil] the found path or nil if no such path was found
214
289
  #
215
290
  def existing_path(resolved_path)
216
291
  raise NotImplementedError.new
217
292
  end
218
293
 
294
+ # Abstract method that subclasses override to return an array of paths that match the resolved path regardless of
295
+ # path extension.
296
+ #
297
+ # @param resolved_path [String] a path, without extension, resolved by a smart path against the loader's root (if it has one)
298
+ # @return [Array<String>]
299
+ #
300
+ def existing_paths(resolved_path)
301
+ raise NotImplementedError.new
302
+ end
303
+
219
304
  # Abstract method that subclasses override to produce the content of the effective path.
220
305
  # It should either succeed and return a String or fail with an exception.
221
306
  #
@@ -244,6 +329,16 @@ module ModuleLoaders
244
329
  module_name.nil? || module_name == ENVIRONMENT
245
330
  end
246
331
 
332
+ # Answers `true` if the loader used by this instance is rooted beneath 'lib'. This is
333
+ # typically true for the the system_loader. It will have a path relative to the parent
334
+ # of 'puppet' instead of the parent of 'lib/puppet' since the 'lib' directory of puppet
335
+ # is renamed during install. This is significant for loaders that load ruby code.
336
+ #
337
+ # @return [Boolean] a boolean answering if the loader is rooted beneath 'lib'.
338
+ def lib_root?
339
+ false
340
+ end
341
+
247
342
  # Produces the private loader for the module. If this module is not already resolved, this will trigger resolution
248
343
  #
249
344
  def private_loader
@@ -252,6 +347,15 @@ module ModuleLoaders
252
347
  @private_loader ||= (global? ? self : @loaders.private_loader_for_module(module_name))
253
348
  end
254
349
 
350
+ # Return all paths that matches the given smart path. The returned paths are
351
+ # relative to the `#generic_path` of the given smart path.
352
+ #
353
+ # @param smart_path [SmartPath] the path to find relative paths for
354
+ # @return [Array<String>] found paths
355
+ def relative_paths(smart_path)
356
+ raise NotImplementedError.new
357
+ end
358
+
255
359
  private
256
360
 
257
361
  # @return [TypedName] the fake typed name that maps to the init_typeset path for this module
@@ -259,16 +363,37 @@ module ModuleLoaders
259
363
  @init_typeset_name ||= TypedName.new(:type, "#{module_name}::init_typeset")
260
364
  end
261
365
 
262
- # Find an existing path for the given `typed_name`. Return `nil` if no such path is found
366
+ # @return [TypedName] the fake typed name that maps to the path of an init[arbitrary extension]
367
+ # file that represents a task named after the module
368
+ def init_task_name
369
+ @init_task_name ||= TypedName.new(:task, "#{module_name}::init")
370
+ end
371
+
372
+ # @return [TypedName] the fake typed name that maps to the path of an init.pp file that represents
373
+ # a plan named after the module
374
+ def init_plan_name
375
+ @init_plan_name ||= TypedName.new(:plan, "#{module_name}::init")
376
+ end
377
+
378
+ # Find an existing path or paths for the given `typed_name`. Return `nil` if no path is found
263
379
  # @param typed_name [TypedName] the `typed_name` to find a path for
264
- # @return [Array,nil] `nil`or a two element array an effective path `String` and the `SmartPath` that produced the effective path.
380
+ # @return [Array,nil] `nil`or a two element array where the first element is an effective path or array of paths
381
+ # (depending on the `SmartPath`) and the second element is the `SmartPath` that produced the effective path or
382
+ # paths. A path is a String
265
383
  def find_existing_path(typed_name)
266
384
  is_global = global?
267
385
  smart_paths.effective_paths(typed_name.type).each do |sp|
386
+ next unless sp.valid_name?(typed_name)
268
387
  origin = sp.effective_path(typed_name, is_global ? 0 : 1)
269
388
  unless origin.nil?
270
- existing = existing_path(origin)
271
- return [origin, sp] unless existing.nil?
389
+ if sp.match_many?
390
+ # Find all paths that starts with origin
391
+ origins = existing_paths(origin)
392
+ return [origins, sp] unless origins.empty?
393
+ else
394
+ existing = existing_path(origin)
395
+ return [origin, sp] unless existing.nil?
396
+ end
272
397
  end
273
398
  end
274
399
  nil
@@ -291,7 +416,7 @@ module ModuleLoaders
291
416
  #
292
417
  def initialize(parent_loader, loaders, module_name, path, loader_name, loadables = LOADABLE_KINDS)
293
418
  super
294
- @path_index = Set.new()
419
+ @path_index = Set.new
295
420
  end
296
421
 
297
422
  def existing_path(effective_path)
@@ -299,16 +424,32 @@ module ModuleLoaders
299
424
  @path_index.include?(effective_path) ? effective_path : nil
300
425
  end
301
426
 
427
+ def existing_paths(effective_path)
428
+ dirname = File.dirname(effective_path)
429
+ basename = File.basename(effective_path)
430
+ # Select all paths matching `effective_path` up until an optional file extension
431
+ @path_index.select do |path|
432
+ File.basename(path, '.*') == basename &&
433
+ File.dirname(path) == dirname
434
+ end
435
+ end
436
+
302
437
  def meaningful_to_search?(smart_path)
303
438
  ! add_to_index(smart_path).empty?
304
439
  end
305
440
 
306
441
  def to_s()
307
- "(ModuleLoader::FileBased '#{loader_name()}' '#{module_name()}')"
442
+ "(ModuleLoader::FileBased '#{loader_name}' '#{module_name}')"
308
443
  end
309
444
 
310
445
  def add_to_index(smart_path)
311
446
  found = Dir.glob(File.join(smart_path.generic_path, '**', "*#{smart_path.extension}"))
447
+
448
+ # The reason for not always rejecting directories here is performance (avoid extra stat calls). The
449
+ # false positives (directories with a matching extension) is an error in any case and will be caught
450
+ # later.
451
+ found = found.reject { |file_name| File.directory?(file_name) } if smart_path.extension.empty?
452
+
312
453
  @path_index.merge(found)
313
454
  found
314
455
  end
@@ -316,6 +457,34 @@ module ModuleLoaders
316
457
  def get_contents(effective_path)
317
458
  Puppet::FileSystem.read(effective_path, :encoding => 'utf-8')
318
459
  end
460
+
461
+ # Return all paths that matches the given smart path. The returned paths are
462
+ # relative to the `#generic_path` of the given smart path.
463
+ #
464
+ # This method relies on the cache and does not perform any file system access
465
+ #
466
+ # @param smart_path [SmartPath] the path to find relative paths for
467
+ # @return [Array<String>] found paths
468
+ def relative_paths(smart_path)
469
+ root = smart_path.generic_path
470
+ found = []
471
+ @path_index.each do |path|
472
+ found << Pathname(path).relative_path_from(Pathname(root)).to_s if smart_path.valid_path?(path)
473
+ end
474
+ found
475
+ end
476
+ end
477
+
478
+ # Specialization used by the system_loader which is limited to see what's beneath 'lib' and hence
479
+ # cannot be rooted in its parent. The 'lib' directory is renamed during install so any attempt
480
+ # to traverse into it from above would fail.
481
+ #
482
+ # @api private
483
+ #
484
+ class LibRootedFileBased < FileBased
485
+ def lib_root?
486
+ true
487
+ end
319
488
  end
320
489
 
321
490
  # Loads from a gem specified as a URI, gem://gemname/optional/path/in/gem, or just a String gemname.
@@ -346,7 +515,7 @@ module ModuleLoaders
346
515
  end
347
516
 
348
517
  def to_s()
349
- "(ModuleLoader::GemBased '#{loader_name()}' '#{@gem_ref}' [#{module_name()}])"
518
+ "(ModuleLoader::GemBased '#{loader_name}' '#{@gem_ref}' [#{module_name}])"
350
519
  end
351
520
  end
352
521
  end
@@ -0,0 +1,84 @@
1
+ module Puppet::Pops
2
+ module Loader
3
+ # The PuppetPlanInstantiator instantiates a Puppet::Functions::PuppetFunction given a Puppet Programming language
4
+ # source that when called evaluates the Puppet logic it contains.
5
+ #
6
+ class PuppetPlanInstantiator
7
+ # Produces an instance of the Function class with the given typed_name, or fails with an error if the
8
+ # given puppet source does not produce this instance when evaluated.
9
+ #
10
+ # @param loader [Loader] The loader the function is associated with
11
+ # @param typed_name [TypedName] the type / name of the function to load
12
+ # @param source_ref [URI, String] a reference to the source / origin of the puppet code to evaluate
13
+ # @param pp_code_string [String] puppet code in a string
14
+ #
15
+ # @return [Functions::Function] - an instantiated function with global scope closure associated with the given loader
16
+ #
17
+ def self.create(loader, typed_name, source_ref, pp_code_string)
18
+ parser = Parser::EvaluatingParser.new()
19
+
20
+ # parse and validate
21
+ result = parser.parse_string(pp_code_string, source_ref)
22
+ # Only one function is allowed (and no other definitions)
23
+ case result.definitions.size
24
+ when 0
25
+ raise ArgumentError, _("The code loaded from %{source_ref} does not define the plan '%{plan_name}' - it is empty.") % { source_ref: source_ref, plan_name: typed_name.name }
26
+ when 1
27
+ # ok
28
+ else
29
+ raise ArgumentError, _("The code loaded from %{source_ref} must contain only the plan '%{plan_name}' - it has additional definitions.") % { source_ref: source_ref, plan_name: typed_name.name }
30
+ end
31
+ the_plan_definition = result.definitions[0]
32
+
33
+ unless the_plan_definition.is_a?(Model::PlanDefinition)
34
+ raise ArgumentError, _("The code loaded from %{source_ref} does not define the plan '%{plan_name}' - no plan found.") % { source_ref: source_ref, plan_name: typed_name.name }
35
+ end
36
+ unless the_plan_definition.name == typed_name.name
37
+ expected = typed_name.name
38
+ actual = the_plan_definition.name
39
+ raise ArgumentError, _("The code loaded from %{source_ref} produced plan with the wrong name, expected %{expected}, actual %{actual}") % { source_ref: source_ref, expected: expected, actual: actual }
40
+ end
41
+ unless result.body == the_plan_definition
42
+ raise ArgumentError, _("The code loaded from %{source} contains additional logic - can only contain the plan %{plan_name}") % { source: source_ref, plan_name: typed_name.name }
43
+ end
44
+
45
+ # Adapt the function definition with loader - this is used from logic contained in it body to find the
46
+ # loader to use when making calls to the new function API. Such logic have a hard time finding the closure (where
47
+ # the loader is known - hence this mechanism
48
+ private_loader = loader.private_loader
49
+ Adapters::LoaderAdapter.adapt(the_plan_definition).loader_name = private_loader.loader_name
50
+
51
+ # Cannot bind loaded functions to global scope, that must be done without binding that scope as
52
+ # loaders survive a compilation.
53
+ closure_scope = nil
54
+
55
+ created = create_function_class(the_plan_definition)
56
+ # create the function instance - it needs closure (scope), and loader (i.e. where it should start searching for things
57
+ # when calling functions etc.
58
+ # It should be bound to global scope
59
+
60
+ created.new(closure_scope, private_loader)
61
+ end
62
+
63
+ # Creates Function class and instantiates it based on a FunctionDefinition model
64
+ # @return [Array<TypedName, Functions.Function>] - array of
65
+ # typed name, and an instantiated function with global scope closure associated with the given loader
66
+ #
67
+ def self.create_from_model(plan_definition, loader)
68
+ created = create_function_class(plan_definition)
69
+ typed_name = TypedName.new(:plan, plan_definition.name)
70
+ [typed_name, created.new(nil, loader)]
71
+ end
72
+
73
+ def self.create_function_class(plan_definition)
74
+ # Create a 4x function wrapper around a named closure
75
+ Puppet::Functions.create_function(plan_definition.name, Puppet::Functions::PuppetFunction) do
76
+ # TODO: should not create a new evaluator per function
77
+ init_dispatch(Evaluator::Closure::Named.new(
78
+ plan_definition.name,
79
+ Evaluator::EvaluatorImpl.new(), plan_definition))
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end