puppet 4.2.3 → 4.3.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 (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
@@ -16,19 +16,40 @@ class Puppet::Resource::Type
16
16
  include Puppet::Util::Warnings
17
17
  include Puppet::Util::Errors
18
18
 
19
- RESOURCE_KINDS = [:hostclass, :node, :definition]
19
+ RESOURCE_KINDS = [:hostclass, :node, :definition, :capability_mapping, :application, :site]
20
20
 
21
21
  # Map the names used in our documentation to the names used internally
22
22
  RESOURCE_KINDS_TO_EXTERNAL_NAMES = {
23
23
  :hostclass => "class",
24
24
  :node => "node",
25
25
  :definition => "defined_type",
26
+ :application => "application",
27
+ :site => 'site'
26
28
  }
27
29
  RESOURCE_EXTERNAL_NAMES_TO_KINDS = RESOURCE_KINDS_TO_EXTERNAL_NAMES.invert
28
30
 
31
+ NAME = 'name'.freeze
32
+ TITLE = 'title'.freeze
33
+ MODULE_NAME = 'module_name'.freeze
34
+ CALLER_MODULE_NAME = 'caller_module_name'.freeze
35
+ PARAMETERS = 'parameters'.freeze
36
+ KIND = 'kind'.freeze
37
+ NODES = 'nodes'.freeze
38
+ DOUBLE_COLON = '::'.freeze
39
+ EMPTY_ARRAY = [].freeze
40
+
29
41
  attr_accessor :file, :line, :doc, :code, :parent, :resource_type_collection
30
42
  attr_reader :namespace, :arguments, :behaves_like, :module_name
31
43
 
44
+ # The attributes 'produces' and 'consumes' are arrays of the blueprints
45
+ # of capabilities this type can produce/consume. The entries in the array
46
+ # are a fairly direct representation of what goes into produces/consumes
47
+ # clauses. Each entry is a hash with attributes
48
+ # :capability - the type name of the capres produced/consumed
49
+ # :mappings - a hash of attribute_name => Expression
50
+ # These two attributes are populated in
51
+ # PopsBridge::instantiate_CapabilityMaping
52
+
32
53
  # Map from argument (aka parameter) names to Puppet Type
33
54
  # @return [Hash<Symbol, Puppet::Pops::Types::PAnyType] map from name to type
34
55
  #
@@ -48,8 +69,8 @@ class Puppet::Resource::Type
48
69
  indirects :resource_type, :terminus_class => :parser
49
70
 
50
71
  def self.from_data_hash(data)
51
- name = data.delete('name') or raise ArgumentError, "Resource Type names must be specified"
52
- kind = data.delete('kind') || "definition"
72
+ name = data.delete(NAME) or raise ArgumentError, 'Resource Type names must be specified'
73
+ kind = data.delete(KIND) || 'definition'
53
74
 
54
75
  unless type = RESOURCE_EXTERNAL_NAMES_TO_KINDS[kind]
55
76
  raise ArgumentError, "Unsupported resource kind '#{kind}'"
@@ -74,15 +95,15 @@ class Puppet::Resource::Type
74
95
  # External documentation uses "parameters" but the internal name
75
96
  # is "arguments"
76
97
  # Dump any arguments as source
77
- data['parameters'] = Hash[arguments.map do |k,v|
98
+ data[PARAMETERS] = Hash[arguments.map do |k,v|
78
99
  [k, v.respond_to?(:source_text) ? v.source_text : v]
79
100
  end]
80
- data['name'] = name
101
+ data[NAME] = name
81
102
 
82
103
  unless RESOURCE_KINDS_TO_EXTERNAL_NAMES.has_key?(type)
83
104
  raise ArgumentError, "Unsupported resource kind '#{type}'"
84
105
  end
85
- data['kind'] = RESOURCE_KINDS_TO_EXTERNAL_NAMES[type]
106
+ data[KIND] = RESOURCE_KINDS_TO_EXTERNAL_NAMES[type]
86
107
  data
87
108
  end
88
109
 
@@ -94,6 +115,48 @@ class Puppet::Resource::Type
94
115
  return(klass == parent_type ? true : parent_type.child_of?(klass))
95
116
  end
96
117
 
118
+ # Evaluate the resources produced by the given resource. These resources are
119
+ # evaluated in a separate but identical scope from the rest of the resource.
120
+ def evaluate_produces(resource, scope)
121
+ # Only defined types and classes can produce capabilities
122
+ return unless definition? || hostclass?
123
+
124
+ resource.export.map do |ex|
125
+ # Assert that the ref really is a resource reference
126
+ raise Puppet::Error, "Invalid export in #{resource.ref}: #{ex} is not a resource" unless ex.is_a?(Puppet::Resource)
127
+ raise Puppet::Error, "Invalid export in #{resource.ref}: #{ex} is not a capability resource" if ex.resource_type.nil? || !ex.resource_type.is_capability?
128
+
129
+ blueprint = produces.find { |pr| pr[:capability] == ex.type }
130
+ if blueprint.nil?
131
+ raise Puppet::ParseError, "Resource type #{resource.type} does not produce #{ex.type}"
132
+ end
133
+ produced_resource = Puppet::Parser::Resource.new(ex.type, ex.title, :scope => scope, :source => self)
134
+
135
+ produced_resource.resource_type.parameters.each do |name|
136
+ next if name == :name
137
+
138
+ if expr = blueprint[:mappings][name.to_s]
139
+ produced_resource[name] = expr.safeevaluate(scope)
140
+ else
141
+ produced_resource[name] = scope[name.to_s]
142
+ end
143
+ end
144
+ # Tag the produced resource so we can later distinguish it from
145
+ # copies of the resource that wind up in the catalogs of nodes that
146
+ # use this resource. We tag the resource with producer:<environment>,
147
+ # meaning produced resources need to be unique within their
148
+ # environment
149
+ # @todo lutter 2014-11-13: we would really like to use a dedicated
150
+ # metadata field to indicate the producer of a resource, but that
151
+ # requires changes to PuppetDB and its API; so for now, we just use
152
+ # tagging
153
+ produced_resource.tag("producer:#{scope.catalog.environment}")
154
+ scope.catalog.add_resource(produced_resource)
155
+ produced_resource[:require] = resource.ref
156
+ produced_resource
157
+ end
158
+ end
159
+
97
160
  # Now evaluate the code associated with this class or definition.
98
161
  def evaluate_code(resource)
99
162
 
@@ -107,6 +170,8 @@ class Puppet::Resource::Type
107
170
 
108
171
  resource.add_edge_to_stage
109
172
 
173
+ evaluate_produces(resource, scope)
174
+
110
175
  if code
111
176
  if @match # Only bother setting up the ephemeral scope if there are match variables to add into it
112
177
  begin
@@ -132,7 +197,7 @@ class Puppet::Resource::Type
132
197
 
133
198
  [:code, :doc, :line, :file, :parent].each do |param|
134
199
  next unless value = options[param]
135
- send(param.to_s + "=", value)
200
+ send(param.to_s + '=', value)
136
201
  end
137
202
 
138
203
  set_arguments(options[:arguments])
@@ -143,6 +208,24 @@ class Puppet::Resource::Type
143
208
  @module_name = options[:module_name]
144
209
  end
145
210
 
211
+ def produces
212
+ @produces || EMPTY_ARRAY
213
+ end
214
+
215
+ def consumes
216
+ @consumes || EMPTY_ARRAY
217
+ end
218
+
219
+ def add_produces(blueprint)
220
+ @produces ||= []
221
+ @produces << blueprint
222
+ end
223
+
224
+ def add_consumes(blueprint)
225
+ @consumes ||= []
226
+ @consumes << blueprint
227
+ end
228
+
146
229
  # This is only used for node names, and really only when the node name
147
230
  # is a regexp.
148
231
  def match(string)
@@ -186,8 +269,17 @@ class Puppet::Resource::Type
186
269
  # parameterized class, then all parameters take on their default
187
270
  # values.
188
271
  def ensure_in_catalog(scope, parameters=nil)
189
- type == :definition and raise ArgumentError, "Cannot create resources for defined resource types"
190
- resource_type = type == :hostclass ? :class : :node
272
+ resource_type =
273
+ case type
274
+ when :definition
275
+ raise ArgumentError, 'Cannot create resources for defined resource types'
276
+ when :hostclass
277
+ :class
278
+ when :node
279
+ :node
280
+ when :site
281
+ :site
282
+ end
191
283
 
192
284
  # Do nothing if the resource already exists; this makes sure we don't
193
285
  # get multiple copies of the class resource, which helps provide the
@@ -196,11 +288,13 @@ class Puppet::Resource::Type
196
288
  # if parameters are passed, we should still try to create the resource
197
289
  # even if it exists so that we can fail
198
290
  # this prevents us from being able to combine param classes with include
199
- if resource = scope.catalog.resource(resource_type, name) and !parameters
200
- return resource
291
+ if parameters.nil?
292
+ resource = scope.catalog.resource(resource_type, name)
293
+ return resource unless resource.nil?
294
+ elsif parameters.is_a?(Hash)
295
+ parameters = parameters.map {|k, v| Puppet::Parser::Resource::Param.new(:name => k, :value => v, :source => self)}
201
296
  end
202
- resource = Puppet::Parser::Resource.new(resource_type, name, :scope => scope, :source => self)
203
- assign_parameter_values(parameters, resource)
297
+ resource = Puppet::Parser::Resource.new(resource_type, name, :scope => scope, :source => self, :parameters => parameters)
204
298
  instantiate_resource(scope, resource)
205
299
  scope.compiler.add_resource(scope, resource)
206
300
  resource
@@ -229,7 +323,11 @@ class Puppet::Resource::Type
229
323
  @name.is_a?(Regexp)
230
324
  end
231
325
 
326
+ # @deprecated Not used by Puppet
327
+ # @api private
232
328
  def assign_parameter_values(parameters, resource)
329
+ Puppet.deprecation_warning('The method Puppet::Resource::Type.assign_parameter_values is deprecated and will be removed in the next major release of Puppet.')
330
+
233
331
  return unless parameters
234
332
 
235
333
  # It'd be nice to assign default parameter values here,
@@ -247,53 +345,91 @@ class Puppet::Resource::Type
247
345
  fail(Puppet::ParseError, "Could not find parent resource type '#{parent}' of type #{type} in #{scope.environment}")
248
346
  end
249
347
 
250
- # Set any arguments passed by the resource as variables in the scope.
348
+ # Validate and set any arguments passed by the resource as variables in the scope.
349
+ # @param resource [Puppet::Parser::Resource] the resource
350
+ # @param scope [Puppet::Parser::Scope] the scope
351
+ #
352
+ # @api private
251
353
  def set_resource_parameters(resource, scope)
252
- set = {}
253
- resource.to_hash.each do |param, value|
254
- param = param.to_sym
255
- fail Puppet::ParseError, "#{resource.ref} does not accept attribute #{param}" unless valid_parameter?(param)
354
+ # Inject parameters from using external lookup
355
+ resource.add_parameters_from_consume
356
+ inject_external_parameters(resource, scope)
256
357
 
257
- exceptwrap { scope[param.to_s] = value }
258
-
259
- set[param] = true
260
- end
358
+ resource_hash = {}
359
+ resource.each { |k, v| resource_hash[k.to_s] = v.value unless k == :name || k == :title }
261
360
 
262
361
  if @type == :hostclass
263
- scope["title"] = resource.title.to_s.downcase unless set.include? :title
264
- scope["name"] = resource.name.to_s.downcase unless set.include? :name
362
+ scope[TITLE] = resource.title.to_s.downcase
363
+ scope[NAME] = resource.name.to_s.downcase
265
364
  else
266
- scope["title"] = resource.title unless set.include? :title
267
- scope["name"] = resource.name unless set.include? :name
365
+ scope[TITLE] = resource.title
366
+ scope[NAME] = resource.name
268
367
  end
269
- scope["module_name"] = module_name if module_name and ! set.include? :module_name
270
368
 
271
- if caller_name = scope.parent_module_name and ! set.include?(:caller_module_name)
272
- scope["caller_module_name"] = caller_name
369
+ modname = resource_hash[MODULE_NAME] || module_name
370
+ scope[MODULE_NAME] = modname unless modname.nil?
371
+ caller_name = resource_hash[CALLER_MODULE_NAME] || scope.parent_module_name
372
+ scope[CALLER_MODULE_NAME] = caller_name unless caller_name.nil?
373
+
374
+ scope.class_set(self.name,scope) if hostclass? || node?
375
+
376
+ assign_defaults(resource, scope, resource_hash)
377
+ validate_resource_hash(resource, resource_hash)
378
+ resource_hash.each { |param, value| exceptwrap { scope[param] = value }}
379
+ end
380
+
381
+ # Lookup and inject parameters from external scope
382
+ # @param resource [Puppet::Parser::Resource] the resource
383
+ # @param scope [Puppet::Parser::Scope] the scope
384
+ def inject_external_parameters(resource, scope)
385
+ # Only lookup parameters for host classes
386
+ return unless type == :hostclass
387
+ parameters = resource.parameters
388
+ arguments.each do |param_name, _|
389
+ name = param_name.to_sym
390
+ next if parameters.include?(name)
391
+ value = lookup_external_default_for(param_name, scope)
392
+ resource[name] = value unless value.nil?
393
+ end
394
+ end
395
+ private :inject_external_parameters
396
+
397
+ def assign_defaults(resource, scope, resource_hash)
398
+ return unless resource.is_a?(Puppet::Parser::Resource)
399
+ parameters = resource.parameters
400
+ hashed_types = parameter_struct.hashed_elements
401
+ arguments.each do |param_name, default|
402
+ next if default.nil?
403
+ name = param_name.to_sym
404
+ param = parameters[name]
405
+ next unless param.nil? || param.value.nil?
406
+
407
+ value = default.safeevaluate(scope)
408
+ resource[name] = value
409
+ resource_hash[param_name] = value
273
410
  end
274
- scope.class_set(self.name,scope) if hostclass? or node?
411
+ end
412
+ private :assign_defaults
275
413
 
276
- # Evaluate the default parameters, now that all other variables are set
277
- default_params = resource.set_default_parameters(scope)
278
- default_params.each { |param| scope[param] = resource[param] }
414
+ def validate_resource_hash(resource, resource_hash)
415
+ Puppet::Pops::Types::TypeMismatchDescriber.validate_parameters(resource.to_s, parameter_struct, resource_hash, resource.is_unevaluated_consumer?)
416
+ end
417
+ private :validate_resource_hash
279
418
 
280
- # This has to come after the above parameters so that default values
281
- # can use their values
282
- resource.validate_complete
419
+ # Validate that all parameters given to the resource are correct
420
+ # @param resource [Puppet::Resource] the resource to validate
421
+ def validate_resource(resource)
422
+ validate_resource_hash(resource, Hash[resource.parameters.map { |name, value| [name.to_s, value.value] }])
283
423
  end
284
424
 
285
425
  # Check whether a given argument is valid.
286
426
  def valid_parameter?(param)
287
- param = param.to_s
288
-
289
- return true if param == "name"
290
- return true if Puppet::Type.metaparam?(param)
291
- return false unless defined?(@arguments)
292
- return(arguments.include?(param) ? true : false)
427
+ parameter_struct.hashed_elements.include?(param.to_s)
293
428
  end
294
429
 
295
430
  def set_arguments(arguments)
296
431
  @arguments = {}
432
+ @parameter_struct = nil
297
433
  return if arguments.nil?
298
434
 
299
435
  arguments.each do |arg, default|
@@ -309,6 +445,7 @@ class Puppet::Resource::Type
309
445
  #
310
446
  def set_argument_types(name_to_type_hash)
311
447
  @argument_types = {}
448
+ @parameter_struct = nil
312
449
  return unless name_to_type_hash
313
450
  name_to_type_hash.each do |name, t|
314
451
  # catch internal errors
@@ -322,6 +459,14 @@ class Puppet::Resource::Type
322
459
  end
323
460
  end
324
461
 
462
+ # Returns boolean true if an instance of this type is a capability. This
463
+ # implementation always returns false. This "duck-typing" interface is
464
+ # shared among other classes and makes it easier to detect capabilities
465
+ # when they are intermixed with non capability instances.
466
+ def is_capability?
467
+ false
468
+ end
469
+
325
470
  private
326
471
 
327
472
  def convert_from_ast(name)
@@ -341,9 +486,9 @@ class Puppet::Resource::Type
341
486
 
342
487
  # Split an fq name into a namespace and name
343
488
  def namesplit(fullname)
344
- ary = fullname.split("::")
489
+ ary = fullname.split(DOUBLE_COLON)
345
490
  n = ary.pop || ""
346
- ns = ary.join("::")
491
+ ns = ary.join(DOUBLE_COLON)
347
492
  return ns, n
348
493
  end
349
494
 
@@ -374,4 +519,53 @@ class Puppet::Resource::Type
374
519
  raise Puppet::ParseError, "#{param} is a metaparameter; please choose another parameter name in the #{self.name} definition"
375
520
  end
376
521
  end
522
+
523
+ def parameter_struct
524
+ @parameter_struct ||= create_params_struct
525
+ end
526
+
527
+ def create_params_struct
528
+ arg_types = argument_types
529
+ type_factory = Puppet::Pops::Types::TypeFactory
530
+ members = { type_factory.optional(type_factory.string(nil, NAME)) => type_factory.any }
531
+
532
+ if application?
533
+ resource_type = type_factory.type_type(type_factory.resource)
534
+ members[type_factory.optional(type_factory.string(nil, NODES))] = type_factory.hash_of(type_factory.variant(
535
+ resource_type, type_factory.array_of(resource_type)), type_factory.type_type(type_factory.resource('node')))
536
+ end
537
+
538
+ Puppet::Type.eachmetaparam do |name|
539
+ # TODO: Once meta parameters are typed, this should change to reflect that type
540
+ members[name.to_s] = type_factory.any
541
+ end
542
+
543
+ arguments.each_pair do |name, default|
544
+ key_type = type_factory.string(nil, name.to_s)
545
+ key_type = type_factory.optional(key_type) unless default.nil?
546
+
547
+ arg_type = arg_types[name]
548
+ arg_type = type_factory.any if arg_type.nil?
549
+ members[key_type] = arg_type
550
+ end
551
+ type_factory.struct(members)
552
+ end
553
+ private :create_params_struct
554
+
555
+ # Consult external data bindings for class parameter values which must be
556
+ # namespaced in the backend.
557
+ #
558
+ # Example:
559
+ #
560
+ # class foo($port=0){ ... }
561
+ #
562
+ # We make a request to the backend for the key 'foo::port' not 'foo'
563
+ #
564
+ def lookup_external_default_for(param, scope)
565
+ if type == :hostclass
566
+ catch(:no_such_key) { return Puppet::Pops::Lookup.search_and_merge("#{name}::#{param}", Puppet::Pops::Lookup::Invocation.new(scope), nil) }
567
+ end
568
+ nil
569
+ end
570
+ private :lookup_external_default_for
377
571
  end
@@ -11,16 +11,22 @@ class Puppet::Resource::TypeCollection
11
11
  def clear
12
12
  @hostclasses.clear
13
13
  @definitions.clear
14
+ @applications.clear
14
15
  @nodes.clear
15
16
  @notfound.clear
17
+ @capability_mappings.clear
18
+ @sites.clear
16
19
  end
17
20
 
18
21
  def initialize(env)
19
22
  @environment = env
20
23
  @hostclasses = {}
21
24
  @definitions = {}
25
+ @capability_mappings = {}
26
+ @applications = {}
22
27
  @nodes = {}
23
28
  @notfound = {}
29
+ @sites = []
24
30
 
25
31
  # So we can keep a list and match the first-defined regex
26
32
  @node_list = []
@@ -33,7 +39,14 @@ class Puppet::Resource::TypeCollection
33
39
  end
34
40
 
35
41
  def inspect
36
- "TypeCollection" + { :hostclasses => @hostclasses.keys, :definitions => @definitions.keys, :nodes => @nodes.keys }.inspect
42
+ "TypeCollection" + {
43
+ :hostclasses => @hostclasses.keys,
44
+ :definitions => @definitions.keys,
45
+ :nodes => @nodes.keys,
46
+ :capability_mappings => @capability_mappings.keys,
47
+ :applications => @applications.keys,
48
+ :site => @sites[0] # todo, could be just a binary, this dumps the entire body (good while developing)
49
+ }.inspect
37
50
  end
38
51
 
39
52
  def <<(thing)
@@ -55,6 +68,7 @@ class Puppet::Resource::TypeCollection
55
68
  def add_hostclass(instance)
56
69
  dupe_check(instance, @hostclasses) { |dupe| "Class '#{instance.name}' is already defined#{dupe.error_context}; cannot redefine" }
57
70
  dupe_check(instance, @definitions) { |dupe| "Definition '#{instance.name}' is already defined#{dupe.error_context}; cannot be redefined as a class" }
71
+ dupe_check(instance, @applications) { |dupe| "Application '#{instance.name}' is already defined#{dupe.error_context}; cannot be redefined as a class" }
58
72
 
59
73
  @hostclasses[instance.name] = instance
60
74
  instance
@@ -72,6 +86,16 @@ class Puppet::Resource::TypeCollection
72
86
  instance
73
87
  end
74
88
 
89
+ def add_site(instance)
90
+ dupe_check_singleton(instance, @sites) { |dupe| "Site is already defined#{dupe.error_context}; cannot redefine" }
91
+ @sites << instance
92
+ instance
93
+ end
94
+
95
+ def site(_)
96
+ @sites[0]
97
+ end
98
+
75
99
  def loader
76
100
  @loader ||= Puppet::Parser::TypeLoader.new(environment)
77
101
  end
@@ -101,17 +125,38 @@ class Puppet::Resource::TypeCollection
101
125
  def add_definition(instance)
102
126
  dupe_check(instance, @hostclasses) { |dupe| "'#{instance.name}' is already defined#{dupe.error_context} as a class; cannot redefine as a definition" }
103
127
  dupe_check(instance, @definitions) { |dupe| "Definition '#{instance.name}' is already defined#{dupe.error_context}; cannot be redefined" }
128
+ dupe_check(instance, @applications) { |dupe| "'#{instance.name}' is already defined#{dupe.error_context} as an application; cannot be redefined" }
104
129
  @definitions[instance.name] = instance
105
130
  end
106
131
 
132
+ def add_capability_mapping(instance)
133
+ dupe_check(instance, @capability_mappings) { |dupe| "'#{instance.name}' is already defined#{dupe.error_context} as a class; cannot redefine as a mapping" }
134
+ @capability_mappings[instance.name] = instance
135
+ end
136
+
107
137
  def definition(name)
108
138
  @definitions[munge_name(name)]
109
139
  end
110
140
 
141
+ def add_application(instance)
142
+ dupe_check(instance, @hostclasses) { |dupe| "'#{instance.name}' is already defined#{dupe.error_context} as a class; cannot redefine as an application" }
143
+ dupe_check(instance, @definitions) { |dupe| "'#{instance.name}' is already defined#{dupe.error_context} as a definition; cannot redefine as an application" }
144
+ dupe_check(instance, @applications) { |dupe| "'#{instance.name}' is already defined#{dupe.error_context} as an application; cannot be redefined" }
145
+ @applications[instance.name] = instance
146
+ end
147
+
148
+ def application(name)
149
+ @applications[munge_name(name)]
150
+ end
151
+
111
152
  def find_node(name)
112
153
  @nodes[munge_name(name)]
113
154
  end
114
155
 
156
+ def find_site()
157
+ @sites[0]
158
+ end
159
+
115
160
  def find_hostclass(name)
116
161
  find_or_load(name, :hostclass)
117
162
  end
@@ -120,7 +165,14 @@ class Puppet::Resource::TypeCollection
120
165
  find_or_load(name, :definition)
121
166
  end
122
167
 
123
- [:hostclasses, :nodes, :definitions].each do |m|
168
+ def find_application(name)
169
+ find_or_load(name, :application)
170
+ end
171
+
172
+ # TODO: This implementation is wasteful as it creates a copy on each request
173
+ #
174
+ [:hostclasses, :nodes, :definitions, :capability_mappings,
175
+ :applications].each do |m|
124
176
  define_method(m) do
125
177
  instance_variable_get("@#{m}").dup
126
178
  end
@@ -180,4 +232,10 @@ class Puppet::Resource::TypeCollection
180
232
  message = yield dupe
181
233
  instance.fail Puppet::ParseError, message
182
234
  end
235
+
236
+ def dupe_check_singleton(instance, set)
237
+ return if set.empty?
238
+ message = yield set[0]
239
+ instance.fail Puppet::ParseError, message
240
+ end
183
241
  end