puppet 4.2.3-x64-mingw32 → 4.3.0-x64-mingw32

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 (337) hide show
  1. data/Gemfile +3 -0
  2. data/README.md +1 -1
  3. data/ext/debian/puppet.init +0 -1
  4. data/ext/debian/puppet.logrotate +14 -5
  5. data/ext/osx/puppet.plist +0 -2
  6. data/ext/redhat/client.init +13 -5
  7. data/ext/redhat/logrotate +15 -3
  8. data/ext/redhat/puppet.spec.erb +5 -1
  9. data/ext/redhat/server.init +1 -1
  10. data/ext/systemd/puppet.service +1 -0
  11. data/lib/puppet.rb +12 -0
  12. data/lib/puppet/agent.rb +4 -4
  13. data/lib/puppet/agent/locker.rb +11 -2
  14. data/lib/puppet/application/agent.rb +5 -1
  15. data/lib/puppet/application/apply.rb +4 -0
  16. data/lib/puppet/application/filebucket.rb +78 -4
  17. data/lib/puppet/application/lookup.rb +356 -0
  18. data/lib/puppet/application/master.rb +3 -0
  19. data/lib/puppet/configurer.rb +9 -5
  20. data/lib/puppet/context.rb +16 -1
  21. data/lib/puppet/context/trusted_information.rb +21 -1
  22. data/lib/puppet/daemon.rb +17 -13
  23. data/lib/puppet/data_binding.rb +4 -2
  24. data/lib/puppet/data_providers.rb +12 -13
  25. data/lib/puppet/data_providers/data_adapter.rb +7 -68
  26. data/lib/puppet/data_providers/data_function_support.rb +5 -26
  27. data/lib/puppet/data_providers/function_env_data_provider.rb +0 -10
  28. data/lib/puppet/data_providers/function_module_data_provider.rb +0 -22
  29. data/lib/puppet/data_providers/hiera_config.rb +106 -0
  30. data/lib/puppet/data_providers/hiera_env_data_provider.rb +18 -0
  31. data/lib/puppet/data_providers/hiera_interpolate.rb +97 -0
  32. data/lib/puppet/data_providers/hiera_module_data_provider.rb +23 -0
  33. data/lib/puppet/data_providers/hiera_support.rb +37 -0
  34. data/lib/puppet/data_providers/json_data_provider_factory.rb +31 -0
  35. data/lib/puppet/data_providers/lookup_adapter.rb +200 -0
  36. data/lib/puppet/data_providers/yaml_data_provider_factory.rb +32 -0
  37. data/lib/puppet/defaults.rb +12 -2
  38. data/lib/puppet/error.rb +4 -0
  39. data/lib/puppet/face/module/changes.rb +2 -1
  40. data/lib/puppet/feature/cfacter.rb +1 -0
  41. data/lib/puppet/file_bucket/dipper.rb +58 -2
  42. data/lib/puppet/functions.rb +2 -4
  43. data/lib/puppet/functions/assert_type.rb +48 -12
  44. data/lib/puppet/functions/defined.rb +79 -48
  45. data/lib/puppet/functions/each.rb +85 -27
  46. data/lib/puppet/functions/filter.rb +58 -23
  47. data/lib/puppet/functions/hiera.rb +76 -3
  48. data/lib/puppet/functions/hiera_array.rb +65 -3
  49. data/lib/puppet/functions/hiera_hash.rb +74 -2
  50. data/lib/puppet/functions/hiera_include.rb +75 -2
  51. data/lib/puppet/functions/lookup.rb +19 -17
  52. data/lib/puppet/functions/map.rb +56 -21
  53. data/lib/puppet/functions/match.rb +29 -12
  54. data/lib/puppet/functions/reduce.rb +95 -58
  55. data/lib/puppet/functions/versioncmp.rb +36 -0
  56. data/lib/puppet/functions/with.rb +15 -7
  57. data/lib/puppet/indirector/catalog/compiler.rb +3 -3
  58. data/lib/puppet/indirector/catalog/static_compiler.rb +46 -30
  59. data/lib/puppet/indirector/data_binding/none.rb +4 -1
  60. data/lib/puppet/indirector/file_bucket_file/file.rb +58 -1
  61. data/lib/puppet/indirector/hiera.rb +4 -0
  62. data/lib/puppet/indirector/json.rb +1 -1
  63. data/lib/puppet/indirector/msgpack.rb +1 -1
  64. data/lib/puppet/indirector/request.rb +7 -8
  65. data/lib/puppet/indirector/resource_type/parser.rb +5 -3
  66. data/lib/puppet/info_service.rb +7 -0
  67. data/lib/puppet/info_service/class_information_service.rb +111 -0
  68. data/lib/puppet/module_tool/metadata.rb +32 -9
  69. data/lib/puppet/module_tool/skeleton/templates/generator/README.md.erb +42 -38
  70. data/lib/puppet/network/authconfig.rb +21 -1
  71. data/lib/puppet/network/authorization.rb +8 -1
  72. data/lib/puppet/network/http/api/master/v3.rb +7 -1
  73. data/lib/puppet/network/http/api/master/v3/environment.rb +59 -0
  74. data/lib/puppet/node/environment.rb +9 -2
  75. data/lib/puppet/parser.rb +3 -0
  76. data/lib/puppet/parser/ast/pops_bridge.rb +39 -1
  77. data/lib/puppet/parser/compiler.rb +302 -12
  78. data/lib/puppet/parser/compiler/catalog_validator.rb +33 -0
  79. data/lib/puppet/parser/compiler/catalog_validator/env_relationship_validator.rb +64 -0
  80. data/lib/puppet/parser/compiler/catalog_validator/relationship_validator.rb +38 -0
  81. data/lib/puppet/parser/compiler/catalog_validator/site_validator.rb +20 -0
  82. data/lib/puppet/parser/environment_compiler.rb +165 -0
  83. data/lib/puppet/parser/functions/assert_type.rb +46 -16
  84. data/lib/puppet/parser/functions/defined.rb +105 -68
  85. data/lib/puppet/parser/functions/each.rb +85 -27
  86. data/lib/puppet/parser/functions/filter.rb +59 -23
  87. data/lib/puppet/parser/functions/hiera.rb +83 -27
  88. data/lib/puppet/parser/functions/hiera_array.rb +71 -28
  89. data/lib/puppet/parser/functions/hiera_hash.rb +81 -30
  90. data/lib/puppet/parser/functions/hiera_include.rb +81 -40
  91. data/lib/puppet/parser/functions/map.rb +55 -20
  92. data/lib/puppet/parser/functions/match.rb +27 -12
  93. data/lib/puppet/parser/functions/reduce.rb +97 -60
  94. data/lib/puppet/parser/functions/with.rb +16 -8
  95. data/lib/puppet/parser/resource.rb +98 -19
  96. data/lib/puppet/plugins/configuration.rb +3 -2
  97. data/lib/puppet/plugins/data_providers.rb +12 -60
  98. data/lib/puppet/plugins/data_providers/data_provider.rb +283 -0
  99. data/lib/puppet/plugins/data_providers/registry.rb +84 -0
  100. data/lib/puppet/pops.rb +19 -17
  101. data/lib/puppet/pops/adapters.rb +12 -0
  102. data/lib/puppet/pops/binder/binder.rb +2 -2
  103. data/lib/puppet/pops/binder/bindings_checker.rb +1 -1
  104. data/lib/puppet/pops/binder/bindings_label_provider.rb +3 -1
  105. data/lib/puppet/pops/binder/bindings_loader.rb +6 -2
  106. data/lib/puppet/pops/binder/bindings_model_meta.rb +2 -2
  107. data/lib/puppet/pops/binder/config/binder_config.rb +1 -1
  108. data/lib/puppet/pops/binder/injector.rb +4 -4
  109. data/lib/puppet/pops/binder/key_factory.rb +3 -9
  110. data/lib/puppet/pops/binder/scheme_handler/module_scheme.rb +68 -9
  111. data/lib/puppet/pops/evaluator/access_operator.rb +27 -60
  112. data/lib/puppet/pops/evaluator/closure.rb +8 -8
  113. data/lib/puppet/pops/evaluator/collectors/abstract_collector.rb +1 -1
  114. data/lib/puppet/pops/evaluator/evaluator_impl.rb +5 -5
  115. data/lib/puppet/pops/evaluator/literal_evaluator.rb +87 -0
  116. data/lib/puppet/pops/evaluator/relationship_operator.rb +7 -1
  117. data/lib/puppet/pops/functions/dispatcher.rb +3 -3
  118. data/lib/puppet/pops/issues.rb +1 -1
  119. data/lib/puppet/pops/label_provider.rb +1 -1
  120. data/lib/puppet/pops/lookup.rb +25 -47
  121. data/lib/puppet/pops/lookup/explainer.rb +402 -0
  122. data/lib/puppet/pops/lookup/invocation.rb +117 -0
  123. data/lib/puppet/pops/merge_strategy.rb +73 -5
  124. data/lib/puppet/pops/model/factory.rb +34 -0
  125. data/lib/puppet/pops/model/model_label_provider.rb +10 -1
  126. data/lib/puppet/pops/model/model_meta.rb +15 -0
  127. data/lib/puppet/pops/model/model_tree_dumper.rb +18 -0
  128. data/lib/puppet/pops/parser/code_merger.rb +13 -1
  129. data/lib/puppet/pops/parser/egrammar.ra +56 -3
  130. data/lib/puppet/pops/parser/eparser.rb +1549 -1352
  131. data/lib/puppet/pops/parser/lexer2.rb +31 -6
  132. data/lib/puppet/pops/parser/locator.rb +1 -1
  133. data/lib/puppet/pops/parser/parser_support.rb +25 -13
  134. data/lib/puppet/pops/types/enumeration.rb +1 -2
  135. data/lib/puppet/pops/types/type_asserter.rb +16 -15
  136. data/lib/puppet/pops/types/type_assertion_error.rb +1 -0
  137. data/lib/puppet/pops/types/type_calculator.rb +171 -1020
  138. data/lib/puppet/pops/types/type_factory.rb +87 -148
  139. data/lib/puppet/pops/types/type_mismatch_describer.rb +743 -0
  140. data/lib/puppet/pops/types/type_parser.rb +116 -127
  141. data/lib/puppet/pops/types/types.rb +1394 -255
  142. data/lib/puppet/pops/types/types_meta.rb +0 -234
  143. data/lib/puppet/pops/validation.rb +7 -2
  144. data/lib/puppet/pops/validation/checker4_0.rb +28 -0
  145. data/lib/puppet/provider/augeas/augeas.rb +50 -0
  146. data/lib/puppet/provider/group/directoryservice.rb +10 -0
  147. data/lib/puppet/provider/package/dnf.rb +41 -0
  148. data/lib/puppet/provider/package/gem.rb +7 -2
  149. data/lib/puppet/provider/package/rpm.rb +1 -0
  150. data/lib/puppet/provider/package/windows/exe_package.rb +10 -8
  151. data/lib/puppet/provider/package/windows/msi_package.rb +4 -3
  152. data/lib/puppet/provider/package/windows/package.rb +9 -1
  153. data/lib/puppet/provider/package/yum.rb +14 -9
  154. data/lib/puppet/provider/service/bsd.rb +1 -1
  155. data/lib/puppet/provider/service/debian.rb +21 -0
  156. data/lib/puppet/provider/service/init.rb +6 -0
  157. data/lib/puppet/provider/service/rcng.rb +51 -0
  158. data/lib/puppet/provider/service/redhat.rb +2 -1
  159. data/lib/puppet/provider/service/smf.rb +43 -2
  160. data/lib/puppet/provider/service/src.rb +27 -0
  161. data/lib/puppet/provider/service/systemd.rb +15 -3
  162. data/lib/puppet/provider/sshkey/parsed.rb +19 -9
  163. data/lib/puppet/reference/report.rb +9 -12
  164. data/lib/puppet/reports.rb +5 -1
  165. data/lib/puppet/resource.rb +50 -73
  166. data/lib/puppet/resource/capability_finder.rb +95 -0
  167. data/lib/puppet/resource/catalog.rb +47 -7
  168. data/lib/puppet/resource/status.rb +0 -2
  169. data/lib/puppet/resource/type.rb +238 -44
  170. data/lib/puppet/resource/type_collection.rb +60 -2
  171. data/lib/puppet/settings.rb +2 -2
  172. data/lib/puppet/ssl/certificate_authority/interface.rb +2 -2
  173. data/lib/puppet/ssl/oids.rb +9 -1
  174. data/lib/puppet/transaction.rb +4 -1
  175. data/lib/puppet/transaction/additional_resource_generator.rb +71 -8
  176. data/lib/puppet/transaction/resource_harness.rb +9 -4
  177. data/lib/puppet/type.rb +74 -3
  178. data/lib/puppet/type/augeas.rb +8 -0
  179. data/lib/puppet/type/file/source.rb +14 -12
  180. data/lib/puppet/type/user.rb +4 -2
  181. data/lib/puppet/util/windows/security.rb +4 -1
  182. data/lib/puppet/util/windows/taskscheduler.rb +1 -1
  183. data/lib/puppet/version.rb +1 -1
  184. data/spec/fixtures/unit/application/environments/production/data/common.yaml +3 -0
  185. data/spec/fixtures/unit/application/environments/production/environment.conf +1 -0
  186. data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_json/data/bad.json +3 -0
  187. data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_json/environment.conf +2 -0
  188. data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_json/hiera.yaml +5 -0
  189. data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_json/manifests/site.pp +5 -0
  190. data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_yaml/data/bad.yaml +3 -0
  191. data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_yaml/environment.conf +2 -0
  192. data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_yaml/hiera.yaml +5 -0
  193. data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_yaml/manifests/site.pp +5 -0
  194. data/spec/fixtures/unit/data_providers/environments/hiera_defaults/data/common.yaml +2 -0
  195. data/spec/fixtures/unit/data_providers/environments/hiera_defaults/environment.conf +2 -0
  196. data/spec/fixtures/unit/data_providers/environments/hiera_defaults/manifests/site.pp +1 -0
  197. data/spec/fixtures/unit/data_providers/environments/hiera_defaults/modules/one/data/common.yaml +2 -0
  198. data/spec/fixtures/unit/data_providers/environments/hiera_defaults/modules/one/manifests/init.pp +5 -0
  199. data/spec/fixtures/unit/data_providers/environments/hiera_defaults/modules/one/metadata.json +9 -0
  200. data/spec/fixtures/unit/data_providers/environments/hiera_env_config/data1/first.json +3 -0
  201. data/spec/fixtures/unit/data_providers/environments/hiera_env_config/data1/name.yaml +2 -0
  202. data/spec/fixtures/unit/data_providers/environments/hiera_env_config/data1/second.json +3 -0
  203. data/spec/fixtures/unit/data_providers/environments/hiera_env_config/data1/single.yaml +2 -0
  204. data/spec/fixtures/unit/data_providers/environments/hiera_env_config/data2/single.yaml +2 -0
  205. data/spec/fixtures/unit/data_providers/environments/hiera_env_config/environment.conf +2 -0
  206. data/spec/fixtures/unit/data_providers/environments/hiera_env_config/hiera.yaml +18 -0
  207. data/spec/fixtures/unit/data_providers/environments/hiera_env_config/manifests/site.pp +5 -0
  208. data/spec/fixtures/unit/data_providers/environments/hiera_misc/data/common.yaml +46 -0
  209. data/spec/fixtures/unit/data_providers/environments/hiera_misc/environment.conf +2 -0
  210. data/spec/fixtures/unit/data_providers/environments/hiera_misc/manifests/site.pp +1 -0
  211. data/spec/fixtures/unit/data_providers/environments/hiera_misc/modules/one/data/common.yaml +30 -0
  212. data/spec/fixtures/unit/data_providers/environments/hiera_misc/modules/one/manifests/init.pp +13 -0
  213. data/spec/fixtures/unit/data_providers/environments/hiera_misc/modules/one/metadata.json +9 -0
  214. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/environment.conf +2 -0
  215. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/manifests/site.pp +1 -0
  216. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/data1/first.json +3 -0
  217. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/data1/name.yaml +1 -0
  218. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/data1/second.json +3 -0
  219. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/data1/single.yaml +2 -0
  220. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/data2/single.yaml +2 -0
  221. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/hiera.yaml +18 -0
  222. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/manifests/init.pp +5 -0
  223. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/metadata.json +9 -0
  224. data/spec/fixtures/unit/data_providers/environments/sample/modules/dataprovider/lib/puppet_x/helindbe/sample_env_data.rb +1 -0
  225. data/spec/fixtures/unit/data_providers/environments/sample/modules/dataprovider/lib/puppet_x/helindbe/sample_module_data.rb +1 -0
  226. data/spec/fixtures/unit/functions/lookup/environments/production/modules/hieraprovider/data/first.json +3 -0
  227. data/spec/fixtures/unit/functions/lookup/environments/production/modules/hieraprovider/hiera.yaml +8 -0
  228. data/spec/fixtures/unit/functions/lookup/environments/production/modules/hieraprovider/manifests/init.pp +5 -0
  229. data/spec/fixtures/unit/functions/lookup/environments/production/modules/hieraprovider/metadata.json +9 -0
  230. data/spec/fixtures/unit/functions/lookup/environments/production/modules/meta/lib/puppet/functions/meta/data.rb +9 -0
  231. data/spec/fixtures/unit/functions/lookup/environments/production/modules/meta/manifests/init.pp +3 -0
  232. data/spec/fixtures/unit/functions/lookup/environments/production/modules/meta/metadata.json +9 -0
  233. data/spec/fixtures/unit/functions/lookup/environments/production/modules/metawcp/lib/puppet/bindings/metawcp/default.rb +10 -0
  234. data/spec/fixtures/unit/functions/lookup/environments/production/modules/metawcp/lib/puppet_x/thallgren/sample_module_data.rb +23 -0
  235. data/spec/fixtures/unit/functions/lookup/environments/production/modules/metawcp/manifests/init.pp +3 -0
  236. data/spec/fixtures/unit/functions/lookup/environments/production/modules/metawcp/metadata.json +9 -0
  237. data/spec/fixtures/unit/provider/package/yum/yum-check-update-security.txt +184 -0
  238. data/spec/fixtures/vcr/cassettes/Puppet_Network_HTTP_Connection/when_handling_requests/_request_get/should_yield_to_the_block.yml +24 -0
  239. data/spec/fixtures/vcr/cassettes/Puppet_Network_HTTP_Connection/when_handling_requests/_request_head/should_yield_to_the_block.yml +24 -0
  240. data/spec/fixtures/vcr/cassettes/Puppet_Network_HTTP_Connection/when_handling_requests/_request_post/should_yield_to_the_block.yml +24 -0
  241. data/spec/integration/data_binding_spec.rb +229 -0
  242. data/spec/integration/file_bucket/file_spec.rb +2 -2
  243. data/spec/integration/parser/compiler_spec.rb +23 -19
  244. data/spec/integration/parser/resource_expressions_spec.rb +4 -4
  245. data/spec/integration/parser/undef_param_spec.rb +1 -1
  246. data/spec/integration/resource/catalog_spec.rb +1 -1
  247. data/spec/integration/type/package_spec.rb +2 -0
  248. data/spec/integration/util/windows/security_spec.rb +18 -0
  249. data/spec/lib/matchers/include_in_order.rb +2 -2
  250. data/spec/shared_behaviours/iterative_functions.rb +8 -8
  251. data/spec/spec_helper.rb +7 -0
  252. data/spec/unit/agent/locker_spec.rb +4 -4
  253. data/spec/unit/agent_spec.rb +0 -8
  254. data/spec/unit/application/agent_spec.rb +5 -0
  255. data/spec/unit/application/apply_spec.rb +8 -0
  256. data/spec/unit/application/filebucket_spec.rb +87 -1
  257. data/spec/unit/application/lookup_spec.rb +195 -0
  258. data/spec/unit/appmgmt_spec.rb +657 -0
  259. data/spec/unit/capability_spec.rb +414 -0
  260. data/spec/unit/configurer_spec.rb +7 -1
  261. data/spec/unit/context/trusted_information_spec.rb +24 -1
  262. data/spec/unit/daemon_spec.rb +18 -8
  263. data/spec/unit/data_providers/hiera_data_provider_spec.rb +201 -0
  264. data/spec/unit/file_bucket/dipper_spec.rb +210 -1
  265. data/spec/unit/functions/assert_type_spec.rb +5 -7
  266. data/spec/unit/functions/defined_spec.rb +2 -2
  267. data/spec/unit/functions/epp_spec.rb +2 -2
  268. data/spec/unit/functions/lookup_spec.rb +200 -9
  269. data/spec/unit/functions/regsubst_spec.rb +17 -8
  270. data/spec/unit/functions/scanf_spec.rb +1 -1
  271. data/spec/unit/functions/split_spec.rb +2 -2
  272. data/spec/unit/functions/versioncmp_spec.rb +36 -0
  273. data/spec/unit/functions4_spec.rb +58 -72
  274. data/spec/unit/indirector/catalog/compiler_spec.rb +28 -8
  275. data/spec/unit/indirector/catalog/static_compiler_spec.rb +38 -20
  276. data/spec/unit/indirector/data_binding/none_spec.rb +2 -2
  277. data/spec/unit/indirector/file_bucket_file/file_spec.rb +52 -1
  278. data/spec/unit/indirector/request_spec.rb +8 -8
  279. data/spec/unit/info_service_spec.rb +236 -0
  280. data/spec/unit/module_tool/metadata_spec.rb +31 -2
  281. data/spec/unit/network/authconfig_spec.rb +62 -32
  282. data/spec/unit/network/authorization_spec.rb +30 -2
  283. data/spec/unit/network/http/connection_spec.rb +14 -19
  284. data/spec/unit/parser/compiler_spec.rb +86 -2
  285. data/spec/unit/parser/functions/create_resources_spec.rb +1 -1
  286. data/spec/unit/parser/resource_spec.rb +2 -20
  287. data/spec/unit/pops/binder/config/binder_config_spec.rb +1 -1
  288. data/spec/unit/pops/binder/injector_spec.rb +3 -3
  289. data/spec/unit/pops/evaluator/access_ops_spec.rb +13 -11
  290. data/spec/unit/pops/evaluator/basic_expressions_spec.rb +1 -2
  291. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +19 -11
  292. data/spec/unit/pops/evaluator/literal_evaluator_spec.rb +43 -0
  293. data/spec/unit/pops/label_provider_spec.rb +5 -1
  294. data/spec/unit/pops/parser/lexer2_spec.rb +33 -7
  295. data/spec/unit/pops/parser/parse_application_spec.rb +40 -0
  296. data/spec/unit/pops/parser/parse_basic_expressions_spec.rb +4 -0
  297. data/spec/unit/pops/parser/parse_capabilities_spec.rb +47 -0
  298. data/spec/unit/pops/parser/parse_site_spec.rb +38 -0
  299. data/spec/unit/pops/parser/parser_rspec_helper.rb +5 -0
  300. data/spec/unit/pops/parser/parser_spec.rb +18 -0
  301. data/spec/unit/pops/types/type_calculator_spec.rb +427 -444
  302. data/spec/unit/pops/types/type_factory_spec.rb +12 -12
  303. data/spec/unit/pops/types/type_parser_spec.rb +7 -12
  304. data/spec/unit/pops/validator/validator_spec.rb +25 -0
  305. data/spec/unit/provider/augeas/augeas_spec.rb +50 -0
  306. data/spec/unit/provider/group/directoryservice_spec.rb +33 -0
  307. data/spec/unit/provider/group/windows_adsi_spec.rb +3 -0
  308. data/spec/unit/provider/package/dnf_spec.rb +92 -0
  309. data/spec/unit/provider/package/gem_spec.rb +7 -0
  310. data/spec/unit/provider/package/rpm_spec.rb +25 -2
  311. data/spec/unit/provider/package/windows/package_spec.rb +41 -0
  312. data/spec/unit/provider/package/yum_spec.rb +21 -13
  313. data/spec/unit/provider/scheduled_task/win32_taskscheduler_spec.rb +10 -0
  314. data/spec/unit/provider/service/debian_spec.rb +27 -0
  315. data/spec/unit/provider/service/rcng_spec.rb +41 -0
  316. data/spec/unit/provider/service/redhat_spec.rb +8 -1
  317. data/spec/unit/provider/service/smf_spec.rb +30 -5
  318. data/spec/unit/provider/service/src_spec.rb +19 -4
  319. data/spec/unit/provider/service/systemd_spec.rb +78 -29
  320. data/spec/unit/provider/sshkey/parsed_spec.rb +23 -0
  321. data/spec/unit/reports_spec.rb +10 -0
  322. data/spec/unit/resource/capability_finder_spec.rb +56 -0
  323. data/spec/unit/resource/catalog_spec.rb +31 -8
  324. data/spec/unit/resource/type_collection_spec.rb +23 -2
  325. data/spec/unit/resource/type_spec.rb +1 -1
  326. data/spec/unit/resource_spec.rb +22 -4
  327. data/spec/unit/settings_spec.rb +90 -1
  328. data/spec/unit/ssl/certificate_authority/interface_spec.rb +4 -3
  329. data/spec/unit/ssl/oids_spec.rb +8 -0
  330. data/spec/unit/transaction/additional_resource_generator_spec.rb +78 -5
  331. data/spec/unit/transaction/report_spec.rb +24 -1
  332. data/spec/unit/type/package_spec.rb +1 -0
  333. data/spec/unit/type/user_spec.rb +14 -7
  334. data/spec/unit/type_spec.rb +1 -1
  335. metadata +169 -5
  336. data/lib/puppet/pops/evaluator/callable_mismatch_describer.rb +0 -175
  337. data/spec/integration/data_binding.rb +0 -104
@@ -3,17 +3,25 @@ Puppet::Parser::Functions::newfunction(
3
3
  :type => :rvalue,
4
4
  :arity => -1,
5
5
  :doc => <<-DOC
6
- Call a lambda code block with the given arguments. Since the parameters of the lambda
7
- are local to the lambda's scope, this can be used to create private sections
8
- of logic in a class so that the variables are not visible outside of the
9
- class.
6
+ Call a [lambda](https://docs.puppetlabs.com/puppet/latest/reference/lang_lambdas.html)
7
+ with the given arguments and return the result. Since a lambda's scope is
8
+ [local](https://docs.puppetlabs.com/puppet/latest/reference/lang_lambdas.html#lambda-scope)
9
+ to the lambda, you can use the `with` function to create private blocks of code within a
10
+ class using variables whose values cannot be accessed outside of the lambda.
10
11
 
11
- Example:
12
+ **Example**: Using `with`
12
13
 
13
- # notices the array [1, 2, 'foo']
14
- with(1, 2, 'foo') |$x, $y, $z| { notice [$x, $y, $z] }
14
+ ~~~ puppet
15
+ # Concatenate three strings into a single string formatted as a list.
16
+ $fruit = with("apples", "oranges", "bananas") |$x, $y, $z| {
17
+ "${x}, ${y}, and ${z}"
18
+ }
19
+ $check_var = $x
20
+ # $fruit contains "apples, oranges, and bananas"
21
+ # $check_var is undefined, as the value of $x is local to the lambda.
22
+ ~~~
15
23
 
16
- - since 4.0.0
24
+ - Since 4.0.0
17
25
  DOC
18
26
  ) do |args|
19
27
  function_fail(["with() is only available when parser/evaluator future is in effect"])
@@ -73,18 +73,15 @@ class Puppet::Parser::Resource < Puppet::Resource
73
73
  # Retrieve the associated definition and evaluate it.
74
74
  def evaluate
75
75
  return if evaluated?
76
-
77
76
  Puppet::Util::Profiler.profile("Evaluated resource #{self}", [:compiler, :evaluate_resource, self]) do
78
77
  @evaluated = true
79
- if klass = resource_type and ! builtin_type?
80
- finish
81
- evaluated_code = klass.evaluate_code(self)
82
-
83
- return evaluated_code
84
- elsif builtin?
78
+ if builtin?
85
79
  devfail "Cannot evaluate a builtin type (#{type})"
86
- else
80
+ elsif resource_type.nil?
87
81
  self.fail "Cannot find definition #{type}"
82
+ else
83
+ finish(false) # Call finish but do not validate
84
+ resource_type.evaluate_code(self)
88
85
  end
89
86
  end
90
87
  end
@@ -101,13 +98,18 @@ class Puppet::Parser::Resource < Puppet::Resource
101
98
  end
102
99
 
103
100
  # Do any finishing work on this object, called before evaluation or
104
- # before storage/translation.
105
- def finish
101
+ # before storage/translation. The method does nothing the second time
102
+ # it is called on the same resource.
103
+ #
104
+ # @param do_validate [Boolean] true if validation should be performed
105
+ #
106
+ # @api private
107
+ def finish(do_validate = true)
106
108
  return if finished?
107
109
  @finished = true
108
110
  add_defaults
109
111
  add_scope_tags
110
- validate
112
+ validate if do_validate
111
113
  end
112
114
 
113
115
  # Has this resource already been finished?
@@ -115,9 +117,9 @@ class Puppet::Parser::Resource < Puppet::Resource
115
117
  @finished
116
118
  end
117
119
 
118
- def initialize(*args)
119
- raise ArgumentError, "Resources require a hash as last argument" unless args.last.is_a? Hash
120
- raise ArgumentError, "Resources require a scope" unless args.last[:scope]
120
+ def initialize(type, title, attributes)
121
+ raise ArgumentError, 'Resources require a hash as last argument' unless attributes.is_a? Hash
122
+ raise ArgumentError, 'Resources require a scope' unless attributes[:scope]
121
123
  super
122
124
 
123
125
  @source ||= scope.source
@@ -132,6 +134,15 @@ class Puppet::Parser::Resource < Puppet::Resource
132
134
  end
133
135
  end
134
136
 
137
+ def is_unevaluated_consumer?
138
+ # We don't declare a new variable here just to test. Saves memory
139
+ instance_variable_defined?(:@unevaluated_consumer)
140
+ end
141
+
142
+ def mark_unevaluated_consumer
143
+ @unevaluated_consumer = true
144
+ end
145
+
135
146
  # Merge an override resource in. This will throw exceptions if
136
147
  # any overrides aren't allowed.
137
148
  def merge(resource)
@@ -202,6 +213,69 @@ class Puppet::Parser::Resource < Puppet::Resource
202
213
  super || ((scope_resource = scope.resource) && !scope_resource.equal?(self) && scope_resource.raw_tagged?(tag_array))
203
214
  end
204
215
 
216
+ # Fills resource params from a capability
217
+ #
218
+ # This backs 'consumes => Sql[one]'
219
+ # @api private
220
+ def add_parameters_from_consume
221
+ return if self[:consume].nil?
222
+
223
+ map = {}
224
+ [ self[:consume] ].flatten.map do |ref|
225
+ # Assert that the ref really is a resource reference
226
+ raise Puppet::Error, "Invalid consume in #{self.ref}: #{ref} is not a resource" unless ref.is_a?(Puppet::Resource)
227
+
228
+ # Resolve references
229
+ cap = catalog.resource(ref.type, ref.title)
230
+ if cap.nil?
231
+ raise "Resource #{ref} could not be found; it might not have been produced yet"
232
+ end
233
+
234
+ # Ensure that the found resource is a capability resource
235
+ raise Puppet::Error, "Invalid consume in #{ref}: #{cap} is not a capability resource" unless cap.resource_type.is_capability?
236
+ cap
237
+ end.each do |cns|
238
+ # Establish mappings
239
+ blueprint = resource_type.consumes.find do |bp|
240
+ bp[:capability] == cns.type
241
+ end
242
+ # @todo lutter 2015-08-03: catch this earlier, can we do this during
243
+ # static analysis ?
244
+ raise "Resource #{self} tries to consume #{cns} but no 'consumes' mapping exists for #{self.resource_type} and #{cns.type}" unless blueprint
245
+
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
264
+ end
265
+ end
266
+ end
267
+
268
+ map.each { |name, value| self[name] = value if self[name].nil? }
269
+ end
270
+
271
+ def offset
272
+ nil
273
+ end
274
+
275
+ def pos
276
+ nil
277
+ end
278
+
205
279
  private
206
280
 
207
281
  # Add default values from our definition.
@@ -216,7 +290,8 @@ class Puppet::Parser::Resource < Puppet::Resource
216
290
  end
217
291
 
218
292
  def add_scope_tags
219
- if scope_resource = scope.resource
293
+ scope_resource = scope.resource
294
+ unless scope_resource.nil? || scope_resource.equal?(self)
220
295
  merge_tags(scope_resource)
221
296
  end
222
297
  end
@@ -259,11 +334,15 @@ class Puppet::Parser::Resource < Puppet::Resource
259
334
 
260
335
  # Make sure the resource's parameters are all valid for the type.
261
336
  def validate
262
- @parameters.each do |name, param|
263
- validate_parameter(name)
337
+ if builtin_type?
338
+ begin
339
+ @parameters.each { |name, value| validate_parameter(name) }
340
+ rescue => detail
341
+ self.fail Puppet::ParseError, detail.to_s + " on #{self}", detail
342
+ end
343
+ else
344
+ resource_type.validate_resource(self)
264
345
  end
265
- rescue => detail
266
- self.fail Puppet::ParseError, detail.to_s + " on #{self}", detail
267
346
  end
268
347
 
269
348
  def extract_parameters(params)
@@ -11,6 +11,7 @@ module Puppet::Plugins::Configuration
11
11
  require 'puppet/plugins/binding_schemes'
12
12
  require 'puppet/plugins/syntax_checkers'
13
13
  require 'puppet/plugins/data_providers'
14
+ require 'puppet/plugins/data_providers/registry'
14
15
 
15
16
  # Extension-points are registered here:
16
17
  #
@@ -33,7 +34,7 @@ module Puppet::Plugins::Configuration
33
34
 
34
35
  extensions.multibind(checkers_name).name(checkers_name).hash_of(checkers_type)
35
36
  extensions.multibind(schemes_name).name(schemes_name).hash_of(schemes_type)
36
- Puppet::Plugins::DataProviders::register_extensions(extensions)
37
+ Puppet::Plugins::DataProviders::Registry.register_extensions(extensions)
37
38
 
38
39
  # Register injector boot bindings
39
40
  # -------------------------------
@@ -64,5 +65,5 @@ module Puppet::Plugins::Configuration
64
65
  in_multibind(checkers_name)
65
66
  to_instance('Puppet::SyntaxCheckers::Json')
66
67
  end
67
- Puppet::Plugins::DataProviders::register_defaults(bindings)
68
+ Puppet::Plugins::DataProviders::Registry.register_defaults(bindings)
68
69
  end
@@ -1,6 +1,6 @@
1
1
  module Puppet::Plugins; end
2
2
 
3
- class Puppet::Plugins::DataProviders
3
+ module Puppet::Plugins::DataProviders
4
4
 
5
5
  # The lookup **key** for the multibind containing data provider name per module
6
6
  # @api public
@@ -26,65 +26,17 @@ class Puppet::Plugins::DataProviders
26
26
  # @api public
27
27
  MODULE_DATA_PROVIDERS_TYPE = 'Puppet::Plugins::DataProviders::ModuleDataProvider'
28
28
 
29
- def self.register_extensions(extensions)
30
- extensions.multibind(PER_MODULE_DATA_PROVIDER_KEY).name(PER_MODULE_DATA_PROVIDER_KEY).hash_of(PER_MODULE_DATA_PROVIDER_TYPE)
31
- extensions.multibind(ENV_DATA_PROVIDERS_KEY).name(ENV_DATA_PROVIDERS_KEY).hash_of(ENV_DATA_PROVIDERS_TYPE)
32
- extensions.multibind(MODULE_DATA_PROVIDERS_KEY).name(MODULE_DATA_PROVIDERS_KEY).hash_of(MODULE_DATA_PROVIDERS_TYPE)
33
- end
34
-
35
- def self.hash_of_per_module_data_provider
36
- @@HASH_OF_PER_MODULE_DATA_PROVIDERS ||= Puppet::Pops::Types::TypeFactory.hash_of(PER_MODULE_DATA_PROVIDER_TYPE)
37
- end
38
-
39
- def self.hash_of_module_data_providers
40
- @@HASH_OF_MODULE_DATA_PROVIDERS ||= Puppet::Pops::Types::TypeFactory.hash_of(
41
- Puppet::Pops::Types::TypeFactory.type_of(MODULE_DATA_PROVIDERS_TYPE))
42
- end
43
-
44
- def self.hash_of_environment_data_providers
45
- @@HASH_OF_ENV_DATA_PROVIDERS ||= Puppet::Pops::Types::TypeFactory.hash_of(
46
- Puppet::Pops::Types::TypeFactory.type_of(ENV_DATA_PROVIDERS_TYPE))
47
- end
48
-
49
- # Registers a 'none' environment data provider, and a 'none' module data provider as the defaults.
50
- # This is only done to allow that something binds to 'none' rather than removing the entire binding (which
51
- # has the same effect).
52
- #
53
- def self.register_defaults(default_bindings)
54
- default_bindings.bind do
55
- name('none')
56
- in_multibind(ENV_DATA_PROVIDERS_KEY)
57
- to_instance(ENV_DATA_PROVIDERS_TYPE)
58
- end
59
-
60
- default_bindings.bind do
61
- name('function')
62
- in_multibind(ENV_DATA_PROVIDERS_KEY)
63
- to_instance('Puppet::DataProviders::FunctionEnvDataProvider')
64
- end
65
-
66
- default_bindings.bind do
67
- name('none')
68
- in_multibind(MODULE_DATA_PROVIDERS_KEY)
69
- to_instance(MODULE_DATA_PROVIDERS_TYPE)
70
- end
71
-
72
- default_bindings.bind do
73
- name('function')
74
- in_multibind(MODULE_DATA_PROVIDERS_KEY)
75
- to_instance('Puppet::DataProviders::FunctionModuleDataProvider')
76
- end
77
- end
29
+ # The lookup **key** for the multibind containing map of provider name to path based data provider factory
30
+ # implementation.
31
+ # @api public
32
+ PATH_BASED_DATA_PROVIDER_FACTORIES_KEY = 'puppet::path_based_data_provider_factories'
78
33
 
79
- class ModuleDataProvider
80
- def lookup(name, scope, merge)
81
- throw :no_such_key
82
- end
83
- end
34
+ # The lookup **type** for the multibind containing map of provider name to path based data provider factory
35
+ # implementation.
36
+ # @api public
37
+ PATH_BASED_DATA_PROVIDER_FACTORIES_TYPE = 'Puppet::Plugins::DataProviders::PathBasedDataProviderFactory'
84
38
 
85
- class EnvironmentDataProvider
86
- def lookup(name, scope, merge)
87
- throw :no_such_key
88
- end
89
- end
90
39
  end
40
+
41
+ require_relative 'data_providers/data_provider'
42
+ require_relative 'data_providers/registry'
@@ -0,0 +1,283 @@
1
+ module Puppet::Plugins::DataProviders
2
+ module DataProvider
3
+ # Performs a lookup with an endless recursion check.
4
+ #
5
+ # @param key [String] The key to lookup
6
+ # @param lookup_invocation [Puppet::Pops::Lookup::Invocation] The current lookup invocation
7
+ # @param merge [String|Hash<String,Object>|nil] Merge strategy or hash with strategy and options
8
+ #
9
+ # @api public
10
+ def lookup(name, lookup_invocation, merge)
11
+ lookup_invocation.check(name) { unchecked_lookup(name, lookup_invocation, merge) }
12
+ end
13
+
14
+ # Performs a lookup with the assumption that a recursive check has been made.
15
+ #
16
+ # @param key [String] The key to lookup
17
+ # @param lookup_invocation [Puppet::Pops::Lookup::Invocation] The current lookup invocation
18
+ # @param merge [String|Hash<String,Object>|nil] Merge strategy or hash with strategy and options
19
+ #
20
+ # @api public
21
+ def unchecked_lookup(key, lookup_invocation, merge)
22
+ lookup_invocation.with(:data_provider, self) do
23
+ hash = data(data_key(key, lookup_invocation), lookup_invocation)
24
+ value = hash[key]
25
+ if value || hash.include?(key)
26
+ lookup_invocation.report_found(key, post_process(value, lookup_invocation))
27
+ else
28
+ lookup_invocation.report_not_found(key)
29
+ throw :no_such_key
30
+ end
31
+ end
32
+ end
33
+
34
+ # Perform optional post processing of found value. This hook is used by the hiera style
35
+ # providers to perform interpolation. The default method simply returns the given _value_.
36
+ #
37
+ # @param value [Object] The value to perform post processing on
38
+ # @param lookup_invocation [Puppet::Pops::Lookup::Invocation] The current lookup invocation
39
+ # @return [Object] The result of post processing the value.
40
+ #
41
+ # @api public
42
+ def post_process(value, lookup_invocation)
43
+ value
44
+ end
45
+
46
+ # Gets the data from the compiler, or initializes it by calling #initialize_data if not present in the compiler.
47
+ # This means, that data is initialized once per compilation, and the data is cached for as long as the compiler
48
+ # lives (which is for one catalog production). This makes it possible to return data that is tailored for the
49
+ # request.
50
+ #
51
+ # If data is obtained using the #initialize_data method it will be sent to the #validate_data for validation
52
+ #
53
+ # @param data_key [String] The data key such as the name of a module or the constant 'environment'
54
+ # @param lookup_invocation [Puppet::Pops::Lookup::Invocation] The current lookup invocation
55
+ # @param merge [String|Hash<String,Object>|nil] Merge strategy or hash with strategy and options
56
+ # @return [Hash] The data hash for the given _key_
57
+ #
58
+ # @api public
59
+ def data(data_key, lookup_invocation)
60
+ compiler = lookup_invocation.scope.compiler
61
+ adapter = Puppet::DataProviders::DataAdapter.get(compiler) || Puppet::DataProviders::DataAdapter.adapt(compiler)
62
+ adapter.data[data_key] ||= validate_data(initialize_data(data_key, lookup_invocation), data_key)
63
+ end
64
+ protected :data
65
+
66
+ # Obtain an optional key to use when retrieving the data.
67
+ #
68
+ # @param key [String] The key to lookup
69
+ # @return [String,nil] The data key or nil if not applicable
70
+ #
71
+ # @api public
72
+ def data_key(key, lookup_invocation)
73
+ nil
74
+ end
75
+ protected :data_key
76
+
77
+ # Should be reimplemented by subclass to provide the hash that corresponds to the given name.
78
+ #
79
+ # @param data_key [String] The data key such as the name of a module or the constant 'environment'
80
+ # @param lookup_invocation [Puppet::Pops::Lookup::Invocation] The current lookup invocation
81
+ # @return [Hash] The hash of values
82
+ #
83
+ # @api public
84
+ def initialize_data(data_key, lookup_invocation)
85
+ {}
86
+ end
87
+ protected :initialize_data
88
+
89
+ def name
90
+ cname = self.class.name
91
+ cname[cname.rindex(':')+1..-1]
92
+ end
93
+
94
+ def validate_data(data, data_key)
95
+ data
96
+ end
97
+ protected :validate_data
98
+ end
99
+
100
+ class ModuleDataProvider
101
+ include DataProvider
102
+
103
+ # Retrieve the first segment of the qualified name _key_. This method will throw
104
+ # :no_such_key unless the segment can be extracted.
105
+ #
106
+ # @param key [String] The key
107
+ # @return [String] The first segment of the given key
108
+ def data_key(key, lookup_invocation)
109
+ return lookup_invocation.module_name if key == 'lookup_options'
110
+ qual_index = key.index('::')
111
+ throw :no_such_key if qual_index.nil?
112
+ key[0..qual_index-1]
113
+ end
114
+ protected :data_key
115
+
116
+ # Assert that all keys in the given _data_ are prefixed with the given _module_name_.
117
+ #
118
+ # @param data [Hash] The data hash
119
+ # @param module_name [String] The name of the module where the data was found
120
+ # @return [Hash] The data_hash unaltered
121
+ def validate_data(data, module_name)
122
+ module_prefix = "#{module_name}::"
123
+ data.each_key do |k|
124
+ unless k.is_a?(String) && (k == 'lookup_options' || k.start_with?(module_prefix))
125
+ raise Puppet::DataBinding::LookupError, "Module data for module '#{module_name}' must use keys qualified with the name of the module"
126
+ end
127
+ end
128
+ end
129
+ protected :validate_data
130
+ end
131
+
132
+ class EnvironmentDataProvider
133
+ include DataProvider
134
+
135
+ def data_key(key, lookup_invocation)
136
+ 'environment'
137
+ end
138
+ protected :data_key
139
+ end
140
+
141
+ # Class that keeps track of the original path (as it appears in the declaration, before interpolation),
142
+ # the fully resolved path, and whether or the resolved path exists.
143
+ #
144
+ # @api public
145
+ class ResolvedPath
146
+ attr_reader :original_path, :path
147
+
148
+ # @param original_path [String] path as found in declaration. May contain interpolation expressions
149
+ # @param path [Pathname] the expanded absolue path
150
+ # @api public
151
+ def initialize(original_path, path)
152
+ @original_path = original_path
153
+ @path = path
154
+ @exists = nil
155
+ end
156
+
157
+ # @return [Boolean] cached info if the path exists or not
158
+ # @api public
159
+ def exists?
160
+ @exists = @path.exist? if @exists.nil?
161
+ @exists
162
+ end
163
+ end
164
+
165
+ # A data provider that is initialized with a set of _paths_. When performing lookup, each
166
+ # path is search in the order they appear. If a value is found in more than one location it
167
+ # will be merged according to a given (optional) merge strategy.
168
+ #
169
+ # @abstract
170
+ # @api public
171
+ class PathBasedDataProvider
172
+ include DataProvider
173
+
174
+ attr_reader :name
175
+
176
+ # @param name [String] The name of the data provider
177
+ # @param paths [Array<ResolvedPath>] Paths used by this provider
178
+ #
179
+ # @api public
180
+ def initialize(name, paths)
181
+ @name = name
182
+ @paths = paths
183
+ end
184
+
185
+ # Performs a lookup by searching all given paths for the given _key_. A merge will be performed if
186
+ # the value is found in more than one location and _merge_ is not nil.
187
+ #
188
+ # @param key [String] The key to lookup
189
+ # @param lookup_invocation [Puppet::Pops::Lookup::Invocation] The current lookup invocation
190
+ # @param merge [Puppet::Pops::MergeStrategy,String,Hash<String,Object>,nil] Merge strategy or hash with strategy and options
191
+ #
192
+ # @api public
193
+ def unchecked_lookup(key, lookup_invocation, merge)
194
+ lookup_invocation.with(:data_provider, self) do
195
+ merge_strategy = Puppet::Pops::MergeStrategy.strategy(merge)
196
+ lookup_invocation.with(:merge, merge_strategy) do
197
+ merged_result = merge_strategy.merge_lookup(@paths) do |path|
198
+ lookup_invocation.with(:path, path) do
199
+ if path.exists?
200
+ hash = data(path.path, lookup_invocation)
201
+ value = hash[key]
202
+ if value || hash.include?(key)
203
+ lookup_invocation.report_found(key, post_process(value, lookup_invocation))
204
+ else
205
+ lookup_invocation.report_not_found(key)
206
+ throw :no_such_key
207
+ end
208
+ else
209
+ lookup_invocation.report_path_not_found
210
+ throw :no_such_key
211
+ end
212
+ end
213
+ end
214
+ lookup_invocation.report_result(merged_result)
215
+ end
216
+ end
217
+ end
218
+ end
219
+
220
+ # Factory for creating path based data providers
221
+ #
222
+ # @abstract
223
+ # @api public
224
+ class PathBasedDataProviderFactory
225
+ # Create a path based data provider with the given _name_ and _paths_
226
+ #
227
+ # @param name [String] the name of the created provider (for logging and debugging)
228
+ # @param paths [Array<String>] array of resolved paths
229
+ # @return [DataProvider] The created data provider
230
+ #
231
+ # @api public
232
+ def create(name, paths)
233
+ raise NotImplementedError, "Subclass of PathBasedDataProviderFactory must implement 'create' method"
234
+ end
235
+
236
+ # Resolve the given _paths_ to something that is meaningful as a _paths_ argument when creating
237
+ # a provider using the #create call.
238
+ #
239
+ # In order to increase efficiency, the implementors of this method should ensure that resolved
240
+ # paths that exists are included in the result.
241
+ #
242
+ # @param datadir [Pathname] The base when creating absolute paths
243
+ # @param declared_paths [Array<String>] paths as found in declaration. May contain interpolation expressions
244
+ # @param paths [Array<String>] paths that have been preprocessed (interpolations resolved)
245
+ # @param lookup_invocation [Puppet::Pops::Lookup::Invocation] The current lookup invocation
246
+ # @return [Array<ResolvedPath>] Array of resolved paths
247
+ #
248
+ # @api public
249
+ def resolve_paths(datadir, declared_paths, paths, lookup_invocation)
250
+ []
251
+ end
252
+ end
253
+
254
+ # Factory for creating file based data providers. This is an extension of the path based
255
+ # factory where it is required that each resolved path appoints an existing file in the local
256
+ # file system.
257
+ #
258
+ # @abstract
259
+ # @api public
260
+ class FileBasedDataProviderFactory < PathBasedDataProviderFactory
261
+ # @param datadir [Pathname] The base when creating absolute paths
262
+ # @param declared_paths [Array<String>] paths as found in declaration. May contain interpolation expressions
263
+ # @param paths [Array<String>] paths that have been preprocessed (interpolations resolved)
264
+ # @param lookup_invocation [Puppet::Pops::Lookup::Invocation] The current lookup invocation
265
+ # @return [Array<ResolvedPath>] Array of resolved paths
266
+ def resolve_paths(datadir, declared_paths, paths, lookup_invocation)
267
+ resolved_paths = []
268
+ unless paths.nil? || datadir.nil?
269
+ ext = path_extension
270
+ paths.each_with_index do |path, idx|
271
+ path = path + ext unless path.end_with?(ext)
272
+ resolved_paths << ResolvedPath.new(declared_paths[idx], datadir + path)
273
+ end
274
+ end
275
+ resolved_paths
276
+ end
277
+
278
+ def path_extension
279
+ raise NotImplementedError, "Subclass of FileBasedProviderFactory must implement 'path_extension' method"
280
+ end
281
+ protected :path_extension
282
+ end
283
+ end