puppet 4.3.2 → 4.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 (487) hide show
  1. checksums.yaml +4 -4
  2. data/COMMITTERS.md +2 -2
  3. data/CONTRIBUTING.md +6 -6
  4. data/LICENSE +1 -1
  5. data/README.md +8 -9
  6. data/conf/auth.conf +2 -2
  7. data/ext/README.environment +1 -1
  8. data/ext/debian/README.source +1 -1
  9. data/ext/debian/control +1 -1
  10. data/ext/debian/copyright +4 -4
  11. data/ext/debian/puppetmaster.README.debian +11 -9
  12. data/ext/emacs/puppet-mode.el +1 -1
  13. data/ext/envpuppet +2 -2
  14. data/ext/ips/puppetagent.xml +1 -1
  15. data/ext/ips/puppetmaster.xml +1 -1
  16. data/ext/project_data.yaml +8 -0
  17. data/ext/puppet-test +3 -3
  18. data/ext/rack/example-passenger-vhost.conf +1 -1
  19. data/ext/redhat/puppet.spec.erb +2 -2
  20. data/ext/regexp_nodes/regexp_nodes.rb +1 -1
  21. data/ext/solaris/pkginfo +1 -1
  22. data/ext/solaris/smf/puppet.xml +1 -1
  23. data/ext/suse/puppet.spec +2 -2
  24. data/ext/upload_facts.rb +1 -1
  25. data/ext/windows/puppet_interactive.bat +6 -0
  26. data/ext/windows/puppet_shell.bat +9 -0
  27. data/ext/windows/run_puppet_interactive.bat +9 -0
  28. data/ext/yaml_nodes.rb +1 -1
  29. data/install.rb +30 -20
  30. data/lib/puppet/agent.rb +1 -1
  31. data/lib/puppet/application/agent.rb +4 -2
  32. data/lib/puppet/application/apply.rb +7 -4
  33. data/lib/puppet/application/cert.rb +1 -1
  34. data/lib/puppet/application/device.rb +1 -1
  35. data/lib/puppet/application/filebucket.rb +1 -1
  36. data/lib/puppet/application/inspect.rb +1 -1
  37. data/lib/puppet/application/lookup.rb +4 -4
  38. data/lib/puppet/application/master.rb +2 -2
  39. data/lib/puppet/application/resource.rb +1 -1
  40. data/lib/puppet/configurer.rb +100 -22
  41. data/lib/puppet/data_providers/hiera_config.rb +28 -3
  42. data/lib/puppet/data_providers/hiera_interpolate.rb +30 -15
  43. data/lib/puppet/data_providers/hiera_support.rb +1 -1
  44. data/lib/puppet/data_providers/json_data_provider_factory.rb +2 -2
  45. data/lib/puppet/data_providers/yaml_data_provider_factory.rb +2 -2
  46. data/lib/puppet/defaults.rb +65 -19
  47. data/lib/puppet/environments.rb +3 -1
  48. data/lib/puppet/face/config.rb +1 -1
  49. data/lib/puppet/face/epp.rb +1 -1
  50. data/lib/puppet/face/help/man.erb +1 -1
  51. data/lib/puppet/face/module/install.rb +6 -6
  52. data/lib/puppet/face/parser.rb +12 -9
  53. data/lib/puppet/face/status.rb +2 -1
  54. data/lib/puppet/feature/cfpropertylist.rb +3 -0
  55. data/lib/puppet/feature/telnet.rb +9 -0
  56. data/lib/puppet/file_serving/http_metadata.rb +46 -0
  57. data/lib/puppet/file_serving/metadata.rb +18 -2
  58. data/lib/puppet/file_serving/terminus_selector.rb +2 -0
  59. data/lib/puppet/file_system.rb +2 -2
  60. data/lib/puppet/file_system/file_impl.rb +2 -2
  61. data/lib/puppet/file_system/memory_impl.rb +1 -1
  62. data/lib/puppet/file_system/uniquefile.rb +1 -1
  63. data/lib/puppet/forge.rb +1 -1
  64. data/lib/puppet/forge/repository.rb +1 -31
  65. data/lib/puppet/functions.rb +45 -6
  66. data/lib/puppet/functions/assert_type.rb +9 -9
  67. data/lib/puppet/functions/each.rb +5 -13
  68. data/lib/puppet/functions/filter.rb +5 -14
  69. data/lib/puppet/functions/map.rb +6 -14
  70. data/lib/puppet/functions/reduce.rb +5 -13
  71. data/lib/puppet/functions/reverse_each.rb +82 -0
  72. data/lib/puppet/functions/scanf.rb +15 -18
  73. data/lib/puppet/functions/slice.rb +22 -36
  74. data/lib/puppet/functions/split.rb +2 -2
  75. data/lib/puppet/functions/step.rb +88 -0
  76. data/lib/puppet/functions/type.rb +70 -0
  77. data/lib/puppet/graph/rb_tree_map.rb +1 -1
  78. data/lib/puppet/indirector/catalog/compiler.rb +188 -5
  79. data/lib/puppet/indirector/file_content/http.rb +15 -0
  80. data/lib/puppet/indirector/file_metadata/http.rb +27 -0
  81. data/lib/puppet/indirector/generic_http.rb +16 -0
  82. data/lib/puppet/indirector/node/exec.rb +1 -1
  83. data/lib/puppet/indirector/node/ldap.rb +1 -1
  84. data/lib/puppet/indirector/rest.rb +2 -1
  85. data/lib/puppet/info_service/class_information_service.rb +13 -12
  86. data/lib/puppet/loaders.rb +1 -0
  87. data/lib/puppet/module.rb +3 -0
  88. data/lib/puppet/module_tool/skeleton/templates/generator/Gemfile +9 -2
  89. data/lib/puppet/module_tool/skeleton/templates/generator/spec/classes/init_spec.rb.erb +1 -1
  90. data/lib/puppet/module_tool/skeleton/templates/generator/tests/init.pp.erb +2 -2
  91. data/lib/puppet/module_tool/tar/mini.rb +3 -3
  92. data/lib/puppet/network/http/pool.rb +9 -0
  93. data/lib/puppet/node.rb +1 -1
  94. data/lib/puppet/node/environment.rb +11 -2
  95. data/lib/puppet/parser/ast/pops_bridge.rb +19 -22
  96. data/lib/puppet/parser/compiler.rb +3 -3
  97. data/lib/puppet/parser/environment_compiler.rb +0 -1
  98. data/lib/puppet/parser/functions.rb +28 -16
  99. data/lib/puppet/parser/functions/fqdn_rand.rb +1 -1
  100. data/lib/puppet/parser/functions/inline_template.rb +1 -1
  101. data/lib/puppet/parser/functions/map.rb +1 -1
  102. data/lib/puppet/parser/functions/scanf.rb +15 -26
  103. data/lib/puppet/parser/functions/slice.rb +17 -24
  104. data/lib/puppet/parser/functions/split.rb +1 -1
  105. data/lib/puppet/parser/resource.rb +19 -17
  106. data/lib/puppet/parser/scope.rb +176 -5
  107. data/lib/puppet/plugins/data_providers/data_provider.rb +54 -13
  108. data/lib/puppet/pops.rb +0 -8
  109. data/lib/puppet/pops/adaptable.rb +4 -1
  110. data/lib/puppet/pops/adapters.rb +38 -13
  111. data/lib/puppet/pops/binder/binder.rb +21 -17
  112. data/lib/puppet/pops/binder/binder_issues.rb +8 -6
  113. data/lib/puppet/pops/binder/bindings_checker.rb +12 -8
  114. data/lib/puppet/pops/binder/bindings_composer.rb +16 -12
  115. data/lib/puppet/pops/binder/bindings_factory.rb +108 -104
  116. data/lib/puppet/pops/binder/bindings_model.rb +49 -47
  117. data/lib/puppet/pops/binder/config/diagnostic_producer.rb +10 -6
  118. data/lib/puppet/pops/binder/injector.rb +53 -48
  119. data/lib/puppet/pops/binder/key_factory.rb +10 -6
  120. data/lib/puppet/pops/binder/producers.rb +67 -62
  121. data/lib/puppet/pops/evaluator/access_operator.rb +95 -93
  122. data/lib/puppet/pops/evaluator/closure.rb +84 -68
  123. data/lib/puppet/pops/evaluator/collector_transformer.rb +18 -14
  124. data/lib/puppet/pops/evaluator/collectors/exported_collector.rb +0 -1
  125. data/lib/puppet/pops/evaluator/compare_operator.rb +13 -9
  126. data/lib/puppet/pops/evaluator/epp_evaluator.rb +9 -8
  127. data/lib/puppet/pops/evaluator/evaluator_impl.rb +78 -76
  128. data/lib/puppet/pops/evaluator/json_strict_literal_evaluator.rb +85 -0
  129. data/lib/puppet/pops/evaluator/relationship_operator.rb +13 -11
  130. data/lib/puppet/pops/evaluator/runtime3_converter.rb +5 -0
  131. data/lib/puppet/pops/evaluator/runtime3_support.rb +41 -45
  132. data/lib/puppet/pops/issue_reporter.rb +6 -4
  133. data/lib/puppet/pops/issues.rb +34 -11
  134. data/lib/puppet/pops/loader/base_loader.rb +1 -1
  135. data/lib/puppet/pops/loader/loader.rb +1 -1
  136. data/lib/puppet/pops/loader/loader_paths.rb +15 -0
  137. data/lib/puppet/pops/loader/module_loaders.rb +17 -13
  138. data/lib/puppet/pops/loader/puppet_function_instantiator.rb +16 -12
  139. data/lib/puppet/pops/loader/ruby_function_instantiator.rb +16 -3
  140. data/lib/puppet/pops/loader/type_definition_instantiator.rb +55 -0
  141. data/lib/puppet/pops/loaders.rb +51 -9
  142. data/lib/puppet/pops/lookup.rb +14 -12
  143. data/lib/puppet/pops/merge_strategy.rb +16 -19
  144. data/lib/puppet/pops/model/factory.rb +26 -2
  145. data/lib/puppet/pops/model/model.rb +8 -8
  146. data/lib/puppet/pops/model/model_label_provider.rb +13 -7
  147. data/lib/puppet/pops/model/model_meta.rb +17 -0
  148. data/lib/puppet/pops/model/model_tree_dumper.rb +8 -0
  149. data/lib/puppet/pops/parser/egrammar.ra +38 -14
  150. data/lib/puppet/pops/parser/eparser.rb +1353 -1276
  151. data/lib/puppet/pops/parser/epp_support.rb +11 -7
  152. data/lib/puppet/pops/parser/evaluating_parser.rb +14 -10
  153. data/lib/puppet/pops/parser/heredoc_support.rb +15 -11
  154. data/lib/puppet/pops/parser/lexer2.rb +26 -19
  155. data/lib/puppet/pops/parser/lexer_support.rb +85 -7
  156. data/lib/puppet/pops/parser/locator.rb +21 -0
  157. data/lib/puppet/pops/parser/parser_support.rb +19 -16
  158. data/lib/puppet/pops/parser/slurp_support.rb +11 -7
  159. data/lib/puppet/pops/types/class_loader.rb +23 -19
  160. data/lib/puppet/pops/types/enumeration.rb +9 -26
  161. data/lib/puppet/pops/types/iterable.rb +308 -0
  162. data/lib/puppet/pops/types/recursion_guard.rb +82 -0
  163. data/lib/puppet/pops/types/type_acceptor.rb +25 -0
  164. data/lib/puppet/pops/types/type_asserter.rb +10 -9
  165. data/lib/puppet/pops/types/type_calculator.rb +138 -381
  166. data/lib/puppet/pops/types/type_factory.rb +91 -57
  167. data/lib/puppet/pops/types/type_formatter.rb +334 -0
  168. data/lib/puppet/pops/types/type_mismatch_describer.rb +226 -59
  169. data/lib/puppet/pops/types/type_parser.rb +159 -112
  170. data/lib/puppet/pops/types/types.rb +2057 -1247
  171. data/lib/puppet/pops/utils.rb +11 -10
  172. data/lib/puppet/pops/validation.rb +11 -9
  173. data/lib/puppet/pops/validation/checker4_0.rb +83 -55
  174. data/lib/puppet/pops/validation/validator_factory_4_0.rb +8 -4
  175. data/lib/puppet/provider/aixobject.rb +1 -1
  176. data/lib/puppet/provider/augeas/augeas.rb +1 -1
  177. data/lib/puppet/provider/cron/crontab.rb +1 -1
  178. data/lib/puppet/provider/exec/windows.rb +1 -1
  179. data/lib/puppet/provider/macauthorization/macauthorization.rb +10 -9
  180. data/lib/puppet/provider/nameservice/directoryservice.rb +35 -50
  181. data/lib/puppet/provider/package/appdmg.rb +3 -2
  182. data/lib/puppet/provider/package/dnf.rb +1 -1
  183. data/lib/puppet/provider/package/pip.rb +5 -8
  184. data/lib/puppet/provider/package/pip3.rb +1 -1
  185. data/lib/puppet/provider/package/pkg.rb +1 -1
  186. data/lib/puppet/provider/package/pkgdmg.rb +3 -2
  187. data/lib/puppet/provider/package/pkgng.rb +13 -4
  188. data/lib/puppet/provider/package/windows.rb +1 -1
  189. data/lib/puppet/provider/package/yum.rb +1 -1
  190. data/lib/puppet/provider/package/zypper.rb +19 -0
  191. data/lib/puppet/provider/service/debian.rb +2 -2
  192. data/lib/puppet/provider/service/launchd.rb +6 -18
  193. data/lib/puppet/provider/service/systemd.rb +9 -2
  194. data/lib/puppet/provider/sshkey/parsed.rb +1 -1
  195. data/lib/puppet/provider/user/aix.rb +1 -1
  196. data/lib/puppet/provider/user/directoryservice.rb +33 -58
  197. data/lib/puppet/provider/zfs/zfs.rb +1 -1
  198. data/lib/puppet/provider/zpool/zpool.rb +1 -1
  199. data/lib/puppet/reference/configuration.rb +1 -1
  200. data/lib/puppet/reference/providers.rb +1 -1
  201. data/lib/puppet/resource.rb +15 -12
  202. data/lib/puppet/resource/capability_finder.rb +20 -13
  203. data/lib/puppet/resource/catalog.rb +60 -3
  204. data/lib/puppet/resource/status.rb +11 -2
  205. data/lib/puppet/resource/type.rb +28 -38
  206. data/lib/puppet/settings.rb +1 -1
  207. data/lib/puppet/settings/config_file.rb +1 -1
  208. data/lib/puppet/settings/environment_conf.rb +13 -5
  209. data/lib/puppet/ssl/certificate_factory.rb +3 -3
  210. data/lib/puppet/ssl/certificate_request.rb +4 -4
  211. data/lib/puppet/ssl/certificate_signer.rb +1 -1
  212. data/lib/puppet/ssl/validator/default_validator.rb +1 -1
  213. data/lib/puppet/test/test_helper.rb +16 -4
  214. data/lib/puppet/transaction.rb +15 -2
  215. data/lib/puppet/transaction/additional_resource_generator.rb +6 -2
  216. data/lib/puppet/transaction/report.rb +31 -1
  217. data/lib/puppet/transaction/resource_harness.rb +0 -25
  218. data/lib/puppet/type.rb +11 -11
  219. data/lib/puppet/type/augeas.rb +1 -1
  220. data/lib/puppet/type/cron.rb +12 -12
  221. data/lib/puppet/type/file.rb +91 -39
  222. data/lib/puppet/type/file/checksum_value.rb +53 -0
  223. data/lib/puppet/type/file/content.rb +26 -111
  224. data/lib/puppet/type/file/data_sync.rb +84 -0
  225. data/lib/puppet/type/file/ensure.rb +17 -14
  226. data/lib/puppet/type/file/selcontext.rb +1 -1
  227. data/lib/puppet/type/file/source.rb +103 -18
  228. data/lib/puppet/type/filebucket.rb +1 -1
  229. data/lib/puppet/type/interface.rb +8 -3
  230. data/lib/puppet/type/macauthorization.rb +1 -1
  231. data/lib/puppet/type/package.rb +6 -0
  232. data/lib/puppet/type/schedule.rb +1 -1
  233. data/lib/puppet/type/stage.rb +1 -1
  234. data/lib/puppet/type/user.rb +19 -17
  235. data/lib/puppet/type/yumrepo.rb +20 -0
  236. data/lib/puppet/util.rb +109 -22
  237. data/lib/puppet/util/autoload.rb +16 -11
  238. data/lib/puppet/util/checksums.rb +74 -31
  239. data/lib/puppet/util/execution.rb +1 -1
  240. data/lib/puppet/util/http_proxy.rb +72 -0
  241. data/lib/puppet/util/log.rb +2 -0
  242. data/lib/puppet/util/logging.rb +43 -1
  243. data/lib/puppet/util/monkey_patches.rb +2 -2
  244. data/lib/puppet/util/multi_match.rb +51 -0
  245. data/lib/puppet/util/network_device/cisco/device.rb +10 -2
  246. data/lib/puppet/util/network_device/cisco/interface.rb +21 -8
  247. data/lib/puppet/util/network_device/transport/ssh.rb +7 -3
  248. data/lib/puppet/util/network_device/transport/telnet.rb +39 -36
  249. data/lib/puppet/util/plist.rb +130 -0
  250. data/lib/puppet/util/resource_template.rb +1 -1
  251. data/lib/puppet/util/run_mode.rb +2 -2
  252. data/lib/puppet/util/skip_tags.rb +9 -0
  253. data/lib/puppet/util/windows/access_control_entry.rb +1 -1
  254. data/lib/puppet/util/windows/access_control_list.rb +3 -3
  255. data/lib/puppet/util/windows/adsi.rb +4 -4
  256. data/lib/puppet/util/windows/api_types.rb +24 -18
  257. data/lib/puppet/util/windows/com.rb +3 -3
  258. data/lib/puppet/util/windows/error.rb +1 -1
  259. data/lib/puppet/util/windows/file.rb +8 -8
  260. data/lib/puppet/util/windows/principal.rb +23 -14
  261. data/lib/puppet/util/windows/process.rb +78 -11
  262. data/lib/puppet/util/windows/registry.rb +1 -1
  263. data/lib/puppet/util/windows/root_certs.rb +5 -5
  264. data/lib/puppet/util/windows/security.rb +33 -35
  265. data/lib/puppet/util/windows/security_descriptor.rb +1 -1
  266. data/lib/puppet/util/windows/sid.rb +42 -4
  267. data/lib/puppet/util/windows/taskscheduler.rb +15 -15
  268. data/lib/puppet/util/windows/user.rb +10 -10
  269. data/lib/puppet/vendor/deep_merge/deep_merge.gemspec +1 -1
  270. data/lib/puppet/vendor/pathspec/LICENSE +2 -2
  271. data/lib/puppet/vendor/pathspec/README.md +1 -1
  272. data/lib/puppet/vendor/rgen/README.rdoc +1 -1
  273. data/lib/puppet/vendor/semantic/lib/semantic/dependency/module_release.rb +14 -0
  274. data/lib/puppet/version.rb +1 -1
  275. data/lib/semver.rb +17 -1
  276. data/man/man5/puppet.conf.5 +12 -12
  277. data/man/man8/extlookup2hiera.8 +1 -1
  278. data/man/man8/puppet-agent.8 +2 -2
  279. data/man/man8/puppet-apply.8 +2 -2
  280. data/man/man8/puppet-ca.8 +2 -2
  281. data/man/man8/puppet-catalog.8 +2 -2
  282. data/man/man8/puppet-cert.8 +2 -2
  283. data/man/man8/puppet-certificate.8 +2 -2
  284. data/man/man8/puppet-certificate_request.8 +2 -2
  285. data/man/man8/puppet-certificate_revocation_list.8 +2 -2
  286. data/man/man8/puppet-config.8 +3 -3
  287. data/man/man8/puppet-describe.8 +1 -1
  288. data/man/man8/puppet-device.8 +1 -1
  289. data/man/man8/puppet-doc.8 +1 -1
  290. data/man/man8/puppet-epp.8 +2 -2
  291. data/man/man8/puppet-facts.8 +2 -2
  292. data/man/man8/puppet-file.8 +2 -2
  293. data/man/man8/puppet-filebucket.8 +2 -2
  294. data/man/man8/puppet-help.8 +2 -2
  295. data/man/man8/puppet-inspect.8 +2 -2
  296. data/man/man8/puppet-key.8 +2 -2
  297. data/man/man8/puppet-man.8 +2 -2
  298. data/man/man8/puppet-master.8 +2 -2
  299. data/man/man8/puppet-module.8 +9 -9
  300. data/man/man8/puppet-node.8 +2 -2
  301. data/man/man8/puppet-parser.8 +2 -2
  302. data/man/man8/puppet-plugin.8 +2 -2
  303. data/man/man8/puppet-report.8 +2 -2
  304. data/man/man8/puppet-resource.8 +2 -2
  305. data/man/man8/puppet-resource_type.8 +2 -2
  306. data/man/man8/puppet-status.8 +3 -3
  307. data/man/man8/puppet.8 +1 -1
  308. data/spec/fixtures/module.tar.gz +0 -0
  309. data/spec/fixtures/unit/functions/lookup/environments/production/modules/bad_data/lib/puppet/functions/bad_data/data.rb +1 -0
  310. data/spec/fixtures/unit/functions/lookup/environments/production/modules/bad_data/manifests/init.pp +0 -1
  311. data/spec/fixtures/unit/functions/lookup/environments/production/modules/empty_json/data/empty.json +0 -0
  312. data/spec/fixtures/unit/functions/lookup/environments/production/modules/empty_json/hiera.yaml +5 -0
  313. data/spec/fixtures/unit/functions/lookup/environments/production/modules/empty_json/manifests/init.pp +2 -0
  314. data/spec/fixtures/unit/functions/lookup/environments/production/modules/empty_json/metadata.json +9 -0
  315. data/spec/fixtures/unit/functions/lookup/environments/production/modules/empty_yaml/data/empty.yaml +1 -0
  316. data/spec/fixtures/unit/functions/lookup/environments/production/modules/empty_yaml/hiera.yaml +5 -0
  317. data/spec/fixtures/unit/functions/lookup/environments/production/modules/empty_yaml/manifests/init.pp +2 -0
  318. data/spec/fixtures/unit/functions/lookup/environments/production/modules/empty_yaml/metadata.json +9 -0
  319. data/spec/fixtures/unit/functions/lookup/environments/production/modules/hieraprovider/data/first.json +2 -1
  320. data/spec/fixtures/unit/module/trailing-comma.json +1 -1
  321. data/spec/fixtures/unit/pops/loaders/loaders/dependent_modules_with_metadata/modules/usee/manifests/init.pp +3 -1
  322. data/spec/fixtures/unit/pops/loaders/loaders/dependent_modules_with_metadata/modules/usee/types/zero.pp +1 -0
  323. data/spec/fixtures/unit/pops/loaders/loaders/dependent_modules_with_metadata/modules/user/types/withuseeone.pp +1 -0
  324. data/spec/fixtures/unit/pops/loaders/loaders/dependent_modules_with_metadata/modules/user/types/withuseezero.pp +1 -0
  325. data/spec/fixtures/unit/provider/package/yum/yum-check-update-broken-notices.txt +187 -0
  326. data/spec/fixtures/unit/provider/sshkey/parsed/sample_with_blank_lines +8 -0
  327. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_md5/should_fetch_if_not_on_the_local_disk.yml +205 -0
  328. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_md5/should_not_update_if_content_on_disk_is_up-to-date.yml +213 -0
  329. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_md5/should_update_if_content_differs_on_disk.yml +213 -0
  330. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_mtime_is_older_on_disk.yml +205 -0
  331. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_no_header_specified.yml +197 -0
  332. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_not_on_the_local_disk.yml +205 -0
  333. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_not_update_if_mtime_is_newer_on_disk.yml +205 -0
  334. data/spec/integration/defaults_spec.rb +14 -2
  335. data/spec/integration/file_system/uniquefile_spec.rb +29 -0
  336. data/spec/integration/module_tool/tar/mini_spec.rb +28 -0
  337. data/spec/integration/node/environment_spec.rb +13 -0
  338. data/spec/integration/parser/dynamic_scoping_spec.rb +67 -0
  339. data/spec/integration/parser/parameter_defaults_spec.rb +336 -0
  340. data/spec/integration/parser/undef_param_spec.rb +8 -0
  341. data/spec/integration/provider/yumrepo_spec.rb +1 -1
  342. data/spec/integration/test/test_helper_spec.rb +28 -0
  343. data/spec/integration/transaction/report_spec.rb +16 -0
  344. data/spec/integration/transaction_spec.rb +11 -0
  345. data/spec/integration/type/file_spec.rb +194 -4
  346. data/spec/integration/type/package_spec.rb +5 -1
  347. data/spec/integration/type/tidy_spec.rb +21 -9
  348. data/spec/integration/util/execution_spec.rb +22 -0
  349. data/spec/integration/util/windows/principal_spec.rb +90 -4
  350. data/spec/integration/util/windows/process_spec.rb +31 -0
  351. data/spec/integration/util/windows/security_spec.rb +6 -6
  352. data/spec/integration/util/windows/user_spec.rb +1 -1
  353. data/spec/integration/util_spec.rb +49 -27
  354. data/spec/lib/puppet_spec/compiler.rb +17 -0
  355. data/spec/lib/puppet_spec/files.rb +2 -2
  356. data/spec/lib/puppet_spec/pops.rb +13 -0
  357. data/spec/shared_behaviours/iterative_functions.rb +1 -1
  358. data/spec/shared_contexts/types_setup.rb +96 -0
  359. data/spec/unit/agent_spec.rb +1 -0
  360. data/spec/unit/application/agent_spec.rb +10 -0
  361. data/spec/unit/application/apply_spec.rb +9 -0
  362. data/spec/unit/configurer/downloader_spec.rb +5 -5
  363. data/spec/unit/configurer_spec.rb +271 -39
  364. data/spec/unit/data_providers/hiera_interpolation_spec.rb +57 -0
  365. data/spec/unit/defaults_spec.rb +15 -0
  366. data/spec/unit/environments_spec.rb +24 -4
  367. data/spec/unit/face/parser_spec.rb +43 -2
  368. data/spec/unit/file_serving/http_metadata_spec.rb +85 -0
  369. data/spec/unit/file_serving/metadata_spec.rb +50 -0
  370. data/spec/unit/file_serving/terminus_selector_spec.rb +12 -2
  371. data/spec/unit/file_system_spec.rb +26 -0
  372. data/spec/unit/functions/assert_type_spec.rb +36 -2
  373. data/spec/unit/functions/defined_spec.rb +2 -2
  374. data/spec/unit/functions/epp_spec.rb +11 -3
  375. data/spec/unit/functions/lookup_spec.rb +58 -13
  376. data/spec/unit/functions/regsubst_spec.rb +1 -1
  377. data/spec/unit/functions/reverse_each_spec.rb +108 -0
  378. data/spec/unit/functions/step_spec.rb +113 -0
  379. data/spec/unit/functions/type_spec.rb +35 -0
  380. data/spec/unit/functions4_spec.rb +61 -5
  381. data/spec/unit/indirector/catalog/compiler_spec.rb +705 -4
  382. data/spec/unit/indirector/file_bucket_file/file_spec.rb +1 -1
  383. data/spec/unit/indirector/indirection_spec.rb +1 -1
  384. data/spec/unit/info_service_spec.rb +94 -32
  385. data/spec/unit/module_spec.rb +14 -0
  386. data/spec/unit/module_tool/applications/builder_spec.rb +4 -4
  387. data/spec/unit/network/authstore_spec.rb +1 -1
  388. data/spec/unit/network/http/connection_spec.rb +1 -0
  389. data/spec/unit/network/http/pool_spec.rb +30 -0
  390. data/spec/unit/node_spec.rb +1 -1
  391. data/spec/unit/parser/compiler_spec.rb +16 -0
  392. data/spec/unit/parser/scope_spec.rb +28 -11
  393. data/spec/unit/pops/evaluator/access_ops_spec.rb +3 -3
  394. data/spec/unit/pops/evaluator/comparison_ops_spec.rb +3 -0
  395. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +7 -1
  396. data/spec/unit/pops/evaluator/evaluator_rspec_helper.rb +4 -4
  397. data/spec/unit/pops/evaluator/json_strict_literal_evaluator_spec.rb +63 -0
  398. data/spec/unit/pops/evaluator/runtime3_converter_spec.rb +6 -0
  399. data/spec/unit/pops/loaders/dependency_loader_spec.rb +53 -0
  400. data/spec/unit/pops/loaders/loaders_spec.rb +44 -1
  401. data/spec/unit/pops/parser/lexer2_spec.rb +112 -3
  402. data/spec/unit/pops/parser/parse_calls_spec.rb +8 -0
  403. data/spec/unit/pops/parser/parser_spec.rb +10 -0
  404. data/spec/unit/pops/parser/source_pos_adapter_spec.rb +26 -0
  405. data/spec/unit/pops/types/iterable_spec.rb +262 -0
  406. data/spec/unit/pops/types/recursion_guard_spec.rb +91 -0
  407. data/spec/unit/pops/types/type_acceptor_spec.rb +105 -0
  408. data/spec/unit/pops/types/type_asserter_spec.rb +43 -0
  409. data/spec/unit/pops/types/type_calculator_spec.rb +275 -373
  410. data/spec/unit/pops/types/type_formatter_spec.rb +280 -0
  411. data/spec/unit/pops/types/type_mismatch_describer_spec.rb +152 -0
  412. data/spec/unit/pops/types/type_parser_spec.rb +58 -13
  413. data/spec/unit/pops/types/types_spec.rb +241 -0
  414. data/spec/unit/pops/validator/validator_spec.rb +100 -43
  415. data/spec/unit/provider/cron/parsed_spec.rb +1 -0
  416. data/spec/unit/provider/macauthorization_spec.rb +5 -2
  417. data/spec/unit/provider/nameservice/directoryservice_spec.rb +14 -19
  418. data/spec/unit/provider/package/appdmg_spec.rb +3 -3
  419. data/spec/unit/provider/package/dnf_spec.rb +16 -0
  420. data/spec/unit/provider/package/pip3_spec.rb +60 -42
  421. data/spec/unit/provider/package/pip_spec.rb +47 -34
  422. data/spec/unit/provider/package/pkgdmg_spec.rb +18 -9
  423. data/spec/unit/provider/package/pkgng_spec.rb +4 -2
  424. data/spec/unit/provider/package/yum_spec.rb +11 -0
  425. data/spec/unit/provider/package/zypper_spec.rb +14 -0
  426. data/spec/unit/provider/service/launchd_spec.rb +17 -35
  427. data/spec/unit/provider/service/systemd_spec.rb +7 -0
  428. data/spec/unit/provider/sshkey/parsed_spec.rb +20 -19
  429. data/spec/unit/provider/user/directoryservice_spec.rb +40 -59
  430. data/spec/unit/resource/capability_finder_spec.rb +28 -15
  431. data/spec/unit/resource/catalog_spec.rb +33 -1
  432. data/spec/unit/resource/type_spec.rb +149 -7
  433. data/spec/unit/resource_spec.rb +96 -57
  434. data/spec/unit/settings/environment_conf_spec.rb +18 -1
  435. data/spec/unit/ssl/certificate_revocation_list_spec.rb +3 -3
  436. data/spec/unit/transaction/report_spec.rb +27 -0
  437. data/spec/unit/transaction/resource_harness_spec.rb +0 -47
  438. data/spec/unit/transaction_spec.rb +5 -0
  439. data/spec/unit/type/file/checksum_spec.rb +6 -0
  440. data/spec/unit/type/file/checksum_value_spec.rb +286 -0
  441. data/spec/unit/type/file/content_spec.rb +12 -193
  442. data/spec/unit/type/file/source_spec.rb +211 -119
  443. data/spec/unit/type/file_spec.rb +133 -34
  444. data/spec/unit/type/interface_spec.rb +32 -0
  445. data/spec/unit/type/macauthorization_spec.rb +4 -1
  446. data/spec/unit/type/yumrepo_spec.rb +2 -2
  447. data/spec/unit/util/filetype_spec.rb +1 -1
  448. data/spec/unit/util/http_proxy_spec.rb +2 -2
  449. data/spec/unit/util/log/destinations_spec.rb +0 -2
  450. data/spec/unit/util/logging_spec.rb +69 -0
  451. data/spec/unit/util/multi_match_spec.rb +39 -0
  452. data/spec/unit/util/network_device/cisco/device_spec.rb +253 -216
  453. data/spec/unit/util/network_device/transport/telnet_spec.rb +60 -58
  454. data/spec/unit/util/plist_spec.rb +110 -0
  455. data/spec/unit/util/resource_template_spec.rb +2 -2
  456. data/spec/unit/util/run_mode_spec.rb +27 -3
  457. data/spec/unit/util/windows/adsi_spec.rb +4 -4
  458. data/spec/unit/util/windows/api_types_spec.rb +42 -0
  459. data/spec/unit/util/windows/security_descriptor_spec.rb +3 -3
  460. data/spec/unit/util/windows/sid_spec.rb +1 -1
  461. data/spec/unit/util_spec.rb +123 -13
  462. data/tasks/cfpropertylist.rake +15 -0
  463. metadata +114 -26
  464. data/lib/puppet/vendor/load_plist.rb +0 -1
  465. data/lib/puppet/vendor/plist/CHANGELOG +0 -82
  466. data/lib/puppet/vendor/plist/MIT-LICENSE +0 -21
  467. data/lib/puppet/vendor/plist/PUPPET_README.md +0 -6
  468. data/lib/puppet/vendor/plist/README +0 -36
  469. data/lib/puppet/vendor/plist/Rakefile +0 -144
  470. data/lib/puppet/vendor/plist/docs/USAGE +0 -104
  471. data/lib/puppet/vendor/plist/docs/jamis-template.rb +0 -591
  472. data/lib/puppet/vendor/plist/lib/plist.rb +0 -22
  473. data/lib/puppet/vendor/plist/lib/plist/generator.rb +0 -224
  474. data/lib/puppet/vendor/plist/lib/plist/parser.rb +0 -225
  475. data/lib/puppet/vendor/plist/test/assets/AlbumData.xml +0 -203
  476. data/lib/puppet/vendor/plist/test/assets/Cookies.plist +0 -104
  477. data/lib/puppet/vendor/plist/test/assets/commented.plist +0 -9
  478. data/lib/puppet/vendor/plist/test/assets/example_data.bin +0 -0
  479. data/lib/puppet/vendor/plist/test/assets/example_data.jpg +0 -0
  480. data/lib/puppet/vendor/plist/test/assets/example_data.plist +0 -259
  481. data/lib/puppet/vendor/plist/test/assets/test_data_elements.plist +0 -24
  482. data/lib/puppet/vendor/plist/test/assets/test_empty_key.plist +0 -13
  483. data/lib/puppet/vendor/plist/test/test_data_elements.rb +0 -115
  484. data/lib/puppet/vendor/plist/test/test_generator.rb +0 -59
  485. data/lib/puppet/vendor/plist/test/test_generator_basic_types.rb +0 -58
  486. data/lib/puppet/vendor/plist/test/test_generator_collections.rb +0 -82
  487. data/lib/puppet/vendor/plist/test/test_parser.rb +0 -90
@@ -16,6 +16,6 @@ Puppet::Parser::Functions::newfunction(:fqdn_rand, :arity => -2, :type => :rvalu
16
16
  node. (For example, `fqdn_rand(30)`, `fqdn_rand(30, 'expensive job 1')`, and
17
17
  `fqdn_rand(30, 'expensive job 2')` will produce totally different numbers.)") do |args|
18
18
  max = args.shift.to_i
19
- seed = Digest::MD5.hexdigest([self['::fqdn'],args].join(':')).hex
19
+ seed = Digest::MD5.hexdigest([self['::fqdn'],max,args].join(':')).hex
20
20
  Puppet::Util.deterministic_rand_int(seed,max)
21
21
  end
@@ -1,6 +1,6 @@
1
1
  Puppet::Parser::Functions::newfunction(:inline_template, :type => :rvalue, :arity => -2, :doc =>
2
2
  "Evaluate a template string and return its value. See
3
- [the templating docs](http://docs.puppetlabs.com/puppet/latest/reference/lang_template.html) for
3
+ [the templating docs](https://docs.puppetlabs.com/puppet/latest/reference/lang_template.html) for
4
4
  more information. Note that if multiple template strings are specified, their
5
5
  output is all concatenated and returned as the output of the function.") do |vals|
6
6
 
@@ -3,7 +3,7 @@ Puppet::Parser::Functions::newfunction(
3
3
  :type => :rvalue,
4
4
  :arity => -3,
5
5
  :doc => <<-DOC
6
- Applies a [lambda](http://docs.puppetlabs.com/puppet/latest/reference/lang_lambdas.html)
6
+ Applies a [lambda](https://docs.puppetlabs.com/puppet/latest/reference/lang_lambdas.html)
7
7
  to every value in a data structure and returns an array containing the results.
8
8
 
9
9
  This function takes two mandatory arguments, in this order:
@@ -5,37 +5,26 @@ Puppet::Parser::Functions::newfunction(
5
5
  :type => :rvalue,
6
6
  :arity => 2,
7
7
  :doc => <<-DOC
8
- Scans a string and returns an array of one or more converted values as directed by a given format string.args
9
- See the documenation of Ruby's String::scanf method for details about the supported formats (which
10
- are similar but not identical to the formats used in Puppet's `sprintf` function.
8
+ Scans a string and returns an array of one or more converted values based on the given format string.
9
+ See the documenation of Ruby's String#scanf method for details about the supported formats (which
10
+ are similar but not identical to the formats used in Puppet's `sprintf` function.)
11
11
 
12
- This function takes two mandatory arguments: the first is the String to
13
- convert, and the second the format String. The result of the scan is an Array,
14
- with each sucessfully scanned and transformed value.args The scanning stops if
15
- a scan is unsuccesful and the scanned result up to that point is returned. If
16
- there was no succesful scan at all, the result is an empty Array.
12
+ This function takes two mandatory arguments: the first is the string to convert, and the second is
13
+ the format string. The result of the scan is an array, with each sucessfully scanned and transformed value.
14
+ The scanning stops if a scan is unsuccesful, and the scanned result up to that point is returned. If there
15
+ was no succesful scan, the result is an empty array.
17
16
 
18
- scanf("42", "%i")[0] == 42
17
+ "42".scanf("%i")
19
18
 
19
+ You can also optionally pass a lambda to scanf, to do additional validation or processing.
20
20
 
21
- When used with the future parser, an optional parameterized block may be given.
22
- The block is called with the result that is produced by scanf if no block is
23
- present, the result of the block is then returned by the function.
24
-
25
- The optional code block is typically used to assert that the scan was
26
- succesful, and either produce the same input, or perform unwrapping of
27
- the result:
28
-
29
- "42".scanf("%i")
30
- "42".scanf("%i") |$x| {
31
- unless $x[0] =~ Integer {
32
- fail "Expected a well formed integer value, got '$x[0]'"
33
- }
34
- $x[0]
21
+ "42".scanf("%i") |$x| {
22
+ unless $x[0] =~ Integer {
23
+ fail "Expected a well formed integer value, got '$x[0]'"
35
24
  }
36
-
37
- - since 3.7.4 with `parser = future`
38
- - since 3.7.5 with classic parser
25
+ $x[0]
26
+ }
27
+ - since 4.0.0
39
28
  DOC
40
29
  ) do |args|
41
30
  data = args[0]
@@ -3,42 +3,35 @@ Puppet::Parser::Functions::newfunction(
3
3
  :type => :rvalue,
4
4
  :arity => -3,
5
5
  :doc => <<-DOC
6
- Applies a parameterized block to each _slice_ of elements in a sequence of selected entries from the first
7
- argument and returns the first argument, or if no block is given returns a new array with a concatenation of
8
- the slices.
6
+ This function takes two mandatory arguments: the first should be an array or hash, and the second specifies
7
+ the number of elements to include in each slice.
9
8
 
10
- This function takes two mandatory arguments: the first, `$a`, should be an Array, Hash, or something of
11
- enumerable type (integer, Integer range, or String), and the second, `$n`, the number of elements to include
12
- in each slice. The optional third argument should be a a parameterized block as produced by the puppet syntax:
13
-
14
- $a.slice($n) |$x| { ... }
15
- slice($a) |$x| { ... }
16
-
17
- The parameterized block should have either one parameter (receiving an array with the slice), or the same number
18
- of parameters as specified by the slice size (each parameter receiving its part of the slice).
19
- In case there are fewer remaining elements than the slice size for the last slice it will contain the remaining
20
- elements. When the block has multiple parameters, excess parameters are set to undef for an array or
21
- enumerable type, and to empty arrays for a Hash.
22
-
23
- $a.slice(2) |$first, $second| { ... }
24
-
25
- When the first argument is a Hash, each `key,value` entry is counted as one, e.g, a slice size of 2 will produce
9
+ When the first argument is a hash, each key value pair is counted as one. For example, a slice size of 2 will produce
26
10
  an array of two arrays with key, and value.
27
11
 
28
- Example Using slice with Hash
29
-
30
12
  $a.slice(2) |$entry| { notice "first ${$entry[0]}, second ${$entry[1]}" }
31
13
  $a.slice(2) |$first, $second| { notice "first ${first}, second ${second}" }
32
14
 
33
- When called without a block, the function produces a concatenated result of the slices.
34
-
35
- Example Using slice without a block
15
+ The function produces a concatenated result of the slices.
36
16
 
37
17
  slice([1,2,3,4,5,6], 2) # produces [[1,2], [3,4], [5,6]]
38
18
  slice(Integer[1,6], 2) # produces [[1,2], [3,4], [5,6]]
39
19
  slice(4,2) # produces [[0,1], [2,3]]
40
20
  slice('hello',2) # produces [[h, e], [l, l], [o]]
41
21
 
22
+ You can also optionally pass a lambda to slice.
23
+
24
+ $a.slice($n) |$x| { ... }
25
+ slice($a) |$x| { ... }
26
+
27
+ The lambda should have either one parameter (receiving an array with the slice), or the same number
28
+ of parameters as specified by the slice size (each parameter receiving its part of the slice).
29
+ If there are fewer remaining elements than the slice size for the last slice, it will contain the remaining
30
+ elements. If the lambda has multiple parameters, excess parameters are set to undef for an array, or
31
+ to empty arrays for a hash.
32
+
33
+ $a.slice(2) |$first, $second| { ... }
34
+
42
35
  - Since 4.0.0
43
36
  DOC
44
37
  ) do |args|
@@ -12,7 +12,7 @@ Split a string variable into an array using the specified split regexp.
12
12
  $string = 'v1.v2:v3.v4'
13
13
  $array_var1 = split($string, ':')
14
14
  $array_var2 = split($string, '[.]')
15
- $array_var3 = split($string, '[.:]')
15
+ $array_var3 = split($string, Regexp['[.:]'])
16
16
 
17
17
  `$array_var1` now holds the result `['v1.v2', 'v3.v4']`,
18
18
  while `$array_var2` holds `['v1', 'v2:v3', 'v4']`, and
@@ -244,23 +244,25 @@ class Puppet::Parser::Resource < Puppet::Resource
244
244
  raise "Resource #{self} tries to consume #{cns} but no 'consumes' mapping exists for #{self.resource_type} and #{cns.type}" unless blueprint
245
245
 
246
246
  # setup scope that has, for each attr of cns, a binding to cns[attr]
247
- cns_scope = scope.find_global_scope.newscope(:source => self, :resource => self)
248
- cns.to_hash.each { |name, value| cns_scope[name.to_s] = value }
249
-
250
- # evaluate mappings in that scope
251
- resource_type.arguments.keys.each do |name|
252
- if expr = blueprint[:mappings][name]
253
- # Explicit mapping
254
- value = expr.safeevaluate(cns_scope)
255
- else
256
- value = cns[name]
257
- end
258
- unless value.nil?
259
- # @todo lutter 2015-07-01: this should be caught by the checker
260
- # much earlier. We consume several capres, at least two of which
261
- # want to map to the same parameter (PUP-5080)
262
- raise "Attempt to reassign attribute '#{name}' in '#{self}' caused by multiple consumed mappings to the same attribute" if map[name]
263
- map[name] = value
247
+ scope.with_global_scope do |global_scope|
248
+ cns_scope = global_scope.newscope(:source => self, :resource => self)
249
+ cns.to_hash.each { |name, value| cns_scope[name.to_s] = value }
250
+
251
+ # evaluate mappings in that scope
252
+ resource_type.arguments.keys.each do |name|
253
+ if expr = blueprint[:mappings][name]
254
+ # Explicit mapping
255
+ value = expr.safeevaluate(cns_scope)
256
+ else
257
+ value = cns[name]
258
+ end
259
+ unless value.nil?
260
+ # @todo lutter 2015-07-01: this should be caught by the checker
261
+ # much earlier. We consume several capres, at least two of which
262
+ # want to map to the same parameter (PUP-5080)
263
+ raise "Attempt to reassign attribute '#{name}' in '#{self}' caused by multiple consumed mappings to the same attribute" if map[name]
264
+ map[name] = value
265
+ end
264
266
  end
265
267
  end
266
268
  end
@@ -174,13 +174,104 @@ class Puppet::Parser::Scope
174
174
 
175
175
  end
176
176
 
177
+ # @api private
178
+ class ParameterScope < Ephemeral
179
+ class Access
180
+ attr_accessor :value
181
+
182
+ def assigned?
183
+ instance_variable_defined?(:@value)
184
+ end
185
+ end
186
+
187
+ # A parameter default must be evaluated using a special scope. The scope that is given to this method must
188
+ # have a `ParameterScope` as its last ephemeral scope. This method will then push a `MatchScope` while the
189
+ # given `expression` is evaluated. The method will catch any throw of `:unevaluated_parameter` and produce
190
+ # an error saying that the evaluated parameter X tries to access the unevaluated parameter Y.
191
+ #
192
+ # @param name [String] the name of the currently evaluated parameter
193
+ # @param expression [Puppet::Parser::AST] the expression to evaluate
194
+ # @param scope [Puppet::Parser::Scope] a scope where a `ParameterScope` has been pushed
195
+ # @return [Object] the result of the evaluation
196
+ #
197
+ # @api private
198
+ def evaluate3x(name, expression, scope)
199
+ scope.with_guarded_scope do
200
+ bad = catch(:unevaluated_parameter) do
201
+ scope.new_match_scope(nil)
202
+ return as_read_only { expression.safeevaluate(scope) }
203
+ end
204
+ raise Puppet::Error, "default expression for $#{name} tries to illegally access not yet evaluated $#{bad}"
205
+ end
206
+ end
207
+
208
+ def evaluate(name, expression, scope, evaluator)
209
+ scope.with_guarded_scope do
210
+ bad = catch(:unevaluated_parameter) do
211
+ scope.new_match_scope(nil)
212
+ return as_read_only { evaluator.evaluate(expression, scope) }
213
+ end
214
+ raise Puppet::Error, "default expression for $#{name} tries to illegally access not yet evaluated $#{bad}"
215
+ end
216
+ end
217
+
218
+ def initialize(parent, param_names)
219
+ super(parent)
220
+ @params = {}
221
+ param_names.each { |name| @params[name] = Access.new }
222
+ end
223
+
224
+ def [](name)
225
+ access = @params[name]
226
+ return super if access.nil?
227
+ throw(:unevaluated_parameter, name) unless access.assigned?
228
+ access.value
229
+ end
230
+
231
+ def []=(name, value)
232
+ raise Puppet::Error, "Attempt to assign variable #{name} when evaluating parameters" if @read_only
233
+ @params[name] ||= Access.new
234
+ @params[name].value = value
235
+ end
236
+
237
+ def bound?(name)
238
+ @params.include?(name)
239
+ end
240
+
241
+ def include?(name)
242
+ @params.include?(name) || super
243
+ end
244
+
245
+ def is_local_scope?
246
+ true
247
+ end
248
+
249
+ def as_read_only
250
+ read_only = @read_only
251
+ @read_only = true
252
+ begin
253
+ yield
254
+ ensure
255
+ @read_only = read_only
256
+ end
257
+ end
258
+
259
+ def to_hash
260
+ Hash[@params.select {|_, access| access.assigned? }.map { |name, access| [name, access.value] }]
261
+ end
262
+ end
263
+
264
+
177
265
  # Returns true if the variable of the given name has a non nil value.
178
266
  # TODO: This has vague semantics - does the variable exist or not?
179
267
  # use ['name'] to get nil or value, and if nil check with exist?('name')
180
268
  # this include? is only useful because of checking against the boolean value false.
181
269
  #
182
270
  def include?(name)
183
- ! self[name].nil?
271
+ catch(:undefined_variable) {
272
+ return ! self[name].nil?
273
+ }
274
+ false
184
275
  end
185
276
 
186
277
  # Returns true if the variable of the given name is set to any value (including nil)
@@ -412,14 +503,28 @@ class Puppet::Parser::Scope
412
503
  end
413
504
  end
414
505
 
506
+ UNDEFINED_VARIABLES_KIND = 'undefined_variables'.freeze
507
+
415
508
  def variable_not_found(name, reason=nil)
416
509
  # Built in variables always exist
417
510
  if BUILT_IN_VARS.include?(name)
418
511
  return nil
419
512
  end
420
513
  if Puppet[:strict_variables]
421
- throw :undefined_variable
514
+ throw(:undefined_variable, reason)
422
515
  else
516
+ # Always warn, unfortunately without location (unless given in "reason") since
517
+ # a location is in most cases not given to scope (operator [], and lookupvar), and
518
+ # would be too expensive to always give.
519
+ # The ideal solution would be to always throw :undefined_variable, but that has to
520
+ # wait until a major release. It would then force all callers of scope to deal with
521
+ # the case of :undefined_variable. (Should check with include? first or catch the throw).
522
+ # Use deprecation warning to enable turning off these warnings, and to ensure each variable
523
+ # is only logged once.
524
+ unless name =~ Puppet::Pops::Patterns::NUMERIC_VAR_NAME
525
+ Puppet.warn_once(UNDEFINED_VARIABLES_KIND, "Variable: #{name}",
526
+ "Undefined variable '#{name}'; #{reason}" )
527
+ end
423
528
  nil
424
529
  end
425
530
  end
@@ -511,7 +616,8 @@ class Puppet::Parser::Scope
511
616
  else
512
617
  ""
513
618
  end
514
- warning "Could not look up qualified variable '#{class_name}::#{variable_name}'; #{reason}#{location}"
619
+ variable_not_found("#{class_name}::#{variable_name}", "#{reason}#{location}")
620
+ return nil
515
621
  end
516
622
  variable_not_found("#{class_name}::#{variable_name}", reason)
517
623
  end
@@ -738,10 +844,12 @@ class Puppet::Parser::Scope
738
844
 
739
845
  alias_method :inspect, :to_s
740
846
 
741
- # remove ephemeral scope up to level
742
- # TODO: Who uses :all ? Remove ??
847
+ # Pop ephemeral scopes up to level and return them
743
848
  #
849
+ # @deprecated use #pop_epehemeral
850
+ # @api private
744
851
  def unset_ephemeral_var(level=:all)
852
+ Puppet.deprecation_warning('Method Parser::Scope#unset_ephemeral_var() is deprecated')
745
853
  if level == :all
746
854
  @ephemeral = [ MatchScope.new(@symtable, nil)]
747
855
  else
@@ -749,6 +857,22 @@ class Puppet::Parser::Scope
749
857
  end
750
858
  end
751
859
 
860
+ # Pop ephemeral scopes up to level and return them
861
+ #
862
+ # @param level [Fixnum] a positive integer
863
+ # @return [Array] the removed ephemeral scopes
864
+ # @api private
865
+ def pop_ephemerals(level)
866
+ @ephemeral.pop(@ephemeral.size - level)
867
+ end
868
+
869
+ # Push ephemeral scopes onto the ephemeral scope stack
870
+ # @param ephemeral_scopes [Array]
871
+ # @api private
872
+ def push_ephemerals(ephemeral_scopes)
873
+ ephemeral_scopes.each { |ephemeral_scope| @ephemeral.push(ephemeral_scope) } unless ephemeral_scopes.nil?
874
+ end
875
+
752
876
  def ephemeral_level
753
877
  @ephemeral.size
754
878
  end
@@ -762,6 +886,53 @@ class Puppet::Parser::Scope
762
886
  end
763
887
  end
764
888
 
889
+ # Execute given block in global scope with no ephemerals present
890
+ #
891
+ # @yieldparam [Scope] global_scope the global and ephemeral less scope
892
+ # @return [Object] the return of the block
893
+ #
894
+ # @api private
895
+ def with_global_scope(&block)
896
+ find_global_scope.without_ephemeral_scopes(&block)
897
+ end
898
+
899
+ # Execute given block with all ephemeral popped from the ephemeral stack
900
+ #
901
+ # @api private
902
+ def without_ephemeral_scopes
903
+ save_ephemeral = @ephemeral
904
+ begin
905
+ @ephemeral = [ @symtable ]
906
+ yield(self)
907
+ ensure
908
+ @ephemeral = save_ephemeral
909
+ end
910
+ end
911
+
912
+ # Nests a parameter scope
913
+ # @api private
914
+ def with_parameter_scope(param_names)
915
+ param_scope = ParameterScope.new(@ephemeral.last, param_names)
916
+ with_guarded_scope do
917
+ @ephemeral.push(param_scope)
918
+ yield(param_scope)
919
+ end
920
+ end
921
+
922
+ # Execute given block and ensure that ephemeral level is restored
923
+ #
924
+ # @return [Object] the return of the block
925
+ #
926
+ # @api private
927
+ def with_guarded_scope
928
+ elevel = ephemeral_level
929
+ begin
930
+ yield
931
+ ensure
932
+ pop_ephemerals(elevel)
933
+ end
934
+ end
935
+
765
936
  # Sets match data in the most nested scope (which always is a MatchScope), it clobbers match data already set there
766
937
  #
767
938
  def set_match_data(match_data)
@@ -72,7 +72,6 @@ module Puppet::Plugins::DataProviders
72
72
  def data_key(key, lookup_invocation)
73
73
  nil
74
74
  end
75
- protected :data_key
76
75
 
77
76
  # Should be reimplemented by subclass to provide the hash that corresponds to the given name.
78
77
  #
@@ -94,7 +93,6 @@ module Puppet::Plugins::DataProviders
94
93
  def validate_data(data, data_key)
95
94
  data
96
95
  end
97
- protected :validate_data
98
96
  end
99
97
 
100
98
  class ModuleDataProvider
@@ -112,22 +110,29 @@ module Puppet::Plugins::DataProviders
112
110
  throw :no_such_key if qual_index.nil?
113
111
  key[0..qual_index-1]
114
112
  end
115
- protected :data_key
116
113
 
117
- # Assert that all keys in the given _data_ are prefixed with the given _module_name_.
114
+ # Asserts that all keys in the given _data_ are prefixed with the given _module_name_. Remove entries
115
+ # that does not follow the convention and log a warning.
118
116
  #
119
117
  # @param data [Hash] The data hash
120
118
  # @param module_name [String] The name of the module where the data was found
121
- # @return [Hash] The data_hash unaltered
119
+ # @return [Hash] The possibly pruned hash
120
+ # @api public
122
121
  def validate_data(data, module_name)
123
122
  module_prefix = "#{module_name}::"
124
- data.each_key do |k|
125
- unless k.is_a?(String) && (k == LOOKUP_OPTIONS || k.start_with?(module_prefix))
126
- raise Puppet::DataBinding::LookupError, "Module data for module '#{module_name}' must use keys qualified with the name of the module"
123
+ data.each_key.reduce(data) do |memo, k|
124
+ if k.is_a?(String)
125
+ next memo if k == LOOKUP_OPTIONS || k.start_with?(module_prefix)
126
+ msg = 'must use keys qualified with the name of the module'
127
+ else
128
+ msg = "must use keys of type String, got #{k.class.name}"
127
129
  end
130
+ memo = memo.clone if memo.equal?(data)
131
+ memo.delete(k)
132
+ Puppet.warning("Module data for module '#{module_name}' #{msg}")
133
+ memo
128
134
  end
129
135
  end
130
- protected :validate_data
131
136
  end
132
137
 
133
138
  class EnvironmentDataProvider
@@ -136,7 +141,6 @@ module Puppet::Plugins::DataProviders
136
141
  def data_key(key, lookup_invocation)
137
142
  'environment'
138
143
  end
139
- protected :data_key
140
144
  end
141
145
 
142
146
  # Class that keeps track of the original path (as it appears in the declaration, before interpolation),
@@ -176,11 +180,38 @@ module Puppet::Plugins::DataProviders
176
180
 
177
181
  # @param name [String] The name of the data provider
178
182
  # @param paths [Array<ResolvedPath>] Paths used by this provider
183
+ # @param parent_data_provider [DataProvider] The data provider that is the container of this data provider
179
184
  #
180
185
  # @api public
181
- def initialize(name, paths)
186
+ def initialize(name, paths, parent_data_provider = nil)
182
187
  @name = name
183
188
  @paths = paths
189
+ @parent_data_provider = parent_data_provider
190
+ end
191
+
192
+ # Gets the data from the compiler, or initializes it by calling #initialize_data if not present in the compiler.
193
+ # This means, that data is initialized once per compilation, and the data is cached for as long as the compiler
194
+ # lives (which is for one catalog production). This makes it possible to return data that is tailored for the
195
+ # request.
196
+ #
197
+ # If data is obtained using the #initialize_data method it will be sent to the #validate_data for validation
198
+ #
199
+ # @param path [String] The path to the data to be loaded (passed to #initialize_data)
200
+ # @param data_key [String] The data key such as the name of a module or the constant 'environment'
201
+ # @param lookup_invocation [Puppet::Pops::Lookup::Invocation] The current lookup invocation
202
+ # @param merge [String|Hash<String,Object>|nil] Merge strategy or hash with strategy and options
203
+ # @return [Hash] The data hash for the given _key_
204
+ #
205
+ # @api public
206
+ def load_data(path, data_key, lookup_invocation)
207
+ compiler = lookup_invocation.scope.compiler
208
+ adapter = Puppet::DataProviders::DataAdapter.get(compiler) || Puppet::DataProviders::DataAdapter.adapt(compiler)
209
+ adapter.data[path] ||= validate_data(initialize_data(path, lookup_invocation), data_key)
210
+ end
211
+ protected :data
212
+
213
+ def validate_data(data, module_name)
214
+ @parent_data_provider.nil? ? data : @parent_data_provider.validate_data(data, module_name)
184
215
  end
185
216
 
186
217
  # Performs a lookup by searching all given paths for the given _key_. A merge will be performed if
@@ -192,13 +223,14 @@ module Puppet::Plugins::DataProviders
192
223
  #
193
224
  # @api public
194
225
  def unchecked_lookup(key, lookup_invocation, merge)
226
+ module_name = @parent_data_provider.nil? ? nil : @parent_data_provider.data_key(key, lookup_invocation)
195
227
  lookup_invocation.with(:data_provider, self) do
196
228
  merge_strategy = Puppet::Pops::MergeStrategy.strategy(merge)
197
229
  lookup_invocation.with(:merge, merge_strategy) do
198
230
  merged_result = merge_strategy.merge_lookup(@paths) do |path|
199
231
  lookup_invocation.with(:path, path) do
200
232
  if path.exists?
201
- hash = data(path.path, lookup_invocation)
233
+ hash = load_data(path.path, module_name, lookup_invocation)
202
234
  value = hash[key]
203
235
  if value || hash.include?(key)
204
236
  lookup_invocation.report_found(key, post_process(value, lookup_invocation))
@@ -227,10 +259,11 @@ module Puppet::Plugins::DataProviders
227
259
  #
228
260
  # @param name [String] the name of the created provider (for logging and debugging)
229
261
  # @param paths [Array<String>] array of resolved paths
262
+ # @param parent_data_provider [DataProvider] The data provider that is the container of this data provider
230
263
  # @return [DataProvider] The created data provider
231
264
  #
232
265
  # @api public
233
- def create(name, paths)
266
+ def create(name, paths, parent_data_provider)
234
267
  raise NotImplementedError, "Subclass of PathBasedDataProviderFactory must implement 'create' method"
235
268
  end
236
269
 
@@ -250,6 +283,14 @@ module Puppet::Plugins::DataProviders
250
283
  def resolve_paths(datadir, declared_paths, paths, lookup_invocation)
251
284
  []
252
285
  end
286
+
287
+ # Returns the data provider factory version.
288
+ #
289
+ # return [Integer] the version of this data provider factory
290
+ # @api public
291
+ def version
292
+ 2
293
+ end
253
294
  end
254
295
 
255
296
  # Factory for creating file based data providers. This is an extension of the path based