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

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

Potentially problematic release.


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

Files changed (337) hide show
  1. data/Gemfile +3 -0
  2. data/README.md +1 -1
  3. data/ext/debian/puppet.init +0 -1
  4. data/ext/debian/puppet.logrotate +14 -5
  5. data/ext/osx/puppet.plist +0 -2
  6. data/ext/redhat/client.init +13 -5
  7. data/ext/redhat/logrotate +15 -3
  8. data/ext/redhat/puppet.spec.erb +5 -1
  9. data/ext/redhat/server.init +1 -1
  10. data/ext/systemd/puppet.service +1 -0
  11. data/lib/puppet.rb +12 -0
  12. data/lib/puppet/agent.rb +4 -4
  13. data/lib/puppet/agent/locker.rb +11 -2
  14. data/lib/puppet/application/agent.rb +5 -1
  15. data/lib/puppet/application/apply.rb +4 -0
  16. data/lib/puppet/application/filebucket.rb +78 -4
  17. data/lib/puppet/application/lookup.rb +356 -0
  18. data/lib/puppet/application/master.rb +3 -0
  19. data/lib/puppet/configurer.rb +9 -5
  20. data/lib/puppet/context.rb +16 -1
  21. data/lib/puppet/context/trusted_information.rb +21 -1
  22. data/lib/puppet/daemon.rb +17 -13
  23. data/lib/puppet/data_binding.rb +4 -2
  24. data/lib/puppet/data_providers.rb +12 -13
  25. data/lib/puppet/data_providers/data_adapter.rb +7 -68
  26. data/lib/puppet/data_providers/data_function_support.rb +5 -26
  27. data/lib/puppet/data_providers/function_env_data_provider.rb +0 -10
  28. data/lib/puppet/data_providers/function_module_data_provider.rb +0 -22
  29. data/lib/puppet/data_providers/hiera_config.rb +106 -0
  30. data/lib/puppet/data_providers/hiera_env_data_provider.rb +18 -0
  31. data/lib/puppet/data_providers/hiera_interpolate.rb +97 -0
  32. data/lib/puppet/data_providers/hiera_module_data_provider.rb +23 -0
  33. data/lib/puppet/data_providers/hiera_support.rb +37 -0
  34. data/lib/puppet/data_providers/json_data_provider_factory.rb +31 -0
  35. data/lib/puppet/data_providers/lookup_adapter.rb +200 -0
  36. data/lib/puppet/data_providers/yaml_data_provider_factory.rb +32 -0
  37. data/lib/puppet/defaults.rb +12 -2
  38. data/lib/puppet/error.rb +4 -0
  39. data/lib/puppet/face/module/changes.rb +2 -1
  40. data/lib/puppet/feature/cfacter.rb +1 -0
  41. data/lib/puppet/file_bucket/dipper.rb +58 -2
  42. data/lib/puppet/functions.rb +2 -4
  43. data/lib/puppet/functions/assert_type.rb +48 -12
  44. data/lib/puppet/functions/defined.rb +79 -48
  45. data/lib/puppet/functions/each.rb +85 -27
  46. data/lib/puppet/functions/filter.rb +58 -23
  47. data/lib/puppet/functions/hiera.rb +76 -3
  48. data/lib/puppet/functions/hiera_array.rb +65 -3
  49. data/lib/puppet/functions/hiera_hash.rb +74 -2
  50. data/lib/puppet/functions/hiera_include.rb +75 -2
  51. data/lib/puppet/functions/lookup.rb +19 -17
  52. data/lib/puppet/functions/map.rb +56 -21
  53. data/lib/puppet/functions/match.rb +29 -12
  54. data/lib/puppet/functions/reduce.rb +95 -58
  55. data/lib/puppet/functions/versioncmp.rb +36 -0
  56. data/lib/puppet/functions/with.rb +15 -7
  57. data/lib/puppet/indirector/catalog/compiler.rb +3 -3
  58. data/lib/puppet/indirector/catalog/static_compiler.rb +46 -30
  59. data/lib/puppet/indirector/data_binding/none.rb +4 -1
  60. data/lib/puppet/indirector/file_bucket_file/file.rb +58 -1
  61. data/lib/puppet/indirector/hiera.rb +4 -0
  62. data/lib/puppet/indirector/json.rb +1 -1
  63. data/lib/puppet/indirector/msgpack.rb +1 -1
  64. data/lib/puppet/indirector/request.rb +7 -8
  65. data/lib/puppet/indirector/resource_type/parser.rb +5 -3
  66. data/lib/puppet/info_service.rb +7 -0
  67. data/lib/puppet/info_service/class_information_service.rb +111 -0
  68. data/lib/puppet/module_tool/metadata.rb +32 -9
  69. data/lib/puppet/module_tool/skeleton/templates/generator/README.md.erb +42 -38
  70. data/lib/puppet/network/authconfig.rb +21 -1
  71. data/lib/puppet/network/authorization.rb +8 -1
  72. data/lib/puppet/network/http/api/master/v3.rb +7 -1
  73. data/lib/puppet/network/http/api/master/v3/environment.rb +59 -0
  74. data/lib/puppet/node/environment.rb +9 -2
  75. data/lib/puppet/parser.rb +3 -0
  76. data/lib/puppet/parser/ast/pops_bridge.rb +39 -1
  77. data/lib/puppet/parser/compiler.rb +302 -12
  78. data/lib/puppet/parser/compiler/catalog_validator.rb +33 -0
  79. data/lib/puppet/parser/compiler/catalog_validator/env_relationship_validator.rb +64 -0
  80. data/lib/puppet/parser/compiler/catalog_validator/relationship_validator.rb +38 -0
  81. data/lib/puppet/parser/compiler/catalog_validator/site_validator.rb +20 -0
  82. data/lib/puppet/parser/environment_compiler.rb +165 -0
  83. data/lib/puppet/parser/functions/assert_type.rb +46 -16
  84. data/lib/puppet/parser/functions/defined.rb +105 -68
  85. data/lib/puppet/parser/functions/each.rb +85 -27
  86. data/lib/puppet/parser/functions/filter.rb +59 -23
  87. data/lib/puppet/parser/functions/hiera.rb +83 -27
  88. data/lib/puppet/parser/functions/hiera_array.rb +71 -28
  89. data/lib/puppet/parser/functions/hiera_hash.rb +81 -30
  90. data/lib/puppet/parser/functions/hiera_include.rb +81 -40
  91. data/lib/puppet/parser/functions/map.rb +55 -20
  92. data/lib/puppet/parser/functions/match.rb +27 -12
  93. data/lib/puppet/parser/functions/reduce.rb +97 -60
  94. data/lib/puppet/parser/functions/with.rb +16 -8
  95. data/lib/puppet/parser/resource.rb +98 -19
  96. data/lib/puppet/plugins/configuration.rb +3 -2
  97. data/lib/puppet/plugins/data_providers.rb +12 -60
  98. data/lib/puppet/plugins/data_providers/data_provider.rb +283 -0
  99. data/lib/puppet/plugins/data_providers/registry.rb +84 -0
  100. data/lib/puppet/pops.rb +19 -17
  101. data/lib/puppet/pops/adapters.rb +12 -0
  102. data/lib/puppet/pops/binder/binder.rb +2 -2
  103. data/lib/puppet/pops/binder/bindings_checker.rb +1 -1
  104. data/lib/puppet/pops/binder/bindings_label_provider.rb +3 -1
  105. data/lib/puppet/pops/binder/bindings_loader.rb +6 -2
  106. data/lib/puppet/pops/binder/bindings_model_meta.rb +2 -2
  107. data/lib/puppet/pops/binder/config/binder_config.rb +1 -1
  108. data/lib/puppet/pops/binder/injector.rb +4 -4
  109. data/lib/puppet/pops/binder/key_factory.rb +3 -9
  110. data/lib/puppet/pops/binder/scheme_handler/module_scheme.rb +68 -9
  111. data/lib/puppet/pops/evaluator/access_operator.rb +27 -60
  112. data/lib/puppet/pops/evaluator/closure.rb +8 -8
  113. data/lib/puppet/pops/evaluator/collectors/abstract_collector.rb +1 -1
  114. data/lib/puppet/pops/evaluator/evaluator_impl.rb +5 -5
  115. data/lib/puppet/pops/evaluator/literal_evaluator.rb +87 -0
  116. data/lib/puppet/pops/evaluator/relationship_operator.rb +7 -1
  117. data/lib/puppet/pops/functions/dispatcher.rb +3 -3
  118. data/lib/puppet/pops/issues.rb +1 -1
  119. data/lib/puppet/pops/label_provider.rb +1 -1
  120. data/lib/puppet/pops/lookup.rb +25 -47
  121. data/lib/puppet/pops/lookup/explainer.rb +402 -0
  122. data/lib/puppet/pops/lookup/invocation.rb +117 -0
  123. data/lib/puppet/pops/merge_strategy.rb +73 -5
  124. data/lib/puppet/pops/model/factory.rb +34 -0
  125. data/lib/puppet/pops/model/model_label_provider.rb +10 -1
  126. data/lib/puppet/pops/model/model_meta.rb +15 -0
  127. data/lib/puppet/pops/model/model_tree_dumper.rb +18 -0
  128. data/lib/puppet/pops/parser/code_merger.rb +13 -1
  129. data/lib/puppet/pops/parser/egrammar.ra +56 -3
  130. data/lib/puppet/pops/parser/eparser.rb +1549 -1352
  131. data/lib/puppet/pops/parser/lexer2.rb +31 -6
  132. data/lib/puppet/pops/parser/locator.rb +1 -1
  133. data/lib/puppet/pops/parser/parser_support.rb +25 -13
  134. data/lib/puppet/pops/types/enumeration.rb +1 -2
  135. data/lib/puppet/pops/types/type_asserter.rb +16 -15
  136. data/lib/puppet/pops/types/type_assertion_error.rb +1 -0
  137. data/lib/puppet/pops/types/type_calculator.rb +171 -1020
  138. data/lib/puppet/pops/types/type_factory.rb +87 -148
  139. data/lib/puppet/pops/types/type_mismatch_describer.rb +743 -0
  140. data/lib/puppet/pops/types/type_parser.rb +116 -127
  141. data/lib/puppet/pops/types/types.rb +1394 -255
  142. data/lib/puppet/pops/types/types_meta.rb +0 -234
  143. data/lib/puppet/pops/validation.rb +7 -2
  144. data/lib/puppet/pops/validation/checker4_0.rb +28 -0
  145. data/lib/puppet/provider/augeas/augeas.rb +50 -0
  146. data/lib/puppet/provider/group/directoryservice.rb +10 -0
  147. data/lib/puppet/provider/package/dnf.rb +41 -0
  148. data/lib/puppet/provider/package/gem.rb +7 -2
  149. data/lib/puppet/provider/package/rpm.rb +1 -0
  150. data/lib/puppet/provider/package/windows/exe_package.rb +10 -8
  151. data/lib/puppet/provider/package/windows/msi_package.rb +4 -3
  152. data/lib/puppet/provider/package/windows/package.rb +9 -1
  153. data/lib/puppet/provider/package/yum.rb +14 -9
  154. data/lib/puppet/provider/service/bsd.rb +1 -1
  155. data/lib/puppet/provider/service/debian.rb +21 -0
  156. data/lib/puppet/provider/service/init.rb +6 -0
  157. data/lib/puppet/provider/service/rcng.rb +51 -0
  158. data/lib/puppet/provider/service/redhat.rb +2 -1
  159. data/lib/puppet/provider/service/smf.rb +43 -2
  160. data/lib/puppet/provider/service/src.rb +27 -0
  161. data/lib/puppet/provider/service/systemd.rb +15 -3
  162. data/lib/puppet/provider/sshkey/parsed.rb +19 -9
  163. data/lib/puppet/reference/report.rb +9 -12
  164. data/lib/puppet/reports.rb +5 -1
  165. data/lib/puppet/resource.rb +50 -73
  166. data/lib/puppet/resource/capability_finder.rb +95 -0
  167. data/lib/puppet/resource/catalog.rb +47 -7
  168. data/lib/puppet/resource/status.rb +0 -2
  169. data/lib/puppet/resource/type.rb +238 -44
  170. data/lib/puppet/resource/type_collection.rb +60 -2
  171. data/lib/puppet/settings.rb +2 -2
  172. data/lib/puppet/ssl/certificate_authority/interface.rb +2 -2
  173. data/lib/puppet/ssl/oids.rb +9 -1
  174. data/lib/puppet/transaction.rb +4 -1
  175. data/lib/puppet/transaction/additional_resource_generator.rb +71 -8
  176. data/lib/puppet/transaction/resource_harness.rb +9 -4
  177. data/lib/puppet/type.rb +74 -3
  178. data/lib/puppet/type/augeas.rb +8 -0
  179. data/lib/puppet/type/file/source.rb +14 -12
  180. data/lib/puppet/type/user.rb +4 -2
  181. data/lib/puppet/util/windows/security.rb +4 -1
  182. data/lib/puppet/util/windows/taskscheduler.rb +1 -1
  183. data/lib/puppet/version.rb +1 -1
  184. data/spec/fixtures/unit/application/environments/production/data/common.yaml +3 -0
  185. data/spec/fixtures/unit/application/environments/production/environment.conf +1 -0
  186. data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_json/data/bad.json +3 -0
  187. data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_json/environment.conf +2 -0
  188. data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_json/hiera.yaml +5 -0
  189. data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_json/manifests/site.pp +5 -0
  190. data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_yaml/data/bad.yaml +3 -0
  191. data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_yaml/environment.conf +2 -0
  192. data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_yaml/hiera.yaml +5 -0
  193. data/spec/fixtures/unit/data_providers/environments/hiera_bad_syntax_yaml/manifests/site.pp +5 -0
  194. data/spec/fixtures/unit/data_providers/environments/hiera_defaults/data/common.yaml +2 -0
  195. data/spec/fixtures/unit/data_providers/environments/hiera_defaults/environment.conf +2 -0
  196. data/spec/fixtures/unit/data_providers/environments/hiera_defaults/manifests/site.pp +1 -0
  197. data/spec/fixtures/unit/data_providers/environments/hiera_defaults/modules/one/data/common.yaml +2 -0
  198. data/spec/fixtures/unit/data_providers/environments/hiera_defaults/modules/one/manifests/init.pp +5 -0
  199. data/spec/fixtures/unit/data_providers/environments/hiera_defaults/modules/one/metadata.json +9 -0
  200. data/spec/fixtures/unit/data_providers/environments/hiera_env_config/data1/first.json +3 -0
  201. data/spec/fixtures/unit/data_providers/environments/hiera_env_config/data1/name.yaml +2 -0
  202. data/spec/fixtures/unit/data_providers/environments/hiera_env_config/data1/second.json +3 -0
  203. data/spec/fixtures/unit/data_providers/environments/hiera_env_config/data1/single.yaml +2 -0
  204. data/spec/fixtures/unit/data_providers/environments/hiera_env_config/data2/single.yaml +2 -0
  205. data/spec/fixtures/unit/data_providers/environments/hiera_env_config/environment.conf +2 -0
  206. data/spec/fixtures/unit/data_providers/environments/hiera_env_config/hiera.yaml +18 -0
  207. data/spec/fixtures/unit/data_providers/environments/hiera_env_config/manifests/site.pp +5 -0
  208. data/spec/fixtures/unit/data_providers/environments/hiera_misc/data/common.yaml +46 -0
  209. data/spec/fixtures/unit/data_providers/environments/hiera_misc/environment.conf +2 -0
  210. data/spec/fixtures/unit/data_providers/environments/hiera_misc/manifests/site.pp +1 -0
  211. data/spec/fixtures/unit/data_providers/environments/hiera_misc/modules/one/data/common.yaml +30 -0
  212. data/spec/fixtures/unit/data_providers/environments/hiera_misc/modules/one/manifests/init.pp +13 -0
  213. data/spec/fixtures/unit/data_providers/environments/hiera_misc/modules/one/metadata.json +9 -0
  214. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/environment.conf +2 -0
  215. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/manifests/site.pp +1 -0
  216. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/data1/first.json +3 -0
  217. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/data1/name.yaml +1 -0
  218. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/data1/second.json +3 -0
  219. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/data1/single.yaml +2 -0
  220. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/data2/single.yaml +2 -0
  221. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/hiera.yaml +18 -0
  222. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/manifests/init.pp +5 -0
  223. data/spec/fixtures/unit/data_providers/environments/hiera_module_config/modules/one/metadata.json +9 -0
  224. data/spec/fixtures/unit/data_providers/environments/sample/modules/dataprovider/lib/puppet_x/helindbe/sample_env_data.rb +1 -0
  225. data/spec/fixtures/unit/data_providers/environments/sample/modules/dataprovider/lib/puppet_x/helindbe/sample_module_data.rb +1 -0
  226. data/spec/fixtures/unit/functions/lookup/environments/production/modules/hieraprovider/data/first.json +3 -0
  227. data/spec/fixtures/unit/functions/lookup/environments/production/modules/hieraprovider/hiera.yaml +8 -0
  228. data/spec/fixtures/unit/functions/lookup/environments/production/modules/hieraprovider/manifests/init.pp +5 -0
  229. data/spec/fixtures/unit/functions/lookup/environments/production/modules/hieraprovider/metadata.json +9 -0
  230. data/spec/fixtures/unit/functions/lookup/environments/production/modules/meta/lib/puppet/functions/meta/data.rb +9 -0
  231. data/spec/fixtures/unit/functions/lookup/environments/production/modules/meta/manifests/init.pp +3 -0
  232. data/spec/fixtures/unit/functions/lookup/environments/production/modules/meta/metadata.json +9 -0
  233. data/spec/fixtures/unit/functions/lookup/environments/production/modules/metawcp/lib/puppet/bindings/metawcp/default.rb +10 -0
  234. data/spec/fixtures/unit/functions/lookup/environments/production/modules/metawcp/lib/puppet_x/thallgren/sample_module_data.rb +23 -0
  235. data/spec/fixtures/unit/functions/lookup/environments/production/modules/metawcp/manifests/init.pp +3 -0
  236. data/spec/fixtures/unit/functions/lookup/environments/production/modules/metawcp/metadata.json +9 -0
  237. data/spec/fixtures/unit/provider/package/yum/yum-check-update-security.txt +184 -0
  238. data/spec/fixtures/vcr/cassettes/Puppet_Network_HTTP_Connection/when_handling_requests/_request_get/should_yield_to_the_block.yml +24 -0
  239. data/spec/fixtures/vcr/cassettes/Puppet_Network_HTTP_Connection/when_handling_requests/_request_head/should_yield_to_the_block.yml +24 -0
  240. data/spec/fixtures/vcr/cassettes/Puppet_Network_HTTP_Connection/when_handling_requests/_request_post/should_yield_to_the_block.yml +24 -0
  241. data/spec/integration/data_binding_spec.rb +229 -0
  242. data/spec/integration/file_bucket/file_spec.rb +2 -2
  243. data/spec/integration/parser/compiler_spec.rb +23 -19
  244. data/spec/integration/parser/resource_expressions_spec.rb +4 -4
  245. data/spec/integration/parser/undef_param_spec.rb +1 -1
  246. data/spec/integration/resource/catalog_spec.rb +1 -1
  247. data/spec/integration/type/package_spec.rb +2 -0
  248. data/spec/integration/util/windows/security_spec.rb +18 -0
  249. data/spec/lib/matchers/include_in_order.rb +2 -2
  250. data/spec/shared_behaviours/iterative_functions.rb +8 -8
  251. data/spec/spec_helper.rb +7 -0
  252. data/spec/unit/agent/locker_spec.rb +4 -4
  253. data/spec/unit/agent_spec.rb +0 -8
  254. data/spec/unit/application/agent_spec.rb +5 -0
  255. data/spec/unit/application/apply_spec.rb +8 -0
  256. data/spec/unit/application/filebucket_spec.rb +87 -1
  257. data/spec/unit/application/lookup_spec.rb +195 -0
  258. data/spec/unit/appmgmt_spec.rb +657 -0
  259. data/spec/unit/capability_spec.rb +414 -0
  260. data/spec/unit/configurer_spec.rb +7 -1
  261. data/spec/unit/context/trusted_information_spec.rb +24 -1
  262. data/spec/unit/daemon_spec.rb +18 -8
  263. data/spec/unit/data_providers/hiera_data_provider_spec.rb +201 -0
  264. data/spec/unit/file_bucket/dipper_spec.rb +210 -1
  265. data/spec/unit/functions/assert_type_spec.rb +5 -7
  266. data/spec/unit/functions/defined_spec.rb +2 -2
  267. data/spec/unit/functions/epp_spec.rb +2 -2
  268. data/spec/unit/functions/lookup_spec.rb +200 -9
  269. data/spec/unit/functions/regsubst_spec.rb +17 -8
  270. data/spec/unit/functions/scanf_spec.rb +1 -1
  271. data/spec/unit/functions/split_spec.rb +2 -2
  272. data/spec/unit/functions/versioncmp_spec.rb +36 -0
  273. data/spec/unit/functions4_spec.rb +58 -72
  274. data/spec/unit/indirector/catalog/compiler_spec.rb +28 -8
  275. data/spec/unit/indirector/catalog/static_compiler_spec.rb +38 -20
  276. data/spec/unit/indirector/data_binding/none_spec.rb +2 -2
  277. data/spec/unit/indirector/file_bucket_file/file_spec.rb +52 -1
  278. data/spec/unit/indirector/request_spec.rb +8 -8
  279. data/spec/unit/info_service_spec.rb +236 -0
  280. data/spec/unit/module_tool/metadata_spec.rb +31 -2
  281. data/spec/unit/network/authconfig_spec.rb +62 -32
  282. data/spec/unit/network/authorization_spec.rb +30 -2
  283. data/spec/unit/network/http/connection_spec.rb +14 -19
  284. data/spec/unit/parser/compiler_spec.rb +86 -2
  285. data/spec/unit/parser/functions/create_resources_spec.rb +1 -1
  286. data/spec/unit/parser/resource_spec.rb +2 -20
  287. data/spec/unit/pops/binder/config/binder_config_spec.rb +1 -1
  288. data/spec/unit/pops/binder/injector_spec.rb +3 -3
  289. data/spec/unit/pops/evaluator/access_ops_spec.rb +13 -11
  290. data/spec/unit/pops/evaluator/basic_expressions_spec.rb +1 -2
  291. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +19 -11
  292. data/spec/unit/pops/evaluator/literal_evaluator_spec.rb +43 -0
  293. data/spec/unit/pops/label_provider_spec.rb +5 -1
  294. data/spec/unit/pops/parser/lexer2_spec.rb +33 -7
  295. data/spec/unit/pops/parser/parse_application_spec.rb +40 -0
  296. data/spec/unit/pops/parser/parse_basic_expressions_spec.rb +4 -0
  297. data/spec/unit/pops/parser/parse_capabilities_spec.rb +47 -0
  298. data/spec/unit/pops/parser/parse_site_spec.rb +38 -0
  299. data/spec/unit/pops/parser/parser_rspec_helper.rb +5 -0
  300. data/spec/unit/pops/parser/parser_spec.rb +18 -0
  301. data/spec/unit/pops/types/type_calculator_spec.rb +427 -444
  302. data/spec/unit/pops/types/type_factory_spec.rb +12 -12
  303. data/spec/unit/pops/types/type_parser_spec.rb +7 -12
  304. data/spec/unit/pops/validator/validator_spec.rb +25 -0
  305. data/spec/unit/provider/augeas/augeas_spec.rb +50 -0
  306. data/spec/unit/provider/group/directoryservice_spec.rb +33 -0
  307. data/spec/unit/provider/group/windows_adsi_spec.rb +3 -0
  308. data/spec/unit/provider/package/dnf_spec.rb +92 -0
  309. data/spec/unit/provider/package/gem_spec.rb +7 -0
  310. data/spec/unit/provider/package/rpm_spec.rb +25 -2
  311. data/spec/unit/provider/package/windows/package_spec.rb +41 -0
  312. data/spec/unit/provider/package/yum_spec.rb +21 -13
  313. data/spec/unit/provider/scheduled_task/win32_taskscheduler_spec.rb +10 -0
  314. data/spec/unit/provider/service/debian_spec.rb +27 -0
  315. data/spec/unit/provider/service/rcng_spec.rb +41 -0
  316. data/spec/unit/provider/service/redhat_spec.rb +8 -1
  317. data/spec/unit/provider/service/smf_spec.rb +30 -5
  318. data/spec/unit/provider/service/src_spec.rb +19 -4
  319. data/spec/unit/provider/service/systemd_spec.rb +78 -29
  320. data/spec/unit/provider/sshkey/parsed_spec.rb +23 -0
  321. data/spec/unit/reports_spec.rb +10 -0
  322. data/spec/unit/resource/capability_finder_spec.rb +56 -0
  323. data/spec/unit/resource/catalog_spec.rb +31 -8
  324. data/spec/unit/resource/type_collection_spec.rb +23 -2
  325. data/spec/unit/resource/type_spec.rb +1 -1
  326. data/spec/unit/resource_spec.rb +22 -4
  327. data/spec/unit/settings_spec.rb +90 -1
  328. data/spec/unit/ssl/certificate_authority/interface_spec.rb +4 -3
  329. data/spec/unit/ssl/oids_spec.rb +8 -0
  330. data/spec/unit/transaction/additional_resource_generator_spec.rb +78 -5
  331. data/spec/unit/transaction/report_spec.rb +24 -1
  332. data/spec/unit/type/package_spec.rb +1 -0
  333. data/spec/unit/type/user_spec.rb +14 -7
  334. data/spec/unit/type_spec.rb +1 -1
  335. metadata +169 -5
  336. data/lib/puppet/pops/evaluator/callable_mismatch_describer.rb +0 -175
  337. data/spec/integration/data_binding.rb +0 -104
@@ -116,32 +116,32 @@ describe Puppet::Indirector::Request do
116
116
  end
117
117
 
118
118
  it "should set the protocol to the URI scheme" do
119
- expect(Puppet::Indirector::Request.new(:ind, :method, "http://host/an_environment", nil).protocol).to eq("http")
119
+ expect(Puppet::Indirector::Request.new(:ind, :method, "http://host/", nil).protocol).to eq("http")
120
120
  end
121
121
 
122
122
  it "should set the server if a server is provided" do
123
- expect(Puppet::Indirector::Request.new(:ind, :method, "http://host/an_environment", nil).server).to eq("host")
123
+ expect(Puppet::Indirector::Request.new(:ind, :method, "http://host/", nil).server).to eq("host")
124
124
  end
125
125
 
126
126
  it "should set the server and port if both are provided" do
127
- expect(Puppet::Indirector::Request.new(:ind, :method, "http://host:543/an_environment", nil).port).to eq(543)
127
+ expect(Puppet::Indirector::Request.new(:ind, :method, "http://host:543/", nil).port).to eq(543)
128
128
  end
129
129
 
130
130
  it "should default to the masterport if the URI scheme is 'puppet'" do
131
131
  Puppet[:masterport] = "321"
132
- expect(Puppet::Indirector::Request.new(:ind, :method, "puppet://host/an_environment", nil).port).to eq(321)
132
+ expect(Puppet::Indirector::Request.new(:ind, :method, "puppet://host/", nil).port).to eq(321)
133
133
  end
134
134
 
135
135
  it "should use the provided port if the URI scheme is not 'puppet'" do
136
- expect(Puppet::Indirector::Request.new(:ind, :method, "http://host/an_environment", nil).port).to eq(80)
136
+ expect(Puppet::Indirector::Request.new(:ind, :method, "http://host/", nil).port).to eq(80)
137
137
  end
138
138
 
139
- it "should set the request key to the unescaped key part path from the URI" do
140
- expect(Puppet::Indirector::Request.new(:ind, :method, "http://host/an_environment/terminus/stuff with spaces", nil).key).to eq("stuff with spaces")
139
+ it "should set the request key to the unescaped path from the URI" do
140
+ expect(Puppet::Indirector::Request.new(:ind, :method, "http://host/stuff with spaces", nil).key).to eq("stuff with spaces")
141
141
  end
142
142
 
143
143
  it "should set the :uri attribute to the full URI" do
144
- expect(Puppet::Indirector::Request.new(:ind, :method, "http:///an_environment/stu ff", nil).uri).to eq('http:///an_environment/stu ff')
144
+ expect(Puppet::Indirector::Request.new(:ind, :method, "http:///a/path/stu ff", nil).uri).to eq('http:///a/path/stu ff')
145
145
  end
146
146
 
147
147
  it "should not parse relative URI" do
@@ -0,0 +1,236 @@
1
+ require 'spec_helper'
2
+ require 'puppet_spec/files'
3
+
4
+ require 'puppet/pops'
5
+ require 'puppet/info_service'
6
+ require 'puppet/pops/evaluator/literal_evaluator'
7
+
8
+ describe "Puppet::InfoService" do
9
+ context 'classes_per_environment service' do
10
+ include PuppetSpec::Files
11
+
12
+ let(:code_dir) do
13
+ dir_containing('manifests', {
14
+ 'foo.pp' => <<-CODE,
15
+ class foo($foo_a, Integer $foo_b, String $foo_c = 'c default value') { }
16
+ class foo2($foo2_a, Integer $foo2_b, String $foo2_c = 'c default value') { }
17
+ CODE
18
+ 'bar.pp' => <<-CODE,
19
+ class bar($bar_a, Integer $bar_b, String $bar_c = 'c default value') { }
20
+ class bar2($bar2_a, Integer $bar2_b, String $bar2_c = 'c default value') { }
21
+ CODE
22
+ 'fee.pp' => <<-CODE,
23
+ class fee(Integer $fee_a = 1+1) { }
24
+ CODE
25
+ 'fum.pp' => <<-CODE,
26
+ class fum($fum_a) { }
27
+ CODE
28
+ 'nothing.pp' => <<-CODE,
29
+ # not much to see here, move along
30
+ CODE
31
+ 'borked.pp' => <<-CODE,
32
+ class Borked($Herp+$Derp) {}
33
+ CODE
34
+ })
35
+ end
36
+
37
+ it "errors if not given a hash" do
38
+ expect{ Puppet::InfoService.classes_per_environment("you wassup?")}.to raise_error(ArgumentError, 'Given argument must be a Hash')
39
+ end
40
+
41
+ it "returns empty hash if given nothing" do
42
+ expect(Puppet::InfoService.classes_per_environment({})).to eq({})
43
+ end
44
+
45
+ it "produces classes and parameters from a given file" do
46
+ files = ['foo.pp'].map {|f| File.join(code_dir, f) }
47
+ result = Puppet::InfoService.classes_per_environment({'production' => files })
48
+ expect(result).to eq({
49
+ "production"=>{
50
+ "#{code_dir}/foo.pp"=>[
51
+ {:name=>"foo",
52
+ :params=>[
53
+ {:name=>"foo_a"},
54
+ {:name=>"foo_b", :type=>"Integer"},
55
+ {:name=>"foo_c", :type=>"String", :default_literal=>"c default value"}
56
+ ]},
57
+ {:name=>"foo2",
58
+ :params=>[
59
+ {:name=>"foo2_a"},
60
+ {:name=>"foo2_b", :type=>"Integer"},
61
+ {:name=>"foo2_c", :type=>"String", :default_literal=>"c default value"}
62
+ ]
63
+ }
64
+ ]} # end production env
65
+ })
66
+ end
67
+
68
+ it "produces classes and parameters from multiple files in same environment" do
69
+ files = ['foo.pp', 'bar.pp'].map {|f| File.join(code_dir, f) }
70
+ result = Puppet::InfoService.classes_per_environment({'production' => files })
71
+ expect(result).to eq({
72
+ "production"=>{
73
+ "#{code_dir}/foo.pp"=>[
74
+ {:name=>"foo",
75
+ :params=>[
76
+ {:name=>"foo_a"},
77
+ {:name=>"foo_b", :type=>"Integer"},
78
+ {:name=>"foo_c", :type=>"String", :default_literal=>"c default value"}
79
+ ]},
80
+ {:name=>"foo2",
81
+ :params=>[
82
+ {:name=>"foo2_a"},
83
+ {:name=>"foo2_b", :type=>"Integer"},
84
+ {:name=>"foo2_c", :type=>"String", :default_literal=>"c default value"}
85
+ ]
86
+ }
87
+ ],
88
+ "#{code_dir}/bar.pp"=>[
89
+ {:name=>"bar",
90
+ :params=>[
91
+ {:name=>"bar_a"},
92
+ {:name=>"bar_b", :type=>"Integer"},
93
+ {:name=>"bar_c", :type=>"String", :default_literal=>"c default value"}
94
+ ]},
95
+ {:name=>"bar2",
96
+ :params=>[
97
+ {:name=>"bar2_a"},
98
+ {:name=>"bar2_b", :type=>"Integer"},
99
+ {:name=>"bar2_c", :type=>"String", :default_literal=>"c default value"}
100
+ ]
101
+ }
102
+ ],
103
+
104
+ } # end production env
105
+ }
106
+ )
107
+ end
108
+
109
+ it "produces classes and parameters from multiple files in multiple environments" do
110
+ files_production = ['foo.pp', 'bar.pp'].map {|f| File.join(code_dir, f) }
111
+ files_test = ['fee.pp', 'fum.pp'].map {|f| File.join(code_dir, f) }
112
+ result = Puppet::InfoService.classes_per_environment({
113
+ 'production' => files_production,
114
+ 'test' => files_test
115
+ })
116
+
117
+ expect(result).to eq({
118
+ "production"=>{
119
+ "#{code_dir}/foo.pp"=>[
120
+ {:name=>"foo",
121
+ :params=>[
122
+ {:name=>"foo_a"},
123
+ {:name=>"foo_b", :type=>"Integer"},
124
+ {:name=>"foo_c", :type=>"String", :default_literal=>"c default value"}
125
+ ]},
126
+ {:name=>"foo2",
127
+ :params=>[
128
+ {:name=>"foo2_a"},
129
+ {:name=>"foo2_b", :type=>"Integer"},
130
+ {:name=>"foo2_c", :type=>"String", :default_literal=>"c default value"}
131
+ ]
132
+ }
133
+ ],
134
+ "#{code_dir}/bar.pp"=>[
135
+ {:name=>"bar",
136
+ :params=>[
137
+ {:name=>"bar_a"},
138
+ {:name=>"bar_b", :type=>"Integer"},
139
+ {:name=>"bar_c", :type=>"String", :default_literal=>"c default value"}
140
+ ]},
141
+ {:name=>"bar2",
142
+ :params=>[
143
+ {:name=>"bar2_a"},
144
+ {:name=>"bar2_b", :type=>"Integer"},
145
+ {:name=>"bar2_c", :type=>"String", :default_literal=>"c default value"}
146
+ ]
147
+ }
148
+ ],
149
+ }, # end production env
150
+ "test"=>{
151
+ "#{code_dir}/fee.pp"=>[
152
+ {:name=>"fee",
153
+ :params=>[
154
+ {:name=>"fee_a", :type=>"Integer", :default_source=>"1+1"}
155
+ ]},
156
+ ],
157
+ "#{code_dir}/fum.pp"=>[
158
+ {:name=>"fum",
159
+ :params=>[
160
+ {:name=>"fum_a"}
161
+ ]},
162
+ ],
163
+ } # end test env
164
+ }
165
+ )
166
+ end
167
+
168
+ it "avoids parsing file more than once when environments have same feature flag set" do
169
+ # in this version of puppet, all environments are equal in this respect
170
+ result = Puppet::Pops::Parser::EvaluatingParser.new.parse_file("#{code_dir}/fum.pp")
171
+ Puppet::Pops::Parser::EvaluatingParser.any_instance.expects(:parse_file).with("#{code_dir}/fum.pp").returns(result).once
172
+ files_production = ['fum.pp'].map {|f| File.join(code_dir, f) }
173
+ files_test = files_production
174
+
175
+ result = Puppet::InfoService.classes_per_environment({
176
+ 'production' => files_production,
177
+ 'test' => files_test
178
+ })
179
+ expect(result).to eq({
180
+ "production"=>{ "#{code_dir}/fum.pp"=>[ {:name=>"fum", :params=>[ {:name=>"fum_a"}]}]},
181
+ "test" =>{ "#{code_dir}/fum.pp"=>[ {:name=>"fum", :params=>[ {:name=>"fum_a"}]}]}
182
+ }
183
+ )
184
+ end
185
+
186
+ it "produces expression string if a default value is not literal" do
187
+ files = ['fee.pp'].map {|f| File.join(code_dir, f) }
188
+ result = Puppet::InfoService.classes_per_environment({'production' => files })
189
+ expect(result).to eq({
190
+ "production"=>{
191
+ "#{code_dir}/fee.pp"=>[
192
+ {:name=>"fee",
193
+ :params=>[
194
+ {:name=>"fee_a", :type=>"Integer", :default_source=>"1+1"}
195
+ ]},
196
+ ]} # end production env
197
+ })
198
+ end
199
+
200
+ it "produces no type entry if type is not given" do
201
+ files = ['fum.pp'].map {|f| File.join(code_dir, f) }
202
+ result = Puppet::InfoService.classes_per_environment({'production' => files })
203
+ expect(result).to eq({
204
+ "production"=>{
205
+ "#{code_dir}/fum.pp"=>[
206
+ {:name=>"fum",
207
+ :params=>[
208
+ {:name=>"fum_a" }
209
+ ]},
210
+ ]} # end production env
211
+ })
212
+ end
213
+
214
+ it "produces error entry if file is broken" do
215
+ files = ['borked.pp'].map {|f| File.join(code_dir, f) }
216
+ result = Puppet::InfoService.classes_per_environment({'production' => files })
217
+ expect(result).to eq({
218
+ "production"=>{
219
+ "#{code_dir}/borked.pp"=>
220
+ {:error=>"Syntax error at '+' at #{code_dir}/borked.pp:1:30",
221
+ },
222
+ } # end production env
223
+ })
224
+ end
225
+
226
+ it "produces empty {} if parsed result has no classes" do
227
+ files = ['nothing.pp'].map {|f| File.join(code_dir, f) }
228
+ result = Puppet::InfoService.classes_per_environment({'production' => files })
229
+ expect(result).to eq({
230
+ "production"=>{
231
+ "#{code_dir}/nothing.pp"=> []
232
+ },
233
+ })
234
+ end
235
+ end
236
+ end
@@ -9,7 +9,7 @@ describe Puppet::ModuleTool::Metadata do
9
9
  subject { metadata }
10
10
 
11
11
  %w[ name version author summary license source project_page issues_url
12
- dependencies dashed_name release_name description ].each do |prop|
12
+ dependencies dashed_name release_name description data_provider].each do |prop|
13
13
  describe "##{prop}" do
14
14
  it "responds to the property" do
15
15
  subject.send(prop)
@@ -224,6 +224,35 @@ describe Puppet::ModuleTool::Metadata do
224
224
  expect(subject.dependencies.size).to eq(1)
225
225
  end
226
226
  end
227
+
228
+ context 'with valid data_provider' do
229
+ let(:data) { {'data_provider' => 'the_name'} }
230
+
231
+ it 'validates the provider correctly' do
232
+ expect { subject }.not_to raise_error
233
+ end
234
+
235
+ it 'returns the provider' do
236
+ expect(subject.data_provider).to eq('the_name')
237
+ end
238
+ end
239
+
240
+ context 'with invalid data_provider' do
241
+ let(:data) { }
242
+
243
+ it "raises exception unless argument starts with a letter" do
244
+ expect { metadata.update('data_provider' => '_the_name') }.to raise_error(ArgumentError, /field 'data_provider' must begin with a letter/)
245
+ expect { metadata.update('data_provider' => '') }.to raise_error(ArgumentError, /field 'data_provider' must begin with a letter/)
246
+ end
247
+
248
+ it "raises exception if argument contains non-alphanumeric characters" do
249
+ expect { metadata.update('data_provider' => 'the::name') }.to raise_error(ArgumentError, /field 'data_provider' contains non-alphanumeric characters/)
250
+ end
251
+
252
+ it "raises exception unless argument is a string" do
253
+ expect { metadata.update('data_provider' => 23) }.to raise_error(ArgumentError, /field 'data_provider' must be a string/)
254
+ end
255
+ end
227
256
  end
228
257
 
229
258
  describe '#dashed_name' do
@@ -271,7 +300,7 @@ describe Puppet::ModuleTool::Metadata do
271
300
  subject { metadata.to_hash }
272
301
 
273
302
  it "contains the default set of keys" do
274
- expect(subject.keys.sort).to eq(%w[ name version author summary license source issues_url project_page dependencies ].sort)
303
+ expect(subject.keys.sort).to eq(%w[ name version author summary license source issues_url project_page dependencies data_provider].sort)
275
304
  end
276
305
 
277
306
  describe "['license']" do
@@ -3,80 +3,80 @@ require 'spec_helper'
3
3
 
4
4
  require 'puppet/network/authconfig'
5
5
 
6
- describe Puppet::Network::AuthConfig do
6
+ describe Puppet::Network::DefaultAuthProvider do
7
7
  before :each do
8
8
  Puppet::FileSystem.stubs(:stat).returns stub('stat', :ctime => :now)
9
9
  Time.stubs(:now).returns Time.now
10
10
 
11
- Puppet::Network::AuthConfig.any_instance.stubs(:exists?).returns(true)
12
- # FIXME @authconfig = Puppet::Network::AuthConfig.new("dummy")
11
+ Puppet::Network::DefaultAuthProvider.any_instance.stubs(:exists?).returns(true)
12
+ # FIXME @authprovider = Puppet::Network::DefaultAuthProvider.new("dummy")
13
13
  end
14
14
 
15
15
  describe "when initializing" do
16
16
  it "inserts default ACLs after setting initial rights" do
17
- Puppet::Network::AuthConfig.any_instance.expects(:insert_default_acl)
18
- Puppet::Network::AuthConfig.new
17
+ Puppet::Network::DefaultAuthProvider.any_instance.expects(:insert_default_acl)
18
+ Puppet::Network::DefaultAuthProvider.new
19
19
  end
20
20
  end
21
21
 
22
22
  describe "when defining an acl with mk_acl" do
23
23
  before :each do
24
- Puppet::Network::AuthConfig.any_instance.stubs(:insert_default_acl)
25
- @authconfig = Puppet::Network::AuthConfig.new
24
+ Puppet::Network::DefaultAuthProvider.any_instance.stubs(:insert_default_acl)
25
+ @authprovider = Puppet::Network::DefaultAuthProvider.new
26
26
  end
27
27
 
28
28
  it "should create a new right for each default acl" do
29
- @authconfig.mk_acl(:acl => '/')
30
- expect(@authconfig.rights['/']).to be
29
+ @authprovider.mk_acl(:acl => '/')
30
+ expect(@authprovider.rights['/']).to be
31
31
  end
32
32
 
33
33
  it "allows everyone for each default right" do
34
- @authconfig.mk_acl(:acl => '/')
35
- expect(@authconfig.rights['/']).to be_globalallow
34
+ @authprovider.mk_acl(:acl => '/')
35
+ expect(@authprovider.rights['/']).to be_globalallow
36
36
  end
37
37
 
38
38
  it "accepts an argument to restrict the method" do
39
- @authconfig.mk_acl(:acl => '/', :method => :find)
40
- expect(@authconfig.rights['/'].methods).to eq([:find])
39
+ @authprovider.mk_acl(:acl => '/', :method => :find)
40
+ expect(@authprovider.rights['/'].methods).to eq([:find])
41
41
  end
42
42
 
43
43
  it "creates rights with authentication set to true by default" do
44
- @authconfig.mk_acl(:acl => '/')
45
- expect(@authconfig.rights['/'].authentication).to be_truthy
44
+ @authprovider.mk_acl(:acl => '/')
45
+ expect(@authprovider.rights['/'].authentication).to be_truthy
46
46
  end
47
47
 
48
48
  it "accepts an argument to set the authentication requirement" do
49
- @authconfig.mk_acl(:acl => '/', :authenticated => :any)
50
- expect(@authconfig.rights['/'].authentication).to be_falsey
49
+ @authprovider.mk_acl(:acl => '/', :authenticated => :any)
50
+ expect(@authprovider.rights['/'].authentication).to be_falsey
51
51
  end
52
52
  end
53
53
 
54
54
  describe "when adding default ACLs" do
55
55
  before :each do
56
- Puppet::Network::AuthConfig.any_instance.stubs(:insert_default_acl)
57
- @authconfig = Puppet::Network::AuthConfig.new
58
- Puppet::Network::AuthConfig.any_instance.unstub(:insert_default_acl)
56
+ Puppet::Network::DefaultAuthProvider.any_instance.stubs(:insert_default_acl)
57
+ @authprovider = Puppet::Network::DefaultAuthProvider.new
58
+ Puppet::Network::DefaultAuthProvider.any_instance.unstub(:insert_default_acl)
59
59
  end
60
60
 
61
- Puppet::Network::AuthConfig::default_acl.each do |acl|
61
+ Puppet::Network::DefaultAuthProvider::default_acl.each do |acl|
62
62
  it "should create a default right for #{acl[:acl]}" do
63
- @authconfig.stubs(:mk_acl)
64
- @authconfig.expects(:mk_acl).with(acl)
65
- @authconfig.insert_default_acl
63
+ @authprovider.stubs(:mk_acl)
64
+ @authprovider.expects(:mk_acl).with(acl)
65
+ @authprovider.insert_default_acl
66
66
  end
67
67
  end
68
68
 
69
69
  it "should log at info loglevel" do
70
70
  Puppet.expects(:info).at_least_once
71
- @authconfig.insert_default_acl
71
+ @authprovider.insert_default_acl
72
72
  end
73
73
 
74
74
  it "creates an empty catch-all rule for '/' for any authentication request state" do
75
- @authconfig.stubs(:mk_acl)
75
+ @authprovider.stubs(:mk_acl)
76
76
 
77
- @authconfig.insert_default_acl
78
- expect(@authconfig.rights['/']).to be_empty
79
- expect(@authconfig.rights['/'].authentication).to be_falsey
77
+ @authprovider.insert_default_acl
78
+ expect(@authprovider.rights['/']).to be_empty
79
+ expect(@authprovider.rights['/'].authentication).to be_falsey
80
80
  end
81
81
 
82
82
  it '(CVE-2013-2275) allows report submission only for the node matching the certname by default' do
@@ -86,9 +86,9 @@ describe Puppet::Network::AuthConfig do
86
86
  :allow => '$1',
87
87
  :authenticated => true
88
88
  }
89
- @authconfig.stubs(:mk_acl)
90
- @authconfig.expects(:mk_acl).with(acl)
91
- @authconfig.insert_default_acl
89
+ @authprovider.stubs(:mk_acl)
90
+ @authprovider.expects(:mk_acl).with(acl)
91
+ @authprovider.insert_default_acl
92
92
  end
93
93
  end
94
94
 
@@ -107,3 +107,33 @@ describe Puppet::Network::AuthConfig do
107
107
  end
108
108
  end
109
109
  end
110
+
111
+ describe Puppet::Network::AuthConfig do
112
+ after :each do
113
+ Puppet::Network::AuthConfig.authprovider_class = nil
114
+ end
115
+
116
+ class TestAuthProvider
117
+ def initialize(rights=nil); end
118
+ def check_authorization(method, path, params); end
119
+ end
120
+
121
+ it "instantiates authprovider_class with rights" do
122
+ Puppet::Network::AuthConfig.authprovider_class = TestAuthProvider
123
+ rights = Puppet::Network::Rights.new
124
+ TestAuthProvider.expects(:new).with(rights)
125
+ described_class.new(rights)
126
+ end
127
+
128
+ it "delegates authorization check to authprovider_class" do
129
+ Puppet::Network::AuthConfig.authprovider_class = TestAuthProvider
130
+ TestAuthProvider.any_instance.expects(:check_authorization).with(:save, '/path/to/resource', {})
131
+ described_class.new.check_authorization(:save, '/path/to/resource', {})
132
+ end
133
+
134
+ it "uses DefaultAuthProvider by default" do
135
+ Puppet::Network::AuthConfig.authprovider_class = nil
136
+ Puppet::Network::DefaultAuthProvider.any_instance.expects(:check_authorization).with(:save, '/path/to/resource', {})
137
+ described_class.new.check_authorization(:save, '/path/to/resource', {})
138
+ end
139
+ end