puppet 4.2.0 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (422) hide show
  1. data/CONTRIBUTING.md +1 -1
  2. data/Gemfile +5 -7
  3. data/README.md +1 -1
  4. data/Rakefile +20 -0
  5. data/ext/debian/puppet.init +0 -1
  6. data/ext/debian/puppet.logrotate +14 -5
  7. data/ext/osx/puppet.plist +2 -4
  8. data/ext/project_data.yaml +1 -1
  9. data/ext/redhat/client.init +65 -12
  10. data/ext/redhat/logrotate +15 -3
  11. data/ext/redhat/puppet.spec.erb +5 -1
  12. data/ext/redhat/server.init +1 -1
  13. data/ext/solaris/smf/puppet +44 -0
  14. data/ext/solaris/smf/puppet.xml +44 -0
  15. data/ext/suse/client.init +27 -27
  16. data/ext/suse/server.init +2 -2
  17. data/ext/systemd/puppet.service +1 -0
  18. data/install.rb +21 -39
  19. data/lib/hiera/puppet_function.rb +5 -5
  20. data/lib/puppet/agent/locker.rb +11 -2
  21. data/lib/puppet/agent.rb +4 -4
  22. data/lib/puppet/application/agent.rb +28 -14
  23. data/lib/puppet/application/apply.rb +17 -4
  24. data/lib/puppet/application/cert.rb +16 -0
  25. data/lib/puppet/application/filebucket.rb +78 -4
  26. data/lib/puppet/application/lookup.rb +356 -0
  27. data/lib/puppet/application/master.rb +5 -1
  28. data/lib/puppet/configurer.rb +9 -5
  29. data/lib/puppet/context/trusted_information.rb +21 -1
  30. data/lib/puppet/context.rb +16 -1
  31. data/lib/puppet/daemon.rb +17 -13
  32. data/lib/puppet/data_binding.rb +4 -2
  33. data/lib/puppet/data_providers/data_adapter.rb +7 -68
  34. data/lib/puppet/data_providers/data_function_support.rb +5 -26
  35. data/lib/puppet/data_providers/function_env_data_provider.rb +0 -10
  36. data/lib/puppet/data_providers/function_module_data_provider.rb +0 -22
  37. data/lib/puppet/data_providers/hiera_config.rb +106 -0
  38. data/lib/puppet/data_providers/hiera_env_data_provider.rb +18 -0
  39. data/lib/puppet/data_providers/hiera_interpolate.rb +97 -0
  40. data/lib/puppet/data_providers/hiera_module_data_provider.rb +23 -0
  41. data/lib/puppet/data_providers/hiera_support.rb +37 -0
  42. data/lib/puppet/data_providers/json_data_provider_factory.rb +31 -0
  43. data/lib/puppet/data_providers/lookup_adapter.rb +200 -0
  44. data/lib/puppet/data_providers/yaml_data_provider_factory.rb +32 -0
  45. data/lib/puppet/data_providers.rb +12 -13
  46. data/lib/puppet/defaults.rb +14 -3
  47. data/lib/puppet/environments.rb +94 -6
  48. data/lib/puppet/error.rb +4 -0
  49. data/lib/puppet/face/module/changes.rb +2 -1
  50. data/lib/puppet/feature/cfacter.rb +1 -0
  51. data/lib/puppet/file_bucket/dipper.rb +58 -2
  52. data/lib/puppet/file_system/windows.rb +3 -1
  53. data/lib/puppet/functions/assert_type.rb +48 -12
  54. data/lib/puppet/functions/defined.rb +79 -48
  55. data/lib/puppet/functions/each.rb +85 -27
  56. data/lib/puppet/functions/epp.rb +29 -37
  57. data/lib/puppet/functions/filter.rb +60 -25
  58. data/lib/puppet/functions/hiera.rb +76 -3
  59. data/lib/puppet/functions/hiera_array.rb +65 -3
  60. data/lib/puppet/functions/hiera_hash.rb +74 -2
  61. data/lib/puppet/functions/hiera_include.rb +77 -4
  62. data/lib/puppet/functions/inline_epp.rb +44 -71
  63. data/lib/puppet/functions/lookup.rb +19 -17
  64. data/lib/puppet/functions/map.rb +56 -21
  65. data/lib/puppet/functions/match.rb +29 -12
  66. data/lib/puppet/functions/reduce.rb +95 -58
  67. data/lib/puppet/functions/versioncmp.rb +36 -0
  68. data/lib/puppet/functions/with.rb +15 -7
  69. data/lib/puppet/functions.rb +2 -4
  70. data/lib/puppet/indirector/catalog/compiler.rb +3 -3
  71. data/lib/puppet/indirector/catalog/static_compiler.rb +46 -30
  72. data/lib/puppet/indirector/data_binding/none.rb +4 -1
  73. data/lib/puppet/indirector/file_bucket_file/file.rb +58 -1
  74. data/lib/puppet/indirector/hiera.rb +4 -0
  75. data/lib/puppet/indirector/indirection.rb +6 -1
  76. data/lib/puppet/indirector/json.rb +1 -1
  77. data/lib/puppet/indirector/msgpack.rb +1 -1
  78. data/lib/puppet/indirector/request.rb +7 -8
  79. data/lib/puppet/indirector/resource_type/parser.rb +5 -3
  80. data/lib/puppet/info_service/class_information_service.rb +111 -0
  81. data/lib/puppet/info_service.rb +7 -0
  82. data/lib/puppet/module_tool/applications/unpacker.rb +1 -1
  83. data/lib/puppet/module_tool/metadata.rb +32 -9
  84. data/lib/puppet/module_tool/skeleton/templates/generator/README.md.erb +42 -38
  85. data/lib/puppet/module_tool/skeleton/templates/generator/manifests/init.pp.erb +25 -18
  86. data/lib/puppet/network/authconfig.rb +21 -1
  87. data/lib/puppet/network/authorization.rb +8 -1
  88. data/lib/puppet/network/http/api/master/v3/environment.rb +59 -0
  89. data/lib/puppet/network/http/api/master/v3.rb +7 -1
  90. data/lib/puppet/node/environment.rb +9 -2
  91. data/lib/puppet/node.rb +11 -5
  92. data/lib/puppet/parser/ast/pops_bridge.rb +39 -1
  93. data/lib/puppet/parser/compiler/catalog_validator/env_relationship_validator.rb +64 -0
  94. data/lib/puppet/parser/compiler/catalog_validator/relationship_validator.rb +38 -0
  95. data/lib/puppet/parser/compiler/catalog_validator/site_validator.rb +20 -0
  96. data/lib/puppet/parser/compiler/catalog_validator.rb +33 -0
  97. data/lib/puppet/parser/compiler.rb +300 -12
  98. data/lib/puppet/parser/environment_compiler.rb +165 -0
  99. data/lib/puppet/parser/functions/assert_type.rb +46 -16
  100. data/lib/puppet/parser/functions/defined.rb +105 -68
  101. data/lib/puppet/parser/functions/each.rb +85 -27
  102. data/lib/puppet/parser/functions/epp.rb +29 -37
  103. data/lib/puppet/parser/functions/filter.rb +59 -23
  104. data/lib/puppet/parser/functions/hiera.rb +83 -27
  105. data/lib/puppet/parser/functions/hiera_array.rb +71 -28
  106. data/lib/puppet/parser/functions/hiera_hash.rb +81 -30
  107. data/lib/puppet/parser/functions/hiera_include.rb +81 -40
  108. data/lib/puppet/parser/functions/inline_epp.rb +35 -60
  109. data/lib/puppet/parser/functions/inline_template.rb +2 -2
  110. data/lib/puppet/parser/functions/map.rb +55 -20
  111. data/lib/puppet/parser/functions/match.rb +27 -12
  112. data/lib/puppet/parser/functions/reduce.rb +97 -60
  113. data/lib/puppet/parser/functions/with.rb +16 -8
  114. data/lib/puppet/parser/resource.rb +103 -21
  115. data/lib/puppet/parser.rb +3 -0
  116. data/lib/puppet/plugins/configuration.rb +3 -2
  117. data/lib/puppet/plugins/data_providers/data_provider.rb +283 -0
  118. data/lib/puppet/plugins/data_providers/registry.rb +84 -0
  119. data/lib/puppet/plugins/data_providers.rb +12 -60
  120. data/lib/puppet/pops/adapters.rb +12 -0
  121. data/lib/puppet/pops/binder/binder.rb +2 -2
  122. data/lib/puppet/pops/binder/bindings_checker.rb +1 -1
  123. data/lib/puppet/pops/binder/bindings_label_provider.rb +3 -1
  124. data/lib/puppet/pops/binder/bindings_loader.rb +6 -2
  125. data/lib/puppet/pops/binder/bindings_model_meta.rb +2 -2
  126. data/lib/puppet/pops/binder/config/binder_config.rb +1 -1
  127. data/lib/puppet/pops/binder/injector.rb +4 -4
  128. data/lib/puppet/pops/binder/key_factory.rb +3 -9
  129. data/lib/puppet/pops/binder/scheme_handler/module_scheme.rb +68 -9
  130. data/lib/puppet/pops/evaluator/access_operator.rb +27 -60
  131. data/lib/puppet/pops/evaluator/closure.rb +8 -8
  132. data/lib/puppet/pops/evaluator/collectors/abstract_collector.rb +1 -1
  133. data/lib/puppet/pops/evaluator/evaluator_impl.rb +10 -6
  134. data/lib/puppet/pops/evaluator/literal_evaluator.rb +87 -0
  135. data/lib/puppet/pops/evaluator/relationship_operator.rb +7 -1
  136. data/lib/puppet/pops/functions/dispatcher.rb +3 -3
  137. data/lib/puppet/pops/issues.rb +11 -3
  138. data/lib/puppet/pops/label_provider.rb +1 -1
  139. data/lib/puppet/pops/lookup/explainer.rb +402 -0
  140. data/lib/puppet/pops/lookup/invocation.rb +117 -0
  141. data/lib/puppet/pops/lookup.rb +25 -47
  142. data/lib/puppet/pops/merge_strategy.rb +73 -5
  143. data/lib/puppet/pops/model/factory.rb +38 -3
  144. data/lib/puppet/pops/model/model_label_provider.rb +10 -1
  145. data/lib/puppet/pops/model/model_meta.rb +19 -1
  146. data/lib/puppet/pops/model/model_tree_dumper.rb +18 -0
  147. data/lib/puppet/pops/parser/code_merger.rb +13 -1
  148. data/lib/puppet/pops/parser/egrammar.ra +65 -2
  149. data/lib/puppet/pops/parser/eparser.rb +1569 -1241
  150. data/lib/puppet/pops/parser/lexer2.rb +32 -1
  151. data/lib/puppet/pops/parser/locator.rb +1 -1
  152. data/lib/puppet/pops/parser/parser_support.rb +25 -13
  153. data/lib/puppet/pops/patterns.rb +3 -0
  154. data/lib/puppet/pops/types/enumeration.rb +1 -2
  155. data/lib/puppet/pops/types/type_asserter.rb +16 -15
  156. data/lib/puppet/pops/types/type_assertion_error.rb +1 -0
  157. data/lib/puppet/pops/types/type_calculator.rb +171 -1020
  158. data/lib/puppet/pops/types/type_factory.rb +87 -148
  159. data/lib/puppet/pops/types/type_mismatch_describer.rb +743 -0
  160. data/lib/puppet/pops/types/type_parser.rb +118 -129
  161. data/lib/puppet/pops/types/types.rb +1394 -255
  162. data/lib/puppet/pops/types/types_meta.rb +0 -234
  163. data/lib/puppet/pops/validation/checker4_0.rb +49 -1
  164. data/lib/puppet/pops/validation/validator_factory_4_0.rb +3 -1
  165. data/lib/puppet/pops/validation.rb +7 -2
  166. data/lib/puppet/pops.rb +19 -17
  167. data/lib/puppet/provider/augeas/augeas.rb +50 -0
  168. data/lib/puppet/provider/exec.rb +6 -1
  169. data/lib/puppet/provider/group/directoryservice.rb +10 -0
  170. data/lib/puppet/provider/package/dnf.rb +41 -0
  171. data/lib/puppet/provider/package/gem.rb +7 -2
  172. data/lib/puppet/provider/package/nim.rb +1 -1
  173. data/lib/puppet/provider/package/rpm.rb +1 -0
  174. data/lib/puppet/provider/package/windows/exe_package.rb +10 -8
  175. data/lib/puppet/provider/package/windows/msi_package.rb +4 -3
  176. data/lib/puppet/provider/package/windows/package.rb +9 -1
  177. data/lib/puppet/provider/package/yum.rb +20 -9
  178. data/lib/puppet/provider/service/bsd.rb +1 -1
  179. data/lib/puppet/provider/service/debian.rb +21 -0
  180. data/lib/puppet/provider/service/init.rb +6 -0
  181. data/lib/puppet/provider/service/launchd.rb +36 -7
  182. data/lib/puppet/provider/service/rcng.rb +51 -0
  183. data/lib/puppet/provider/service/redhat.rb +2 -1
  184. data/lib/puppet/provider/service/smf.rb +43 -2
  185. data/lib/puppet/provider/service/src.rb +27 -0
  186. data/lib/puppet/provider/service/systemd.rb +25 -5
  187. data/lib/puppet/provider/sshkey/parsed.rb +19 -9
  188. data/lib/puppet/provider/zone/solaris.rb +2 -2
  189. data/lib/puppet/reference/configuration.rb +10 -4
  190. data/lib/puppet/reference/report.rb +9 -12
  191. data/lib/puppet/reports.rb +5 -1
  192. data/lib/puppet/resource/capability_finder.rb +95 -0
  193. data/lib/puppet/resource/catalog.rb +47 -7
  194. data/lib/puppet/resource/status.rb +0 -2
  195. data/lib/puppet/resource/type.rb +238 -44
  196. data/lib/puppet/resource/type_collection.rb +60 -2
  197. data/lib/puppet/resource.rb +50 -73
  198. data/lib/puppet/settings/file_setting.rb +10 -9
  199. data/lib/puppet/settings.rb +2 -2
  200. data/lib/puppet/ssl/certificate_authority/interface.rb +2 -2
  201. data/lib/puppet/ssl/oids.rb +9 -1
  202. data/lib/puppet/transaction/additional_resource_generator.rb +71 -8
  203. data/lib/puppet/transaction/resource_harness.rb +9 -4
  204. data/lib/puppet/transaction.rb +8 -1
  205. data/lib/puppet/type/augeas.rb +8 -0
  206. data/lib/puppet/type/file/source.rb +14 -12
  207. data/lib/puppet/type/package.rb +9 -6
  208. data/lib/puppet/type/user.rb +4 -2
  209. data/lib/puppet/type.rb +78 -7
  210. data/lib/puppet/util/command_line.rb +4 -0
  211. data/lib/puppet/util/execution.rb +18 -2
  212. data/lib/puppet/util/tagging.rb +7 -1
  213. data/lib/puppet/util/windows/adsi.rb +5 -2
  214. data/lib/puppet/util/windows/security.rb +4 -1
  215. data/lib/puppet/util/windows/taskscheduler.rb +1 -1
  216. data/lib/puppet/util.rb +9 -1
  217. data/lib/puppet/version.rb +1 -1
  218. data/lib/puppet.rb +12 -0
  219. data/spec/fixtures/unit/application/environments/production/data/common.yaml +3 -0
  220. data/spec/fixtures/unit/application/environments/production/environment.conf +1 -0
  221. data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_json/data/bad.json +3 -0
  222. data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_json/environment.conf +2 -0
  223. data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_json/hiera.yaml +5 -0
  224. data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_json/manifests/site.pp +5 -0
  225. data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_yaml/data/bad.yaml +3 -0
  226. data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_yaml/environment.conf +2 -0
  227. data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_yaml/hiera.yaml +5 -0
  228. data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_yaml/manifests/site.pp +5 -0
  229. data/spec/fixtures/unit/data_providers/environments/hiera_defaults/data/common.yaml +2 -0
  230. data/spec/fixtures/unit/data_providers/environments/hiera_defaults/environment.conf +2 -0
  231. data/spec/fixtures/unit/data_providers/environments/hiera_defaults/manifests/site.pp +1 -0
  232. data/spec/fixtures/unit/data_providers/environments/hiera_defaults/modules/one/data/common.yaml +2 -0
  233. data/spec/fixtures/unit/data_providers/environments/hiera_defaults/modules/one/manifests/init.pp +5 -0
  234. data/spec/fixtures/unit/data_providers/environments/hiera_defaults/modules/one/metadata.json +9 -0
  235. data/spec/fixtures/unit/data_providers/environments/hiera_env_config/data1/first.json +3 -0
  236. data/spec/fixtures/unit/data_providers/environments/hiera_env_config/data1/name.yaml +2 -0
  237. data/spec/fixtures/unit/data_providers/environments/hiera_env_config/data1/second.json +3 -0
  238. data/spec/fixtures/unit/data_providers/environments/hiera_env_config/data1/single.yaml +2 -0
  239. data/spec/fixtures/unit/data_providers/environments/hiera_env_config/data2/single.yaml +2 -0
  240. data/spec/fixtures/unit/data_providers/environments/hiera_env_config/environment.conf +2 -0
  241. data/spec/fixtures/unit/data_providers/environments/hiera_env_config/hiera.yaml +18 -0
  242. data/spec/fixtures/unit/data_providers/environments/hiera_env_config/manifests/site.pp +5 -0
  243. data/spec/fixtures/unit/data_providers/environments/hiera_misc/data/common.yaml +46 -0
  244. data/spec/fixtures/unit/data_providers/environments/hiera_misc/environment.conf +2 -0
  245. data/spec/fixtures/unit/data_providers/environments/hiera_misc/manifests/site.pp +1 -0
  246. data/spec/fixtures/unit/data_providers/environments/hiera_misc/modules/one/data/common.yaml +30 -0
  247. data/spec/fixtures/unit/data_providers/environments/hiera_misc/modules/one/manifests/init.pp +13 -0
  248. data/spec/fixtures/unit/data_providers/environments/hiera_misc/modules/one/metadata.json +9 -0
  249. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/environment.conf +2 -0
  250. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/manifests/site.pp +1 -0
  251. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/data1/first.json +3 -0
  252. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/data1/name.yaml +1 -0
  253. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/data1/second.json +3 -0
  254. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/data1/single.yaml +2 -0
  255. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/data2/single.yaml +2 -0
  256. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/hiera.yaml +18 -0
  257. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/manifests/init.pp +5 -0
  258. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/metadata.json +9 -0
  259. data/spec/fixtures/unit/data_providers/environments/sample/modules/dataprovider/lib/puppet_x/helindbe/sample_env_data.rb +1 -0
  260. data/spec/fixtures/unit/data_providers/environments/sample/modules/dataprovider/lib/puppet_x/helindbe/sample_module_data.rb +1 -0
  261. data/spec/fixtures/unit/functions/lookup/environments/production/modules/hieraprovider/data/first.json +3 -0
  262. data/spec/fixtures/unit/functions/lookup/environments/production/modules/hieraprovider/hiera.yaml +8 -0
  263. data/spec/fixtures/unit/functions/lookup/environments/production/modules/hieraprovider/manifests/init.pp +5 -0
  264. data/spec/fixtures/unit/functions/lookup/environments/production/modules/hieraprovider/metadata.json +9 -0
  265. data/spec/fixtures/unit/functions/lookup/environments/production/modules/meta/lib/puppet/functions/meta/data.rb +9 -0
  266. data/spec/fixtures/unit/functions/lookup/environments/production/modules/meta/manifests/init.pp +3 -0
  267. data/spec/fixtures/unit/functions/lookup/environments/production/modules/meta/metadata.json +9 -0
  268. data/spec/fixtures/unit/functions/lookup/environments/production/modules/metawcp/lib/puppet/bindings/metawcp/default.rb +10 -0
  269. data/spec/fixtures/unit/functions/lookup/environments/production/modules/metawcp/lib/puppet_x/thallgren/sample_module_data.rb +23 -0
  270. data/spec/fixtures/unit/functions/lookup/environments/production/modules/metawcp/manifests/init.pp +3 -0
  271. data/spec/fixtures/unit/functions/lookup/environments/production/modules/metawcp/metadata.json +9 -0
  272. data/spec/fixtures/unit/provider/package/yum/yum-check-update-security.txt +184 -0
  273. data/spec/fixtures/vcr/cassettes/Puppet_Network_HTTP_Connection/when_handling_requests/_request_get/should_yield_to_the_block.yml +24 -0
  274. data/spec/fixtures/vcr/cassettes/Puppet_Network_HTTP_Connection/when_handling_requests/_request_head/should_yield_to_the_block.yml +24 -0
  275. data/spec/fixtures/vcr/cassettes/Puppet_Network_HTTP_Connection/when_handling_requests/_request_post/should_yield_to_the_block.yml +24 -0
  276. data/spec/integration/data_binding_spec.rb +229 -0
  277. data/spec/integration/file_bucket/file_spec.rb +2 -2
  278. data/spec/integration/parser/compiler_spec.rb +30 -24
  279. data/spec/integration/parser/resource_expressions_spec.rb +4 -4
  280. data/spec/integration/parser/undef_param_spec.rb +1 -1
  281. data/spec/integration/provider/package_spec.rb +3 -1
  282. data/spec/integration/resource/catalog_spec.rb +1 -1
  283. data/spec/integration/ssl/certificate_authority_spec.rb +0 -1
  284. data/spec/integration/ssl/certificate_request_spec.rb +0 -1
  285. data/spec/integration/ssl/certificate_revocation_list_spec.rb +0 -1
  286. data/spec/integration/ssl/host_spec.rb +0 -1
  287. data/spec/integration/type/package_spec.rb +2 -0
  288. data/spec/integration/util/rdoc/parser_spec.rb +1 -1
  289. data/spec/integration/util/windows/security_spec.rb +18 -0
  290. data/spec/lib/matchers/include_in_order.rb +2 -2
  291. data/spec/shared_behaviours/iterative_functions.rb +8 -8
  292. data/spec/spec_helper.rb +7 -0
  293. data/spec/unit/agent/locker_spec.rb +4 -4
  294. data/spec/unit/agent_spec.rb +0 -8
  295. data/spec/unit/application/agent_spec.rb +5 -0
  296. data/spec/unit/application/apply_spec.rb +9 -1
  297. data/spec/unit/application/filebucket_spec.rb +88 -2
  298. data/spec/unit/application/lookup_spec.rb +195 -0
  299. data/spec/unit/application/master_spec.rb +2 -2
  300. data/spec/unit/application_spec.rb +3 -3
  301. data/spec/unit/appmgmt_spec.rb +657 -0
  302. data/spec/unit/capability_spec.rb +414 -0
  303. data/spec/unit/configurer_spec.rb +7 -1
  304. data/spec/unit/context/trusted_information_spec.rb +24 -1
  305. data/spec/unit/daemon_spec.rb +18 -8
  306. data/spec/unit/data_providers/hiera_data_provider_spec.rb +201 -0
  307. data/spec/unit/environments_spec.rb +2 -0
  308. data/spec/unit/face/node_spec.rb +1 -1
  309. data/spec/unit/file_bucket/dipper_spec.rb +210 -1
  310. data/spec/unit/file_serving/configuration_spec.rb +1 -1
  311. data/spec/unit/file_system_spec.rb +20 -0
  312. data/spec/unit/functions/assert_type_spec.rb +5 -7
  313. data/spec/unit/functions/defined_spec.rb +2 -2
  314. data/spec/unit/functions/epp_spec.rb +2 -2
  315. data/spec/unit/functions/filter_spec.rb +18 -0
  316. data/spec/unit/functions/hiera_spec.rb +2 -2
  317. data/spec/unit/functions/lookup_spec.rb +200 -9
  318. data/spec/unit/functions/regsubst_spec.rb +17 -8
  319. data/spec/unit/functions/scanf_spec.rb +1 -1
  320. data/spec/unit/functions/split_spec.rb +2 -2
  321. data/spec/unit/functions/versioncmp_spec.rb +36 -0
  322. data/spec/unit/functions4_spec.rb +58 -72
  323. data/spec/unit/graph/sequential_prioritizer_spec.rb +1 -1
  324. data/spec/unit/indirector/catalog/compiler_spec.rb +28 -8
  325. data/spec/unit/indirector/catalog/static_compiler_spec.rb +38 -20
  326. data/spec/unit/indirector/data_binding/none_spec.rb +2 -2
  327. data/spec/unit/indirector/file_bucket_file/file_spec.rb +52 -1
  328. data/spec/unit/indirector/indirection_spec.rb +13 -2
  329. data/spec/unit/indirector/request_spec.rb +8 -8
  330. data/spec/unit/indirector/ssl_file_spec.rb +1 -1
  331. data/spec/unit/indirector/yaml_spec.rb +1 -1
  332. data/spec/unit/info_service_spec.rb +236 -0
  333. data/spec/unit/module_tool/application_spec.rb +1 -1
  334. data/spec/unit/module_tool/applications/builder_spec.rb +1 -1
  335. data/spec/unit/module_tool/metadata_spec.rb +31 -2
  336. data/spec/unit/network/authconfig_spec.rb +62 -32
  337. data/spec/unit/network/authorization_spec.rb +30 -2
  338. data/spec/unit/network/authstore_spec.rb +1 -1
  339. data/spec/unit/network/http/compression_spec.rb +1 -1
  340. data/spec/unit/network/http/connection_spec.rb +14 -19
  341. data/spec/unit/network/http/handler_spec.rb +0 -5
  342. data/spec/unit/network/rights_spec.rb +3 -3
  343. data/spec/unit/node_spec.rb +27 -0
  344. data/spec/unit/parser/ast/leaf_spec.rb +1 -1
  345. data/spec/unit/parser/compiler_spec.rb +86 -2
  346. data/spec/unit/parser/functions/create_resources_spec.rb +1 -1
  347. data/spec/unit/parser/resource_spec.rb +2 -20
  348. data/spec/unit/pops/binder/config/binder_config_spec.rb +1 -1
  349. data/spec/unit/pops/binder/injector_spec.rb +3 -3
  350. data/spec/unit/pops/evaluator/access_ops_spec.rb +13 -11
  351. data/spec/unit/pops/evaluator/basic_expressions_spec.rb +1 -2
  352. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +20 -11
  353. data/spec/unit/pops/evaluator/literal_evaluator_spec.rb +43 -0
  354. data/spec/unit/pops/label_provider_spec.rb +5 -1
  355. data/spec/unit/pops/parser/lexer2_spec.rb +39 -0
  356. data/spec/unit/pops/parser/parse_application_spec.rb +40 -0
  357. data/spec/unit/pops/parser/parse_basic_expressions_spec.rb +4 -0
  358. data/spec/unit/pops/parser/parse_capabilities_spec.rb +47 -0
  359. data/spec/unit/pops/parser/parse_site_spec.rb +38 -0
  360. data/spec/unit/pops/parser/parser_rspec_helper.rb +5 -0
  361. data/spec/unit/pops/parser/parser_spec.rb +18 -0
  362. data/spec/unit/pops/types/type_calculator_spec.rb +427 -444
  363. data/spec/unit/pops/types/type_factory_spec.rb +12 -12
  364. data/spec/unit/pops/types/type_parser_spec.rb +15 -12
  365. data/spec/unit/pops/validator/validator_spec.rb +68 -0
  366. data/spec/unit/property_spec.rb +1 -1
  367. data/spec/unit/provider/augeas/augeas_spec.rb +50 -0
  368. data/spec/unit/provider/group/directoryservice_spec.rb +33 -0
  369. data/spec/unit/provider/group/windows_adsi_spec.rb +3 -0
  370. data/spec/unit/provider/package/dnf_spec.rb +92 -0
  371. data/spec/unit/provider/package/gem_spec.rb +7 -0
  372. data/spec/unit/provider/package/nim_spec.rb +6 -6
  373. data/spec/unit/provider/package/rpm_spec.rb +25 -2
  374. data/spec/unit/provider/package/windows/package_spec.rb +41 -0
  375. data/spec/unit/provider/package/yum_spec.rb +35 -12
  376. data/spec/unit/provider/scheduled_task/win32_taskscheduler_spec.rb +10 -0
  377. data/spec/unit/provider/service/debian_spec.rb +28 -0
  378. data/spec/unit/provider/service/gentoo_spec.rb +1 -0
  379. data/spec/unit/provider/service/init_spec.rb +6 -0
  380. data/spec/unit/provider/service/launchd_spec.rb +85 -10
  381. data/spec/unit/provider/service/openrc_spec.rb +1 -0
  382. data/spec/unit/provider/service/rcng_spec.rb +41 -0
  383. data/spec/unit/provider/service/redhat_spec.rb +8 -1
  384. data/spec/unit/provider/service/smf_spec.rb +30 -5
  385. data/spec/unit/provider/service/src_spec.rb +20 -4
  386. data/spec/unit/provider/service/systemd_spec.rb +79 -29
  387. data/spec/unit/provider/ssh_authorized_key/parsed_spec.rb +1 -1
  388. data/spec/unit/provider/sshkey/parsed_spec.rb +23 -0
  389. data/spec/unit/provider/user/windows_adsi_spec.rb +2 -1
  390. data/spec/unit/provider/zone/solaris_spec.rb +19 -0
  391. data/spec/unit/reports_spec.rb +10 -0
  392. data/spec/unit/resource/capability_finder_spec.rb +56 -0
  393. data/spec/unit/resource/catalog_spec.rb +31 -8
  394. data/spec/unit/resource/type_collection_spec.rb +23 -2
  395. data/spec/unit/resource/type_spec.rb +1 -1
  396. data/spec/unit/resource_spec.rb +23 -5
  397. data/spec/unit/settings/file_setting_spec.rb +31 -0
  398. data/spec/unit/settings_spec.rb +91 -2
  399. data/spec/unit/ssl/certificate_authority/interface_spec.rb +4 -3
  400. data/spec/unit/ssl/certificate_authority_spec.rb +5 -3
  401. data/spec/unit/ssl/host_spec.rb +2 -2
  402. data/spec/unit/ssl/oids_spec.rb +8 -0
  403. data/spec/unit/transaction/additional_resource_generator_spec.rb +78 -5
  404. data/spec/unit/transaction/report_spec.rb +24 -1
  405. data/spec/unit/transaction_spec.rb +7 -0
  406. data/spec/unit/type/exec_spec.rb +16 -8
  407. data/spec/unit/type/host_spec.rb +4 -4
  408. data/spec/unit/type/package_spec.rb +1 -0
  409. data/spec/unit/type/tidy_spec.rb +4 -4
  410. data/spec/unit/type/user_spec.rb +14 -7
  411. data/spec/unit/type/vlan_spec.rb +1 -1
  412. data/spec/unit/type_spec.rb +1 -1
  413. data/spec/unit/util/ldap/generator_spec.rb +1 -1
  414. data/spec/unit/util/network_device/cisco/device_spec.rb +1 -1
  415. data/spec/unit/util/network_device/transport/ssh_spec.rb +1 -1
  416. data/spec/unit/util/network_device_spec.rb +1 -1
  417. data/spec/unit/util/storage_spec.rb +5 -1
  418. data/spec/unit/util/windows/adsi_spec.rb +13 -0
  419. data/spec/unit/util_spec.rb +21 -2
  420. metadata +173 -7
  421. data/lib/puppet/pops/evaluator/callable_mismatch_describer.rb +0 -175
  422. data/spec/integration/data_binding.rb +0 -104
@@ -6,6 +6,7 @@ require 'puppet/util/errors'
6
6
 
7
7
  require 'puppet/resource/type_collection_helper'
8
8
  require 'puppet/loaders'
9
+ require 'puppet/pops'
9
10
 
10
11
  # Maintain a graph of scopes, along with a bunch of data
11
12
  # about the individual catalog we're compiling.
@@ -16,8 +17,9 @@ class Puppet::Parser::Compiler
16
17
  include Puppet::Util::Errors
17
18
  include Puppet::Util::MethodHelper
18
19
  include Puppet::Resource::TypeCollectionHelper
20
+ include Puppet::Pops::Evaluator::Runtime3Support
19
21
 
20
- def self.compile(node)
22
+ def self.compile(node, code_id = nil)
21
23
  $env_module_directories = nil
22
24
  node.environment.check_for_reparse
23
25
 
@@ -31,7 +33,7 @@ class Puppet::Parser::Compiler
31
33
  raise(Puppet::Error, errmsg.join(' '))
32
34
  end
33
35
 
34
- new(node).compile {|resulting_catalog| resulting_catalog.to_resource }
36
+ new(node, :code_id => code_id).compile {|resulting_catalog| resulting_catalog.to_resource }
35
37
  rescue Puppet::ParseErrorWithIssue => detail
36
38
  detail.node = node.name
37
39
  Puppet.log_exception(detail)
@@ -65,6 +67,10 @@ class Puppet::Parser::Compiler
65
67
  #
66
68
  attr_accessor :boot_injector
67
69
 
70
+ # The id of code input to the compiler.
71
+ # @api private
72
+ attr_accessor :code_id
73
+
68
74
  # Add a collection to the global list.
69
75
  def_delegator :@collections, :<<, :add_collection
70
76
  def_delegator :@relationships, :<<, :add_relationship
@@ -82,6 +88,22 @@ class Puppet::Parser::Compiler
82
88
  end
83
89
 
84
90
  def add_resource(scope, resource)
91
+ type = resource.resource_type
92
+ if type.is_a?(Puppet::Resource::Type) && type.application?
93
+ @applications << resource
94
+ assert_app_in_site(scope, resource)
95
+ return
96
+ end
97
+
98
+ if @current_app
99
+ # We are in the process of pulling application components out that
100
+ # apply to this node
101
+ Puppet.notice "Check #{resource}"
102
+ return unless @current_components.any? do |comp|
103
+ comp.type == resource.type && comp.title == resource.title
104
+ end
105
+ end
106
+
85
107
  @resources << resource
86
108
 
87
109
  # Note that this will fail if the resource is not unique.
@@ -99,7 +121,22 @@ class Puppet::Parser::Compiler
99
121
  # This adds a resource to the class it lexically appears in in the
100
122
  # manifest.
101
123
  unless resource.class?
102
- return @catalog.add_edge(scope.resource, resource)
124
+ @catalog.add_edge(scope.resource, resource)
125
+ end
126
+ end
127
+
128
+ def assert_app_in_site(scope, resource)
129
+ if resource.type == 'App'
130
+ if scope.resource
131
+ # directly contained in a Site
132
+ return if scope.resource.type == 'Site'
133
+ # contained in something that may be contained in Site
134
+ upstream = @catalog.upstream_from_vertex(scope.resource)
135
+ if upstream
136
+ return if upstream.keys.map(&:type).include?('Site')
137
+ end
138
+ end
139
+ raise ArgumentError, "Application instances like '#{resource}' can only be contained within a Site"
103
140
  end
104
141
  end
105
142
 
@@ -111,6 +148,16 @@ class Puppet::Parser::Compiler
111
148
  @catalog.add_class(name) unless name == ""
112
149
  end
113
150
 
151
+ # Add a catalog validator that will run at some stage to this compiler
152
+ # @param catalog_validators [Class<CatalogValidator>] The catalog validator class to add
153
+ def add_catalog_validator(catalog_validators)
154
+ @catalog_validators << catalog_validators
155
+ nil
156
+ end
157
+
158
+ def add_catalog_validators
159
+ add_catalog_validator(CatalogValidator::RelationshipValidator)
160
+ end
114
161
 
115
162
  # Return a list of all of the defined classes.
116
163
  def_delegator :@catalog, :classes, :classlist
@@ -128,18 +175,37 @@ class Puppet::Parser::Compiler
128
175
 
129
176
  activate_binder
130
177
 
178
+ Puppet::Util::Profiler.profile("Compile: Evaluated capability mappings", [:compiler, :evaluate_capability_mappings]) { evaluate_capability_mappings }
179
+
131
180
  Puppet::Util::Profiler.profile("Compile: Evaluated main", [:compiler, :evaluate_main]) { evaluate_main }
132
181
 
182
+ Puppet::Util::Profiler.profile("Compile: Evaluated site", [:compiler, :evaluate_site]) { evaluate_site }
183
+
133
184
  Puppet::Util::Profiler.profile("Compile: Evaluated AST node", [:compiler, :evaluate_ast_node]) { evaluate_ast_node }
134
185
 
135
186
  Puppet::Util::Profiler.profile("Compile: Evaluated node classes", [:compiler, :evaluate_node_classes]) { evaluate_node_classes }
136
187
 
188
+ Puppet::Util::Profiler.profile("Compile: Evaluated application instances", [:compiler, :evaluate_applications]) { evaluate_applications }
189
+
190
+ # New capability mappings may have been defined when the site was evaluated
191
+ Puppet::Util::Profiler.profile("Compile: Evaluated site capability mappings", [:compiler, :evaluate_capability_mappings]) { evaluate_capability_mappings }
192
+
137
193
  Puppet::Util::Profiler.profile("Compile: Evaluated generators", [:compiler, :evaluate_generators]) { evaluate_generators }
138
194
 
195
+ Puppet::Util::Profiler.profile("Compile: Validate Catalog pre-finish", [:compiler, :validate_pre_finish]) do
196
+ validate_catalog(CatalogValidator::PRE_FINISH)
197
+ end
198
+
139
199
  Puppet::Util::Profiler.profile("Compile: Finished catalog", [:compiler, :finish_catalog]) { finish }
140
200
 
201
+ Puppet::Util::Profiler.profile("Compile: Prune", [:compiler, :prune_catalog]) { prune_catalog }
202
+
141
203
  fail_on_unevaluated
142
204
 
205
+ Puppet::Util::Profiler.profile("Compile: Validate Catalog final", [:compiler, :validate_final]) do
206
+ validate_catalog(CatalogValidator::FINAL)
207
+ end
208
+
143
209
  if block_given?
144
210
  yield @catalog
145
211
  else
@@ -148,6 +214,10 @@ class Puppet::Parser::Compiler
148
214
  end
149
215
  end
150
216
 
217
+ def validate_catalog(validation_stage)
218
+ @catalog_validators.select { |vclass| vclass.validation_stage?(validation_stage) }.each { |vclass| vclass.new(@catalog).validate }
219
+ end
220
+
151
221
  # Constructs the overrides for the context
152
222
  def context_overrides()
153
223
  {
@@ -188,6 +258,111 @@ class Puppet::Parser::Compiler
188
258
  evaluate_classes(classes_without_params, @node_scope || topscope)
189
259
  end
190
260
 
261
+ # Evaluates the site - the top container for an environment catalog
262
+ # The site contain behaves analogous to a node - for the environment catalog, node expressions are ignored
263
+ # as the result is cross node. The site expression serves as a container for everything that is across
264
+ # all nodes.
265
+ #
266
+ # @api private
267
+ #
268
+ def evaluate_site
269
+ # Has a site been defined? If not, do nothing but issue a warning.
270
+ #
271
+ site = known_resource_types.find_site()
272
+ unless site
273
+ on_empty_site()
274
+ return
275
+ end
276
+
277
+ # Create a resource to model this site and add it to catalog
278
+ resource = site.ensure_in_catalog(topscope)
279
+
280
+ # The site sets node scope to be able to shadow what is in top scope
281
+ @node_scope = topscope.class_scope(site)
282
+
283
+ # Evaluates the logic contain in the site expression
284
+ resource.evaluate
285
+ end
286
+
287
+ # @api private
288
+ def on_empty_site
289
+ # do nothing
290
+ end
291
+
292
+ # Prunes the catalog by dropping all resources are contained under the Site (if a site expression is used).
293
+ # As a consequence all edges to/from dropped resources are also dropped.
294
+ # Once the pruning is performed, this compiler returns the pruned list when calling the #resources method.
295
+ # The pruning does not alter the order of resources in the resources list.
296
+ #
297
+ # @api private
298
+ def prune_catalog
299
+ prune_node_catalog
300
+ end
301
+
302
+ def prune_node_catalog
303
+ # Everything under Site[site] should be pruned as that is for the environment catalog, not a node
304
+ #
305
+ the_site_resource = @catalog.resource('Site', 'site')
306
+
307
+ if the_site_resource
308
+ # Get downstream vertexes returns a hash where the keys are the resources and values nesting level
309
+ to_be_removed = @catalog.downstream_from_vertex(the_site_resource).keys
310
+
311
+ # Drop the Site[site] resource if it has no content
312
+ if to_be_removed.empty?
313
+ to_be_removed << the_site_resource
314
+ end
315
+ else
316
+ to_be_removed = []
317
+ end
318
+
319
+ # keep_from_site is populated with any App resources.
320
+ application_resources = @resources.select {|r| r.type == 'App' }
321
+ # keep all applications plus what is directly referenced from applications
322
+ keep_from_site = application_resources
323
+ keep_from_site += application_resources.map {|app| @catalog.direct_dependents_of(app) }.flatten
324
+
325
+ to_be_removed -= keep_from_site
326
+ @catalog.remove_resource(*to_be_removed)
327
+ # set the pruned result
328
+ @resources = @catalog.resources
329
+ end
330
+
331
+ # @api private
332
+ def evaluate_applications
333
+ @applications.each do |app|
334
+ components = []
335
+ mapping = app.parameters[:nodes] ? app.parameters[:nodes].value : {}
336
+ raise Puppet::Error, "Invalid node mapping in #{app.ref}: Mapping must be a hash" unless mapping.is_a?(Hash)
337
+ all_mapped = Set.new
338
+ mapping.each do |k,v|
339
+ raise Puppet::Error, "Invalid node mapping in #{app.ref}: Key #{k} is not a Node" unless k.is_a?(Puppet::Resource) && k.type == 'Node'
340
+ v = [v] unless v.is_a?(Array)
341
+ v.each do |res|
342
+ raise Puppet::Error, "Invalid node mapping in #{app.ref}: Value #{res} is not a resource" unless res.is_a?(Puppet::Resource)
343
+ raise Puppet::Error, "Application #{app.ref} maps component #{res} to multiple nodes" if all_mapped.add?(res.ref).nil?
344
+ components << res if k.title == node.name
345
+ end
346
+ end
347
+ begin
348
+ @current_app = app
349
+ @current_components = components
350
+ unless @current_components.empty?
351
+ Puppet.notice "EVAL APP #{app} #{components.inspect}"
352
+ # Add the app itself since components mapped to the current node
353
+ # will have a containment edge for it
354
+ # @todo lutter 2015-01-28: the node mapping winds up in the
355
+ # catalog, but probably shouldn't
356
+ @catalog.add_resource(@current_app)
357
+ @current_app.evaluate
358
+ end
359
+ ensure
360
+ @current_app = nil
361
+ @current_components = nil
362
+ end
363
+ end
364
+ end
365
+
191
366
  # Evaluates each specified class in turn. If there are any classes that
192
367
  # can't be found, an error is raised. This method really just creates resource objects
193
368
  # that point back to the classes, and then the resources are themselves
@@ -203,6 +378,12 @@ class Puppet::Parser::Compiler
203
378
  classes = classes.keys
204
379
  end
205
380
 
381
+ unless @current_components.nil?
382
+ classes = classes.select do |title|
383
+ @current_components.any? { |comp| comp.class? && comp.title == title }
384
+ end
385
+ end
386
+
206
387
  hostclasses = classes.collect do |name|
207
388
  scope.find_hostclass(name) or raise Puppet::Error, "Could not find class #{name} for #{node.name}"
208
389
  end
@@ -232,9 +413,20 @@ class Puppet::Parser::Compiler
232
413
  def_delegator :@catalog, :resource, :findresource
233
414
 
234
415
  def initialize(node, options = {})
235
- @node = node
416
+ @node = sanitize_node(node)
417
+ # Array of resources representing all application instances we've found
418
+ @applications = []
419
+ # We use @current_app and @current_components to signal to the
420
+ # evaluator that we are in the middle of evaluating an
421
+ # application. They are set in evaluate_applications to the application
422
+ # instance, resp. to an array of the components of that application
423
+ # that is mapped to the current node. They are only non-nil when we are
424
+ # in the middle of executing evaluate_applications
425
+ @current_app = nil
426
+ @current_components = nil
236
427
  set_options(options)
237
428
  initvars
429
+ add_catalog_validators
238
430
  end
239
431
 
240
432
  # Create a new scope, with either a specified parent scope or
@@ -315,6 +507,38 @@ class Puppet::Parser::Compiler
315
507
  [already_included, newly_included]
316
508
  end
317
509
 
510
+ def evaluate_capability_mappings
511
+ krt = known_resource_types
512
+ krt.capability_mappings.each_value do |capability_mapping|
513
+ args = capability_mapping.arguments
514
+ component_ref = args['component']
515
+ kind = args['kind']
516
+
517
+ # That component_ref is either a QNAME or a Class['literal'|QREF] is asserted during validation so no
518
+ # need to check that here
519
+ if component_ref.is_a?(Puppet::Pops::Model::QualifiedName)
520
+ component_name = component_ref.value
521
+ component_type = 'type'
522
+ component = krt.find_definition(component_name)
523
+ else
524
+ component_name = component_ref.keys[0].value
525
+ component_type = 'class'
526
+ component = krt.find_hostclass(component_name)
527
+ end
528
+ if component.nil?
529
+ raise Puppet::ParseError, "Capability mapping error: #{kind} clause references nonexistent #{component_type} #{component_name}"
530
+ end
531
+
532
+ blueprint = args['blueprint']
533
+ if kind == 'produces'
534
+ component.add_produces(blueprint)
535
+ else
536
+ component.add_consumes(blueprint)
537
+ end
538
+ end
539
+ krt.capability_mappings.clear # No longer needed
540
+ end
541
+
318
542
  # If ast nodes are enabled, then see if we can find and evaluate one.
319
543
  def evaluate_ast_node
320
544
  return unless ast_nodes?
@@ -326,7 +550,7 @@ class Puppet::Parser::Compiler
326
550
  end
327
551
 
328
552
  unless (astnode ||= known_resource_types.node("default"))
329
- raise Puppet::ParseError, "Could not find default node or by name with '#{node.names.join(", ")}'"
553
+ raise Puppet::ParseError, "Could not find node statement with name 'default' or '#{node.names.join(", ")}'"
330
554
  end
331
555
 
332
556
  # Create a resource to model this node, and then add it to the list
@@ -363,11 +587,16 @@ class Puppet::Parser::Compiler
363
587
  def evaluate_definitions
364
588
  exceptwrap do
365
589
  Puppet::Util::Profiler.profile("Evaluated definitions", [:compiler, :evaluate_definitions]) do
366
- !unevaluated_resources.each do |resource|
367
- Puppet::Util::Profiler.profile("Evaluated resource #{resource}", [:compiler, :evaluate_resource, resource]) do
590
+ urs = unevaluated_resources.each do |resource|
591
+ begin
368
592
  resource.evaluate
593
+ rescue Puppet::Error => e
594
+ # PuppetError has the ability to wrap an exception, if so, use the wrapped exception's
595
+ # call stack instead
596
+ fail(Puppet::Pops::Issues::RUNTIME_ERROR, resource, {:detail => e.message}, e.original || e)
369
597
  end
370
- end.empty?
598
+ end
599
+ !urs.empty?
371
600
  end
372
601
  end
373
602
  end
@@ -422,8 +651,7 @@ class Puppet::Parser::Compiler
422
651
  remaining = @resource_overrides.values.flatten.collect(&:ref)
423
652
 
424
653
  if !remaining.empty?
425
- fail Puppet::ParseError,
426
- "Could not find resource(s) #{remaining.join(', ')} for overriding"
654
+ raise Puppet::ParseError, "Could not find resource(s) #{remaining.join(', ')} for overriding"
427
655
  end
428
656
  end
429
657
 
@@ -517,7 +745,7 @@ class Puppet::Parser::Compiler
517
745
  @relationships = []
518
746
 
519
747
  # For maintaining the relationship between scopes and their resources.
520
- @catalog = Puppet::Resource::Catalog.new(@node.name, @node.environment)
748
+ @catalog = Puppet::Resource::Catalog.new(@node.name, @node.environment, @code_id)
521
749
 
522
750
  # MOVED HERE - SCOPE IS NEEDED (MOVE-SCOPE)
523
751
  # Create the initial scope, it is needed early
@@ -549,6 +777,66 @@ class Puppet::Parser::Compiler
549
777
  else
550
778
  @catalog.add_class(*@node.classes)
551
779
  end
780
+
781
+ @catalog_validators = []
782
+ end
783
+
784
+ def sanitize_node(node)
785
+ # Resurrect "trusted information" that comes from node/fact terminus.
786
+ # The current way this is done in puppet db (currently the only one)
787
+ # is to store the node parameter 'trusted' as a hash of the trusted information.
788
+ #
789
+ # Thus here there are two main cases:
790
+ # 1. This terminus was used in a real agent call (only meaningful if someone curls the request as it would
791
+ # fail since the result is a hash of two catalogs).
792
+ # 2 It is a command line call with a given node that use a terminus that:
793
+ # 2.1 does not include a 'trusted' fact - use local from node trusted information
794
+ # 2.2 has a 'trusted' fact - this in turn could be
795
+ # 2.2.1 puppet db having stored trusted node data as a fact (not a great design)
796
+ # 2.2.2 some other terminus having stored a fact called "trusted" (most likely that would have failed earlier, but could
797
+ # be spoofed).
798
+ #
799
+ # For the reasons above, the resurection of trusted node data with authenticated => true is only performed
800
+ # if user is running as root, else it is resurrected as unauthenticated.
801
+ #
802
+ trusted_param = node.parameters['trusted']
803
+ if trusted_param
804
+ # Blows up if it is a parameter as it will be set as $trusted by the compiler as if it was a variable
805
+ node.parameters.delete('trusted')
806
+ if trusted_param.is_a?(Hash) && %w{authenticated certname extensions}.all? {|key| trusted_param.has_key?(key) }
807
+ # looks like a hash of trusted data - resurrect it
808
+ # Allow root to trust the authenticated information if option --trusted is given
809
+ if !Puppet.features.root?
810
+ # Set as not trusted - but keep the information
811
+ trusted_param['authenticated'] = false
812
+ end
813
+ else
814
+ # trusted is some kind of garbage, do not resurrect
815
+ trusted_param = nil
816
+ end
817
+ else
818
+ # trusted may be boolean false if set as a fact by someone
819
+ trusted_param = nil
820
+ end
821
+
822
+ # The options for node.trusted_data in priority order are:
823
+ # 1) node came with trusted_data so use that
824
+ # 2) else if there is :trusted_information in the puppet context
825
+ # 3) else if the node provided a 'trusted' parameter (parsed out above)
826
+ # 4) last, fallback to local node trusted information
827
+ #
828
+ # Note that trusted_data should be a hash, but (2) and (4) are not
829
+ # hashes, so we to_h at the end
830
+ if !node.trusted_data
831
+ trusted = Puppet.lookup(:trusted_information) do
832
+ trusted_param || Puppet::Context::TrustedInformation.local(node)
833
+ end
834
+
835
+ # Ruby 1.9.3 can't apply to_h to a hash, so check first
836
+ node.trusted_data = trusted.is_a?(Hash) ? trusted : trusted.to_h
837
+ end
838
+
839
+ node
552
840
  end
553
841
 
554
842
  # Set the node's parameters into the top-scope as variables.
@@ -610,5 +898,5 @@ class Puppet::Parser::Compiler
610
898
  unless activate_binder()
611
899
  raise Puppet::DevError, "The Puppet Binder was not activated"
612
900
  end
613
- end
901
+ end # Creates a diagnostic producer
614
902
  end
@@ -0,0 +1,165 @@
1
+ require 'puppet/parser/compiler'
2
+
3
+ class Puppet::Parser::EnvironmentCompiler < Puppet::Parser::Compiler
4
+ def self.compile(env)
5
+ begin
6
+ $env_module_directories = nil
7
+ env.check_for_reparse
8
+
9
+ node = Puppet::Node.new(env)
10
+ node.environment = env
11
+ new(node).compile
12
+ rescue => detail
13
+ message = "#{detail} in environment #{env.name}"
14
+ Puppet.log_exception(detail, message)
15
+ raise Puppet::Error, message, detail.backtrace
16
+ end
17
+ end
18
+
19
+ def add_catalog_validators
20
+ super
21
+ add_catalog_validator(CatalogValidator::SiteValidator)
22
+ add_catalog_validator(CatalogValidator::EnvironmentRelationshipValidator)
23
+ end
24
+
25
+ def compile
26
+ Puppet.override(@context_overrides, "For compiling environment catalog #{environment.name}") do
27
+ @catalog.environment_instance = environment
28
+
29
+ Puppet::Util::Profiler.profile("Env Compile: Created settings scope", [:compiler, :create_settings_scope]) { create_settings_scope }
30
+
31
+ activate_binder
32
+
33
+ Puppet::Util::Profiler.profile("Env Compile: Evaluated main", [:compiler, :evaluate_main]) { evaluate_main }
34
+
35
+ Puppet::Util::Profiler.profile("Env Compile: Evaluated site", [:compiler, :evaluate_site]) { evaluate_site }
36
+
37
+ Puppet::Util::Profiler.profile("Env Compile: Evaluated application instances", [:compiler, :evaluate_applications]) { evaluate_applications }
38
+
39
+ Puppet::Util::Profiler.profile("Env Compile: Prune", [:compiler, :prune_catalog]) { prune_catalog }
40
+
41
+ Puppet::Util::Profiler.profile("Env Compile: Validate Catalog pre-finish", [:compiler, :validate_pre_finish]) do
42
+ validate_catalog(CatalogValidator::PRE_FINISH)
43
+ end
44
+
45
+ Puppet::Util::Profiler.profile("Env Compile: Finished catalog", [:compiler, :finish_catalog]) { finish }
46
+
47
+ fail_on_unevaluated
48
+
49
+ Puppet::Util::Profiler.profile("Env Compile: Validate Catalog final", [:compiler, :validate_final]) do
50
+ validate_catalog(CatalogValidator::FINAL)
51
+ end
52
+
53
+ if block_given?
54
+ yield @catalog
55
+ else
56
+ @catalog
57
+ end
58
+ end
59
+ end
60
+
61
+ # @api private
62
+ def prune_catalog
63
+ prune_env_catalog
64
+ end
65
+
66
+ # Prunes the catalog by dropping all resources that are not contained under the Site (if a site expression is used).
67
+ # As a consequence all edges to/from dropped resources are also dropped.
68
+ # Once the pruning is performed, this compiler returns the pruned list when calling the #resources method.
69
+ # The pruning does not alter the order of resources in the resources list.
70
+ #
71
+ def prune_env_catalog
72
+ # Everything under Class[main], that is not under (inclusive of) Site[site] should be pruned as those resources
73
+ # are intended for nodes in a node catalog.
74
+ #
75
+ the_main_class_resource = @catalog.resource('Class', '')
76
+ the_site_resource = @catalog.resource('Site', 'site')
77
+
78
+ # Get downstream vertexes returns a hash where the keys are the resources and values nesting level
79
+ rooted_in_main = @catalog.downstream_from_vertex(the_main_class_resource).keys
80
+
81
+ to_be_removed =
82
+ if the_site_resource
83
+ keep_from_site = @catalog.downstream_from_vertex(the_site_resource).keys
84
+ keep_from_site << the_site_resource
85
+ rooted_in_main - keep_from_site
86
+ else
87
+ rooted_in_main
88
+ end
89
+
90
+ @catalog.remove_resource(*to_be_removed)
91
+ # The compiler keeps a list of added resources, this shadows that list with the now pruned result
92
+ @pruned_resources = @catalog.resources
93
+ end
94
+
95
+ def add_resource(scope, resource)
96
+ @resources << resource
97
+ @catalog.add_resource(resource)
98
+
99
+ if !resource.class? && resource[:stage]
100
+ raise ArgumentError, "Only classes can set 'stage'; normal resources like #{resource} cannot change run stage"
101
+ end
102
+
103
+ # Stages should not be inside of classes. They are always a
104
+ # top-level container, regardless of where they appear in the
105
+ # manifest.
106
+ return if resource.stage?
107
+
108
+ # This adds a resource to the class it lexically appears in in the
109
+ # manifest.
110
+ unless resource.class?
111
+ @catalog.add_edge(scope.resource, resource)
112
+ end
113
+ resource.mark_unevaluated_consumer if is_capability_consumer?(resource)
114
+ assert_app_in_site(scope, resource)
115
+ end
116
+
117
+ def evaluate_ast_node()
118
+ # Do nothing, the environment catalog is not built for a particular node.
119
+ end
120
+
121
+ def on_empty_site
122
+ Puppet.warning("Environment Compiler: Could not find a site definition to evaluate")
123
+ end
124
+
125
+ def evaluate_applications
126
+ exceptwrap do
127
+ resources.select { |resource| type = resource.resource_type; type.is_a?(Puppet::Resource::Type) && type.application? }.each do |resource|
128
+ Puppet::Util::Profiler.profile("Evaluated application #{resource}", [:compiler, :evaluate_resource, resource]) do
129
+ resource.evaluate
130
+ end
131
+ end
132
+ end
133
+ end
134
+
135
+ def evaluate_classes(titles, scope, lazy)
136
+ # Always lazy in an Environment compilation
137
+ super(titles, scope, true)
138
+ end
139
+
140
+ # Overrides the regular compiler to be able to return the list of resources after a prune
141
+ # has taken place in the graph representation. Before a prune, the list is the same as in the regular
142
+ # compiler
143
+ #
144
+ def resources
145
+ @pruned_resources || super
146
+ end
147
+
148
+ def is_capability?(value)
149
+ if value.is_a?(Array)
150
+ value.find { |ev| is_capability?(ev) }
151
+ elsif value.is_a?(Puppet::Resource)
152
+ rstype = value.resource_type
153
+ rstype.nil? ? false : rstype.is_capability?
154
+ else
155
+ false
156
+ end
157
+ end
158
+ private :is_capability?
159
+
160
+ def is_capability_consumer?(resource)
161
+ resource.eachparam { |param| return true if (param.name == :consume || param.name == :require) && is_capability?(param.value) }
162
+ false
163
+ end
164
+ private :is_capability_consumer?
165
+ end
@@ -2,29 +2,59 @@ Puppet::Parser::Functions::newfunction(
2
2
  :assert_type,
3
3
  :type => :rvalue,
4
4
  :arity => -3,
5
- :doc => "Returns the given value if it is an instance of the given type, and raises an error otherwise.
6
- Optionally, if a block is given (accepting two parameters), it will be called instead of raising
7
- an error. This to enable giving the user richer feedback, or to supply a default value.
5
+ :doc => <<DOC
6
+ Returns the given value if it is of the given
7
+ [data type](https://docs.puppetlabs.com/puppet/latest/reference/lang_data.html), or
8
+ otherwise either raises an error or executes an optional two-parameter
9
+ [lambda](https://docs.puppetlabs.com/puppet/latest/reference/lang_lambdas.html).
8
10
 
9
- Example: assert that `$b` is a non empty `String` and assign to `$a`:
11
+ The function takes two mandatory arguments, in this order:
10
12
 
11
- $a = assert_type(String[1], $b)
13
+ 1. The expected data type.
14
+ 2. A value to compare against the expected data type.
12
15
 
13
- Example using custom error message:
16
+ **Example**: Using `assert_type`
14
17
 
15
- $a = assert_type(String[1], $b) |$expected, $actual| {
16
- fail('The name cannot be empty')
17
- }
18
+ ~~~ puppet
19
+ $raw_username = 'Amy Berry'
18
20
 
19
- Example, using a warning and a default:
21
+ # Assert that $raw_username is a non-empty string and assign it to $valid_username.
22
+ $valid_username = assert_type(String[1], $raw_username)
20
23
 
21
- $a = assert_type(String[1], $b) |$expected, $actual| {
22
- warning('Name is empty, using default')
23
- 'anonymous'
24
- }
24
+ # $valid_username contains "Amy Berry".
25
+ # If $raw_username was an empty string or a different data type, the Puppet run would
26
+ # fail with an "Expected type does not match actual" error.
27
+ ~~~
28
+
29
+ You can use an optional lambda to provide enhanced feedback. The lambda takes two
30
+ mandatory parameters, in this order:
31
+
32
+ 1. The expected data type as described in the function's first argument.
33
+ 2. The actual data type of the value.
34
+
35
+ **Example**: Using `assert_type` with a warning and default value
36
+
37
+ ~~~ puppet
38
+ $raw_username = 'Amy Berry'
39
+
40
+ # Assert that $raw_username is a non-empty string and assign it to $valid_username.
41
+ # If it isn't, output a warning describing the problem and use a default value.
42
+ $valid_username = assert_type(String[1], $raw_username) |$expected, $actual| {
43
+ warning( "The username should be \'${expected}\', not \'${actual}\'. Using 'anonymous'." )
44
+ 'anonymous'
45
+ }
46
+
47
+ # $valid_username contains "Amy Berry".
48
+ # If $raw_username was an empty string, the Puppet run would set $valid_username to
49
+ # "anonymous" and output a warning: "The username should be 'String[1, default]', not
50
+ # 'String[0, 0]'. Using 'anonymous'."
51
+ ~~~
52
+
53
+ For more information about data types, see the
54
+ [documentation](https://docs.puppetlabs.com/puppet/latest/reference/lang_data.html).
25
55
 
26
- See the documentation for 'The Puppet Type System' for more information about types.
27
56
  - Since 4.0.0
28
- ") do |args|
57
+ DOC
58
+ ) do |args|
29
59
  function_fail(["assert_type() is only available when parser/evaluator future is in effect"])
30
60
  end