chef 12.4.3-universal-mingw32 → 12.5.1-universal-mingw32

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 (320) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +21 -25
  3. data/Gemfile +46 -0
  4. data/README.md +4 -4
  5. data/Rakefile +4 -110
  6. data/bin/chef-service-manager +3 -1
  7. data/distro/common/html/knife_cookbook_site.html +18 -18
  8. data/distro/common/man/man1/knife-cookbook-site.1 +11 -11
  9. data/lib/chef.rb +1 -1
  10. data/lib/chef/application.rb +1 -1
  11. data/lib/chef/application/apply.rb +19 -1
  12. data/lib/chef/application/client.rb +11 -5
  13. data/lib/chef/application/knife.rb +2 -2
  14. data/lib/chef/application/solo.rb +1 -1
  15. data/lib/chef/application/windows_service_manager.rb +19 -12
  16. data/lib/chef/chef_class.rb +46 -0
  17. data/lib/chef/chef_fs/config.rb +22 -24
  18. data/lib/chef/chef_fs/data_handler/client_data_handler.rb +3 -1
  19. data/lib/chef/chef_fs/file_pattern.rb +4 -15
  20. data/lib/chef/chef_fs/file_system/acl_dir.rb +3 -4
  21. data/lib/chef/chef_fs/file_system/acls_dir.rb +5 -1
  22. data/lib/chef/chef_fs/file_system/base_fs_dir.rb +0 -5
  23. data/lib/chef/chef_fs/file_system/base_fs_object.rb +5 -2
  24. data/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_dir.rb +2 -9
  25. data/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_entry.rb +2 -9
  26. data/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbooks_dir.rb +10 -17
  27. data/lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb +1 -12
  28. data/lib/chef/chef_fs/file_system/chef_repository_file_system_root_dir.rb +15 -11
  29. data/lib/chef/chef_fs/file_system/chef_server_root_dir.rb +8 -2
  30. data/lib/chef/chef_fs/file_system/cookbook_dir.rb +4 -4
  31. data/lib/chef/chef_fs/file_system/cookbooks_acl_dir.rb +1 -1
  32. data/lib/chef/chef_fs/file_system/cookbooks_dir.rb +3 -11
  33. data/lib/chef/chef_fs/file_system/data_bags_dir.rb +3 -5
  34. data/lib/chef/chef_fs/file_system/environments_dir.rb +1 -1
  35. data/lib/chef/chef_fs/file_system/file_system_entry.rb +7 -4
  36. data/lib/chef/chef_fs/file_system/memory_dir.rb +2 -3
  37. data/lib/chef/chef_fs/file_system/multiplexed_dir.rb +15 -0
  38. data/lib/chef/chef_fs/file_system/nodes_dir.rb +1 -1
  39. data/lib/chef/chef_fs/file_system/organization_members_entry.rb +2 -2
  40. data/lib/chef/chef_fs/file_system/rest_list_dir.rb +4 -9
  41. data/lib/chef/chef_fs/knife.rb +35 -7
  42. data/lib/chef/chef_fs/path_utils.rb +65 -34
  43. data/lib/chef/client.rb +2 -3
  44. data/lib/chef/config.rb +34 -2
  45. data/lib/chef/{mixin/wstring.rb → constants.rb} +9 -13
  46. data/lib/chef/cookbook/metadata.rb +25 -3
  47. data/lib/chef/cookbook/synchronizer.rb +1 -1
  48. data/lib/chef/cookbook_site_streaming_uploader.rb +1 -1
  49. data/lib/chef/cookbook_version.rb +3 -3
  50. data/lib/chef/delayed_evaluator.rb +21 -0
  51. data/lib/chef/deprecation/mixin/template.rb +1 -2
  52. data/lib/chef/deprecation/provider/cookbook_file.rb +1 -1
  53. data/lib/chef/deprecation/provider/file.rb +1 -1
  54. data/lib/chef/deprecation/provider/remote_directory.rb +52 -0
  55. data/lib/chef/deprecation/provider/remote_file.rb +1 -2
  56. data/lib/chef/deprecation/provider/template.rb +1 -1
  57. data/lib/chef/deprecation/warnings.rb +3 -4
  58. data/lib/chef/dsl/reboot_pending.rb +3 -2
  59. data/lib/chef/dsl/recipe.rb +26 -7
  60. data/lib/chef/dsl/resources.rb +2 -2
  61. data/lib/chef/event_dispatch/base.rb +51 -22
  62. data/lib/chef/event_dispatch/dispatcher.rb +21 -6
  63. data/lib/chef/event_dispatch/dsl.rb +64 -0
  64. data/lib/chef/exceptions.rb +28 -1
  65. data/lib/chef/file_content_management/tempfile.rb +1 -1
  66. data/lib/chef/formatters/base.rb +3 -0
  67. data/lib/chef/formatters/doc.rb +56 -6
  68. data/lib/chef/formatters/error_inspectors/compile_error_inspector.rb +36 -0
  69. data/lib/chef/formatters/minimal.rb +2 -2
  70. data/lib/chef/guard_interpreter/resource_guard_interpreter.rb +3 -1
  71. data/lib/chef/http/http_request.rb +1 -1
  72. data/lib/chef/knife.rb +35 -55
  73. data/lib/chef/knife/bootstrap.rb +41 -0
  74. data/lib/chef/knife/bootstrap/chef_vault_handler.rb +1 -0
  75. data/lib/chef/knife/bootstrap/client_builder.rb +16 -0
  76. data/lib/chef/knife/bootstrap/templates/README.md +3 -4
  77. data/lib/chef/knife/bootstrap/templates/chef-full.erb +1 -1
  78. data/lib/chef/knife/cookbook_create.rb +1 -1
  79. data/lib/chef/knife/cookbook_site_download.rb +1 -1
  80. data/lib/chef/knife/cookbook_site_install.rb +1 -1
  81. data/lib/chef/knife/cookbook_site_share.rb +6 -6
  82. data/lib/chef/knife/cookbook_site_unshare.rb +2 -2
  83. data/lib/chef/knife/core/bootstrap_context.rb +12 -4
  84. data/lib/chef/knife/core/custom_manifest_loader.rb +69 -0
  85. data/lib/chef/knife/core/gem_glob_loader.rb +138 -0
  86. data/lib/chef/knife/core/hashed_command_loader.rb +80 -0
  87. data/lib/chef/knife/core/node_presenter.rb +24 -1
  88. data/lib/chef/knife/core/object_loader.rb +1 -0
  89. data/lib/chef/knife/core/subcommand_loader.rb +131 -146
  90. data/lib/chef/knife/node_run_list_remove.rb +12 -1
  91. data/lib/chef/knife/null.rb +10 -0
  92. data/lib/chef/knife/rehash.rb +62 -0
  93. data/lib/chef/knife/search.rb +3 -3
  94. data/lib/chef/knife/ssh.rb +52 -30
  95. data/lib/chef/knife/ssl_check.rb +3 -2
  96. data/lib/chef/knife/user_edit.rb +1 -2
  97. data/lib/chef/local_mode.rb +5 -0
  98. data/lib/chef/log.rb +5 -1
  99. data/lib/chef/mixin/deprecation.rb +8 -8
  100. data/lib/chef/mixin/params_validate.rb +362 -135
  101. data/lib/chef/mixin/template.rb +48 -0
  102. data/lib/chef/mixin/which.rb +1 -1
  103. data/lib/chef/mixin/wide_string.rb +72 -0
  104. data/lib/chef/mixin/windows_architecture_helper.rb +15 -39
  105. data/lib/chef/mixin/windows_env_helper.rb +4 -1
  106. data/lib/chef/monkey_patches/webrick-utils.rb +51 -0
  107. data/lib/chef/monkey_patches/win32/registry.rb +72 -0
  108. data/lib/chef/node.rb +116 -3
  109. data/lib/chef/node_map.rb +2 -2
  110. data/lib/chef/platform/handler_map.rb +0 -5
  111. data/lib/chef/platform/provider_mapping.rb +5 -6
  112. data/lib/chef/platform/query_helpers.rb +46 -4
  113. data/lib/chef/platform/rebooter.rb +1 -1
  114. data/lib/chef/platform/service_helpers.rb +30 -32
  115. data/lib/chef/policy_builder.rb +1 -8
  116. data/lib/chef/policy_builder/dynamic.rb +186 -0
  117. data/lib/chef/policy_builder/expand_node_object.rb +30 -15
  118. data/lib/chef/policy_builder/policyfile.rb +155 -18
  119. data/lib/chef/property.rb +568 -0
  120. data/lib/chef/provider.rb +222 -13
  121. data/lib/chef/provider/batch.rb +8 -0
  122. data/lib/chef/provider/deploy.rb +5 -7
  123. data/lib/chef/provider/directory.rb +14 -2
  124. data/lib/chef/provider/dsc_resource.rb +5 -9
  125. data/lib/chef/provider/group/pw.rb +1 -1
  126. data/lib/chef/provider/ifconfig.rb +2 -2
  127. data/lib/chef/provider/lwrp_base.rb +1 -75
  128. data/lib/chef/provider/mount.rb +7 -3
  129. data/lib/chef/provider/package.rb +1 -1
  130. data/lib/chef/provider/package/dpkg.rb +5 -11
  131. data/lib/chef/provider/package/rpm.rb +2 -2
  132. data/lib/chef/provider/package/rubygems.rb +1 -1
  133. data/lib/chef/provider/package/windows/msi.rb +2 -2
  134. data/lib/chef/provider/package/yum.rb +17 -5
  135. data/lib/chef/provider/powershell_script.rb +59 -23
  136. data/lib/chef/provider/registry_key.rb +5 -5
  137. data/lib/chef/provider/remote_directory.rb +190 -102
  138. data/lib/chef/provider/service.rb +12 -2
  139. data/lib/chef/provider/service/aix.rb +1 -1
  140. data/lib/chef/provider/service/debian.rb +3 -5
  141. data/lib/chef/provider/service/freebsd.rb +1 -1
  142. data/lib/chef/provider/service/gentoo.rb +3 -3
  143. data/lib/chef/provider/service/init.rb +3 -3
  144. data/lib/chef/provider/service/insserv.rb +2 -4
  145. data/lib/chef/provider/service/invokercd.rb +2 -4
  146. data/lib/chef/provider/service/macosx.rb +5 -1
  147. data/lib/chef/provider/service/openbsd.rb +2 -1
  148. data/lib/chef/provider/service/redhat.rb +52 -16
  149. data/lib/chef/provider/service/simple.rb +2 -2
  150. data/lib/chef/provider/service/systemd.rb +3 -5
  151. data/lib/chef/provider/service/upstart.rb +4 -6
  152. data/lib/chef/provider/subversion.rb +13 -7
  153. data/lib/chef/provider/template/content.rb +16 -6
  154. data/lib/chef/provider/user/solaris.rb +32 -4
  155. data/lib/chef/provider/windows_script.rb +3 -5
  156. data/lib/chef/provider_resolver.rb +2 -2
  157. data/lib/chef/recipe.rb +1 -8
  158. data/lib/chef/resource.rb +563 -90
  159. data/lib/chef/resource/action_class.rb +83 -0
  160. data/lib/chef/resource/chef_gem.rb +3 -3
  161. data/lib/chef/resource/deploy.rb +8 -2
  162. data/lib/chef/resource/dsc_script.rb +2 -0
  163. data/lib/chef/resource/file/verification.rb +7 -1
  164. data/lib/chef/resource/lwrp_base.rb +1 -7
  165. data/lib/chef/resource/registry_key.rb +1 -1
  166. data/lib/chef/resource/service.rb +10 -2
  167. data/lib/chef/resource/subversion.rb +5 -0
  168. data/lib/chef/resource/windows_script.rb +6 -2
  169. data/lib/chef/resource/yum_package.rb +10 -1
  170. data/lib/chef/resource_resolver.rb +3 -3
  171. data/lib/chef/run_context.rb +402 -83
  172. data/lib/chef/run_list/versioned_recipe_list.rb +15 -0
  173. data/lib/chef/run_lock.rb +30 -21
  174. data/lib/chef/util/powershell/ps_credential.rb +4 -0
  175. data/lib/chef/util/windows.rb +0 -32
  176. data/lib/chef/util/windows/net_group.rb +85 -106
  177. data/lib/chef/util/windows/net_use.rb +35 -71
  178. data/lib/chef/util/windows/net_user.rb +0 -1
  179. data/lib/chef/util/windows/volume.rb +19 -19
  180. data/lib/chef/version.rb +3 -3
  181. data/lib/chef/win32/api.rb +1 -0
  182. data/lib/chef/win32/api/file.rb +20 -0
  183. data/lib/chef/win32/api/net.rb +163 -43
  184. data/lib/chef/win32/api/registry.rb +51 -0
  185. data/lib/chef/win32/api/system.rb +23 -0
  186. data/lib/chef/win32/api/unicode.rb +0 -43
  187. data/lib/chef/win32/crypto.rb +2 -1
  188. data/lib/chef/win32/file.rb +28 -3
  189. data/lib/chef/win32/mutex.rb +1 -2
  190. data/lib/chef/win32/net.rb +162 -8
  191. data/lib/chef/win32/process.rb +13 -0
  192. data/lib/chef/win32/registry.rb +35 -30
  193. data/lib/chef/win32/security.rb +1 -1
  194. data/lib/chef/win32/security/token.rb +1 -1
  195. data/lib/chef/win32/system.rb +62 -0
  196. data/lib/chef/win32/unicode.rb +7 -2
  197. data/lib/chef/win32/version.rb +0 -4
  198. data/lib/chef/workstation_config_loader.rb +3 -158
  199. data/spec/data/cookbooks/openldap/templates/default/helpers.erb +14 -0
  200. data/spec/data/cookbooks/openldap/templates/default/nested_openldap_partials.erb +1 -0
  201. data/spec/data/cookbooks/openldap/templates/default/nested_partial.erb +1 -0
  202. data/spec/data/dsc_lcm.pfx +0 -0
  203. data/spec/data/run_context/cookbooks/include/recipes/default.rb +24 -0
  204. data/spec/data/run_context/cookbooks/include/recipes/includee.rb +3 -0
  205. data/spec/functional/dsl/reboot_pending_spec.rb +33 -43
  206. data/spec/functional/knife/cookbook_delete_spec.rb +17 -7
  207. data/spec/functional/knife/ssh_spec.rb +16 -0
  208. data/spec/functional/rebooter_spec.rb +1 -1
  209. data/spec/functional/resource/deploy_revision_spec.rb +1 -1
  210. data/spec/functional/resource/dsc_resource_spec.rb +2 -0
  211. data/spec/functional/resource/dsc_script_spec.rb +91 -2
  212. data/spec/functional/resource/group_spec.rb +67 -44
  213. data/spec/functional/resource/{powershell_spec.rb → powershell_script_spec.rb} +107 -18
  214. data/spec/functional/resource/windows_service_spec.rb +1 -1
  215. data/spec/functional/run_lock_spec.rb +368 -189
  216. data/spec/functional/win32/{registry_helper_spec.rb → registry_spec.rb} +16 -23
  217. data/spec/functional/win32/service_manager_spec.rb +2 -2
  218. data/spec/integration/client/client_spec.rb +51 -0
  219. data/spec/integration/knife/chef_repo_path_spec.rb +13 -11
  220. data/spec/integration/knife/download_spec.rb +4 -0
  221. data/spec/integration/knife/list_spec.rb +8 -0
  222. data/spec/integration/knife/upload_spec.rb +1 -1
  223. data/spec/integration/recipes/recipe_dsl_spec.rb +1 -16
  224. data/spec/integration/recipes/remote_directory.rb +74 -0
  225. data/spec/integration/recipes/resource_action_spec.rb +363 -0
  226. data/spec/integration/recipes/resource_converge_if_changed_spec.rb +423 -0
  227. data/spec/integration/recipes/resource_load_spec.rb +206 -0
  228. data/spec/spec_helper.rb +9 -0
  229. data/spec/support/platform_helpers.rb +13 -0
  230. data/spec/support/shared/context/win32.rb +34 -0
  231. data/spec/support/shared/functional/win32_service.rb +2 -1
  232. data/spec/support/shared/functional/windows_script.rb +63 -26
  233. data/spec/support/shared/unit/mock_shellout.rb +46 -0
  234. data/spec/support/shared/unit/provider/file.rb +10 -4
  235. data/spec/unit/application/client_spec.rb +16 -3
  236. data/spec/unit/application/knife_spec.rb +2 -2
  237. data/spec/unit/application/solo_spec.rb +4 -3
  238. data/spec/unit/chef_class_spec.rb +23 -4
  239. data/spec/unit/chef_fs/path_util_spec.rb +108 -0
  240. data/spec/unit/client_spec.rb +6 -1
  241. data/spec/unit/config_spec.rb +31 -0
  242. data/spec/unit/cookbook/metadata_spec.rb +23 -3
  243. data/spec/unit/cookbook/syntax_check_spec.rb +3 -0
  244. data/spec/unit/deprecation_spec.rb +3 -6
  245. data/spec/unit/dsl/reboot_pending_spec.rb +12 -6
  246. data/spec/unit/event_dispatch/dispatcher_spec.rb +65 -3
  247. data/spec/unit/event_dispatch/dsl_spec.rb +83 -0
  248. data/spec/unit/formatters/doc_spec.rb +32 -0
  249. data/spec/unit/formatters/error_inspectors/compile_error_inspector_spec.rb +26 -0
  250. data/spec/unit/json_compat_spec.rb +4 -3
  251. data/spec/unit/knife/bootstrap/client_builder_spec.rb +27 -0
  252. data/spec/unit/knife/bootstrap_spec.rb +55 -3
  253. data/spec/unit/knife/cookbook_site_share_spec.rb +3 -3
  254. data/spec/unit/knife/core/bootstrap_context_spec.rb +21 -4
  255. data/spec/unit/knife/core/custom_manifest_loader_spec.rb +41 -0
  256. data/spec/unit/knife/core/gem_glob_loader_spec.rb +210 -0
  257. data/spec/unit/knife/core/hashed_command_loader_spec.rb +93 -0
  258. data/spec/unit/knife/core/subcommand_loader_spec.rb +16 -192
  259. data/spec/unit/knife/node_run_list_remove_spec.rb +17 -0
  260. data/spec/unit/knife/ssl_check_spec.rb +4 -0
  261. data/spec/unit/mixin/enforce_ownership_and_permissions_spec.rb +10 -10
  262. data/spec/unit/mixin/params_validate_spec.rb +4 -2
  263. data/spec/unit/mixin/template_spec.rb +5 -1
  264. data/spec/unit/mixin/windows_architecture_helper_spec.rb +13 -8
  265. data/spec/unit/node_spec.rb +220 -0
  266. data/spec/unit/platform/query_helpers_spec.rb +146 -3
  267. data/spec/unit/policy_builder/dynamic_spec.rb +275 -0
  268. data/spec/unit/policy_builder/expand_node_object_spec.rb +37 -38
  269. data/spec/unit/policy_builder/policyfile_spec.rb +260 -46
  270. data/spec/unit/property/state_spec.rb +506 -0
  271. data/spec/unit/property/validation_spec.rb +663 -0
  272. data/spec/unit/property_spec.rb +1094 -0
  273. data/spec/unit/provider/deploy_spec.rb +5 -5
  274. data/spec/unit/provider/directory_spec.rb +35 -0
  275. data/spec/unit/provider/dsc_resource_spec.rb +3 -10
  276. data/spec/unit/provider/ifconfig_spec.rb +22 -2
  277. data/spec/unit/provider/mount/aix_spec.rb +2 -1
  278. data/spec/unit/provider/mount/mount_spec.rb +6 -0
  279. data/spec/unit/provider/mount/windows_spec.rb +14 -0
  280. data/spec/unit/provider/mount_spec.rb +12 -1
  281. data/spec/unit/provider/package/dpkg_spec.rb +8 -1
  282. data/spec/unit/provider/package/rpm_spec.rb +18 -1
  283. data/spec/unit/provider/package/rubygems_spec.rb +18 -0
  284. data/spec/unit/provider/package/yum_spec.rb +97 -24
  285. data/spec/unit/provider/powershell_script_spec.rb +106 -0
  286. data/spec/unit/provider/registry_key_spec.rb +12 -0
  287. data/spec/unit/provider/remote_directory_spec.rb +1 -2
  288. data/spec/unit/provider/service/aix_service_spec.rb +3 -3
  289. data/spec/unit/provider/service/gentoo_service_spec.rb +4 -4
  290. data/spec/unit/provider/service/macosx_spec.rb +4 -4
  291. data/spec/unit/provider/service/openbsd_service_spec.rb +10 -8
  292. data/spec/unit/provider/service/redhat_spec.rb +88 -8
  293. data/spec/unit/provider/service/upstart_service_spec.rb +11 -7
  294. data/spec/unit/provider/service/windows_spec.rb +211 -200
  295. data/spec/unit/provider/subversion_spec.rb +50 -31
  296. data/spec/unit/provider/template/content_spec.rb +93 -2
  297. data/spec/unit/provider/user/solaris_spec.rb +66 -9
  298. data/spec/unit/provider_resolver_spec.rb +707 -650
  299. data/spec/unit/provider_spec.rb +1 -3
  300. data/spec/unit/recipe_spec.rb +0 -4
  301. data/spec/unit/resource/deploy_spec.rb +7 -1
  302. data/spec/unit/resource/dsc_script_spec.rb +4 -0
  303. data/spec/unit/resource/file/verification_spec.rb +33 -5
  304. data/spec/unit/resource/{powershell_spec.rb → powershell_script_spec.rb} +17 -13
  305. data/spec/unit/resource/service_spec.rb +4 -4
  306. data/spec/unit/resource/subversion_spec.rb +4 -0
  307. data/spec/unit/resource/yum_package_spec.rb +10 -1
  308. data/spec/unit/resource_spec.rb +2 -2
  309. data/spec/unit/run_context/child_run_context_spec.rb +133 -0
  310. data/spec/unit/run_context_spec.rb +7 -0
  311. data/spec/unit/run_list/versioned_recipe_list_spec.rb +5 -0
  312. data/spec/unit/win32/registry_spec.rb +394 -0
  313. data/tasks/external_tests.rb +47 -23
  314. data/tasks/maintainers.rb +155 -14
  315. metadata +64 -53
  316. data/lib/chef/knife/bootstrap/templates/archlinux-gems.erb +0 -76
  317. data/lib/chef/knife/bootstrap/templates/chef-aix.erb +0 -72
  318. data/spec/unit/provider/powershell_spec.rb +0 -80
  319. data/spec/unit/registry_helper_spec.rb +0 -376
  320. data/spec/unit/workstation_config_loader_spec.rb +0 -283
@@ -136,7 +136,7 @@ class Chef
136
136
  def read_cli_args
137
137
  if config[:query]
138
138
  if @name_args[1]
139
- ui.error "please specify query as an argument or an option via -q, not both"
139
+ ui.error "Please specify query as an argument or an option via -q, not both"
140
140
  ui.msg opt_parser
141
141
  exit 1
142
142
  end
@@ -145,7 +145,7 @@ class Chef
145
145
  else
146
146
  case name_args.size
147
147
  when 0
148
- ui.error "no query specified"
148
+ ui.error "No query specified"
149
149
  ui.msg opt_parser
150
150
  exit 1
151
151
  when 1
@@ -160,7 +160,7 @@ class Chef
160
160
 
161
161
  def fuzzify_query
162
162
  if @query !~ /:/
163
- @query = "tags:*#{@query}* OR roles:*#{@query}* OR fqdn:*#{@query}* OR addresses:*#{@query}*"
163
+ @query = "tags:*#{@query}* OR roles:*#{@query}* OR fqdn:*#{@query}* OR addresses:*#{@query}* OR policy_name:*#{@query}* OR policy_group:*#{@query}*"
164
164
  end
165
165
  end
166
166
 
@@ -132,15 +132,19 @@ class Chef
132
132
  if config[:ssh_gateway]
133
133
  gw_host, gw_user = config[:ssh_gateway].split('@').reverse
134
134
  gw_host, gw_port = gw_host.split(':')
135
- gw_opts = gw_port ? { :port => gw_port } : {}
135
+ gw_opts = session_options(gw_host, gw_port, gw_user)
136
+ user = gw_opts.delete(:user)
136
137
 
137
- session.via(gw_host, gw_user || config[:ssh_user], gw_opts)
138
+ begin
139
+ # Try to connect with a key.
140
+ session.via(gw_host, user, gw_opts)
141
+ rescue Net::SSH::AuthenticationFailed
142
+ prompt = "Enter the password for #{user}@#{gw_host}: "
143
+ gw_opts[:password] = prompt_for_password(prompt)
144
+ # Try again with a password.
145
+ session.via(gw_host, user, gw_opts)
146
+ end
138
147
  end
139
- rescue Net::SSH::AuthenticationFailed
140
- user = gw_user || config[:ssh_user]
141
- prompt = "Enter the password for #{user}@#{gw_host}: "
142
- gw_opts.merge!(:password => prompt_for_password(prompt))
143
- session.via(gw_host, user, gw_opts)
144
148
  end
145
149
 
146
150
  def configure_session
@@ -204,32 +208,50 @@ class Chef
204
208
  list
205
209
  end
206
210
 
207
- def session_from_list(list)
208
- list.each do |item|
209
- host, ssh_port = item
210
- Chef::Log.debug("Adding #{host}")
211
- session_opts = {}
212
-
213
- ssh_config = Net::SSH.configuration_for(host)
214
-
211
+ # Net::SSH session options hash for global options. These should be
212
+ # options that will apply to the gateway connection in addition to the
213
+ # main one.
214
+ #
215
+ # @since 12.5.0
216
+ # @param host [String] Hostname for this session.
217
+ # @param port [String] SSH port for this session.
218
+ # @param user [String] Optional username for this session.
219
+ # @return [Hash<Symbol, Object>]
220
+ def session_options(host, port, user=nil)
221
+ ssh_config = Net::SSH.configuration_for(host)
222
+ {}.tap do |opts|
215
223
  # Chef::Config[:knife][:ssh_user] is parsed in #configure_user and written to config[:ssh_user]
216
- user = config[:ssh_user] || ssh_config[:user]
217
- hostspec = user ? "#{user}@#{host}" : host
218
- session_opts[:keys] = File.expand_path(config[:identity_file]) if config[:identity_file]
219
- session_opts[:keys_only] = true if config[:identity_file]
220
- session_opts[:password] = config[:ssh_password] if config[:ssh_password]
221
- session_opts[:forward_agent] = config[:forward_agent]
222
- session_opts[:port] = config[:ssh_port] ||
223
- ssh_port || # Use cloud port if available
224
- Chef::Config[:knife][:ssh_port] ||
225
- ssh_config[:port]
226
- session_opts[:logger] = Chef::Log.logger if Chef::Log.level == :debug
227
-
224
+ opts[:user] = user || config[:ssh_user] || ssh_config[:user]
225
+ if config[:identity_file]
226
+ opts[:keys] = File.expand_path(config[:identity_file])
227
+ opts[:keys_only] = true
228
+ elsif config[:ssh_password]
229
+ opts[:password] = config[:ssh_password]
230
+ end
231
+ # Don't set the keys to nil if we don't have them.
232
+ forward_agent = config[:forward_agent] || ssh_config[:forward_agent]
233
+ opts[:forward_agent] = forward_agent unless forward_agent.nil?
234
+ port ||= ssh_config[:port]
235
+ opts[:port] = port unless port.nil?
236
+ opts[:logger] = Chef::Log.logger if Chef::Log.level == :debug
228
237
  if !config[:host_key_verify]
229
- session_opts[:paranoid] = false
230
- session_opts[:user_known_hosts_file] = "/dev/null"
238
+ opts[:paranoid] = false
239
+ opts[:user_known_hosts_file] = '/dev/null'
231
240
  end
241
+ end
242
+ end
232
243
 
244
+ def session_from_list(list)
245
+ list.each do |item|
246
+ host, ssh_port = item
247
+ Chef::Log.debug("Adding #{host}")
248
+ session_opts = session_options(host, ssh_port)
249
+ # Handle port overrides for the main connection.
250
+ session_opts[:port] = Chef::Config[:knife][:ssh_port] if Chef::Config[:knife][:ssh_port]
251
+ session_opts[:port] = config[:ssh_port] if config[:ssh_port]
252
+ # Create the hostspec.
253
+ hostspec = session_opts[:user] ? "#{session_opts.delete(:user)}@#{host}" : host
254
+ # Connect a new session on the multi.
233
255
  session.use(hostspec, session_opts)
234
256
 
235
257
  @longest = host.length if host.length > @longest
@@ -405,7 +427,7 @@ class Chef
405
427
  begin
406
428
  require 'appscript'
407
429
  rescue LoadError
408
- STDERR.puts "you need the rb-appscript gem to use knife ssh macterm. `(sudo) gem install rb-appscript` to install"
430
+ STDERR.puts "You need the rb-appscript gem to use knife ssh macterm. `(sudo) gem install rb-appscript` to install"
409
431
  raise
410
432
  end
411
433
 
@@ -73,11 +73,12 @@ class Chef
73
73
  exit 1
74
74
  end
75
75
 
76
-
77
76
  def verify_peer_socket
78
77
  @verify_peer_socket ||= begin
79
78
  tcp_connection = TCPSocket.new(host, port)
80
- OpenSSL::SSL::SSLSocket.new(tcp_connection, verify_peer_ssl_context)
79
+ ssl_client = OpenSSL::SSL::SSLSocket.new(tcp_connection, verify_peer_ssl_context)
80
+ ssl_client.hostname = host
81
+ ssl_client
81
82
  end
82
83
  end
83
84
 
@@ -57,7 +57,6 @@ EOF
57
57
  end
58
58
 
59
59
  original_user = Chef::UserV1.load(@user_name).to_hash
60
-
61
60
  # DEPRECATION NOTE
62
61
  # Remove this if statement and corrosponding code post OSC 11 support.
63
62
  #
@@ -73,7 +72,7 @@ EOF
73
72
  user.update
74
73
  ui.msg("Saved #{user}.")
75
74
  else
76
- ui.msg("User unchaged, not saving.")
75
+ ui.msg("User unchanged, not saving.")
77
76
  end
78
77
  end
79
78
 
@@ -15,6 +15,11 @@
15
15
  # See the License for the specific language governing permissions and
16
16
  # limitations under the License.
17
17
  require 'chef/config'
18
+ if Chef::Platform.windows?
19
+ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.1')
20
+ require 'chef/monkey_patches/webrick-utils'
21
+ end
22
+ end
18
23
 
19
24
  class Chef
20
25
  module LocalMode
@@ -37,7 +37,11 @@ class Chef
37
37
  end
38
38
  end
39
39
 
40
- def self.deprecation(msg=nil, &block)
40
+ def self.deprecation(msg=nil, location=caller(2..2)[0], &block)
41
+ if msg
42
+ msg << " at #{Array(location).join("\n")}"
43
+ msg = msg.join("") if msg.respond_to?(:join)
44
+ end
41
45
  if Chef::Config[:treat_deprecation_warnings_as_errors]
42
46
  error(msg, &block)
43
47
  raise Chef::Exceptions::DeprecatedFeatureError.new(msg)
@@ -102,20 +102,20 @@ class Chef
102
102
 
103
103
  def deprecated_attr_reader(name, alternative, level=:warn)
104
104
  define_method(name) do
105
- Chef::Log.deprecation("#{self.class}.#{name} is deprecated. Support will be removed in a future release.")
106
- Chef::Log.deprecation(alternative)
107
- Chef::Log.deprecation("Called from:")
108
- caller[0..3].each {|c| Chef::Log.deprecation(c)}
105
+ Chef.log_deprecation("#{self.class}.#{name} is deprecated. Support will be removed in a future release.")
106
+ Chef.log_deprecation(alternative)
107
+ Chef.log_deprecation("Called from:")
108
+ caller[0..3].each {|c| Chef.log_deprecation(c)}
109
109
  instance_variable_get("@#{name}")
110
110
  end
111
111
  end
112
112
 
113
113
  def deprecated_attr_writer(name, alternative, level=:warn)
114
114
  define_method("#{name}=") do |value|
115
- Chef::Log.deprecation("Writing to #{self.class}.#{name} with #{name}= is deprecated. Support will be removed in a future release.")
116
- Chef::Log.deprecation(alternative)
117
- Chef::Log.deprecation("Called from:")
118
- caller[0..3].each {|c| Chef::Log.deprecation(c)}
115
+ Chef.log_deprecation("Writing to #{self.class}.#{name} with #{name}= is deprecated. Support will be removed in a future release.")
116
+ Chef.log_deprecation(alternative)
117
+ Chef.log_deprecation("Called from:")
118
+ caller[0..3].each {|c| Chef.log_deprecation(c)}
119
119
  instance_variable_set("@#{name}", value)
120
120
  end
121
121
  end
@@ -15,9 +15,11 @@
15
15
  # See the License for the specific language governing permissions and
16
16
  # limitations under the License.
17
17
 
18
+ require 'chef/constants'
19
+ require 'chef/property'
20
+ require 'chef/delayed_evaluator'
21
+
18
22
  class Chef
19
- class DelayedEvaluator < Proc
20
- end
21
23
  module Mixin
22
24
  module ParamsValidate
23
25
 
@@ -32,20 +34,55 @@ class Chef
32
34
  # Would raise an exception if the value of :one above is not a kind_of? string. Valid
33
35
  # map options are:
34
36
  #
35
- # :default:: Sets the default value for this parameter.
36
- # :callbacks:: Takes a hash of Procs, which should return true if the argument is valid.
37
- # The key will be inserted into the error message if the Proc does not return true:
38
- # "Option #{key}'s value #{value} #{message}!"
39
- # :kind_of:: Ensure that the value is a kind_of?(Whatever). If passed an array, it will ensure
40
- # that the value is one of those types.
41
- # :respond_to:: Ensure that the value has a given method. Takes one method name or an array of
42
- # method names.
43
- # :required:: Raise an exception if this parameter is missing. Valid values are true or false,
44
- # by default, options are not required.
45
- # :regex:: Match the value of the parameter against a regular expression.
46
- # :equal_to:: Match the value of the parameter with ==. An array means it can be equal to any
47
- # of the values.
37
+ # @param opts [Hash<Symbol,Object>] Validation opts.
38
+ # @option opts [Object,Array] :is An object, or list of
39
+ # objects, that must match the value using Ruby's `===` operator
40
+ # (`opts[:is].any? { |v| v === value }`). (See #_pv_is.)
41
+ # @option opts [Object,Array] :equal_to An object, or list
42
+ # of objects, that must be equal to the value using Ruby's `==`
43
+ # operator (`opts[:is].any? { |v| v == value }`) (See #_pv_equal_to.)
44
+ # @option opts [Regexp,Array<Regexp>] :regex An object, or
45
+ # list of objects, that must match the value with `regex.match(value)`.
46
+ # (See #_pv_regex)
47
+ # @option opts [Class,Array<Class>] :kind_of A class, or
48
+ # list of classes, that the value must be an instance of. (See
49
+ # #_pv_kind_of.)
50
+ # @option opts [Hash<String,Proc>] :callbacks A hash of
51
+ # messages -> procs, all of which match the value. The proc must
52
+ # return a truthy or falsey value (true means it matches). (See
53
+ # #_pv_callbacks.)
54
+ # @option opts [Symbol,Array<Symbol>] :respond_to A method
55
+ # name, or list of method names, the value must respond to. (See
56
+ # #_pv_respond_to.)
57
+ # @option opts [Symbol,Array<Symbol>] :cannot_be A property,
58
+ # or a list of properties, that the value cannot have (such as `:nil` or
59
+ # `:empty`). The method with a questionmark at the end is called on the
60
+ # value (e.g. `value.empty?`). If the value does not have this method,
61
+ # it is considered valid (i.e. if you don't respond to `empty?` we
62
+ # assume you are not empty). (See #_pv_cannot_be.)
63
+ # @option opts [Proc] :coerce A proc which will be called to
64
+ # transform the user input to canonical form. The value is passed in,
65
+ # and the transformed value returned as output. Lazy values will *not*
66
+ # be passed to this method until after they are evaluated. Called in the
67
+ # context of the resource (meaning you can access other properties).
68
+ # (See #_pv_coerce.) (See #_pv_coerce.)
69
+ # @option opts [Boolean] :required `true` if this property
70
+ # must be present and not `nil`; `false` otherwise. This is checked
71
+ # after the resource is fully initialized. (See #_pv_required.)
72
+ # @option opts [Boolean] :name_property `true` if this
73
+ # property defaults to the same value as `name`. Equivalent to
74
+ # `default: lazy { name }`, except that #property_is_set? will
75
+ # return `true` if the property is set *or* if `name` is set. (See
76
+ # #_pv_name_property.)
77
+ # @option opts [Boolean] :name_attribute Same as `name_property`.
78
+ # @option opts [Object] :default The value this property
79
+ # will return if the user does not set one. If this is `lazy`, it will
80
+ # be run in the context of the instance (and able to access other
81
+ # properties). (See #_pv_default.)
82
+ #
48
83
  def validate(opts, map)
84
+ map = map.validation_options if map.is_a?(Property)
85
+
49
86
  #--
50
87
  # validate works by taking the keys in the validation map, assuming it's a hash, and
51
88
  # looking for _pv_:symbol as methods. Assuming it find them, it calls the right
@@ -65,7 +102,7 @@ class Chef
65
102
  true
66
103
  when Hash
67
104
  validation.each do |check, carg|
68
- check_method = "_pv_#{check.to_s}"
105
+ check_method = "_pv_#{check}"
69
106
  if self.respond_to?(check_method, true)
70
107
  self.send(check_method, opts, key, carg)
71
108
  else
@@ -81,162 +118,352 @@ class Chef
81
118
  DelayedEvaluator.new(&block)
82
119
  end
83
120
 
84
- def set_or_return(symbol, arg, validation)
85
- iv_symbol = "@#{symbol.to_s}".to_sym
86
- if arg == nil && self.instance_variable_defined?(iv_symbol) == true
87
- ivar = self.instance_variable_get(iv_symbol)
88
- if(ivar.is_a?(DelayedEvaluator))
89
- validate({ symbol => ivar.call }, { symbol => validation })[symbol]
90
- else
91
- ivar
92
- end
93
- else
94
- if(arg.is_a?(DelayedEvaluator))
95
- val = arg
96
- else
97
- val = validate({ symbol => arg }, { symbol => validation })[symbol]
121
+ def set_or_return(symbol, value, validation)
122
+ property = SetOrReturnProperty.new(name: symbol, **validation)
123
+ property.call(self, value)
124
+ end
98
125
 
99
- # Handle the case where the "default" was a DelayedEvaluator. In
100
- # this case, the block yields an optional parameter of +self+,
101
- # which is the equivalent of "new_resource"
102
- if val.is_a?(DelayedEvaluator)
103
- val = val.call(self)
104
- end
105
- end
106
- self.instance_variable_set(iv_symbol, val)
126
+ private
127
+
128
+ def explicitly_allows_nil?(key, validation)
129
+ validation.has_key?(:is) && _pv_is({ key => nil }, key, validation[:is], raise_error: false)
130
+ end
131
+
132
+ # Return the value of a parameter, or nil if it doesn't exist.
133
+ def _pv_opts_lookup(opts, key)
134
+ if opts.has_key?(key.to_s)
135
+ opts[key.to_s]
136
+ elsif opts.has_key?(key.to_sym)
137
+ opts[key.to_sym]
138
+ else
139
+ nil
107
140
  end
108
141
  end
109
142
 
110
- private
143
+ # Raise an exception if the parameter is not found.
144
+ def _pv_required(opts, key, is_required=true, explicitly_allows_nil=false)
145
+ if is_required
146
+ return true if opts.has_key?(key.to_s) && (explicitly_allows_nil || !opts[key.to_s].nil?)
147
+ return true if opts.has_key?(key.to_sym) && (explicitly_allows_nil || !opts[key.to_sym].nil?)
148
+ raise Exceptions::ValidationFailed, "Required argument #{key.inspect} is missing!"
149
+ end
150
+ true
151
+ end
111
152
 
112
- # Return the value of a parameter, or nil if it doesn't exist.
113
- def _pv_opts_lookup(opts, key)
114
- if opts.has_key?(key.to_s)
115
- opts[key.to_s]
116
- elsif opts.has_key?(key.to_sym)
117
- opts[key.to_sym]
118
- else
119
- nil
153
+ #
154
+ # List of things values must be equal to.
155
+ #
156
+ # Uses Ruby's `==` to evaluate (equal_to == value). At least one must
157
+ # match for the value to be valid.
158
+ #
159
+ # `nil` passes this validation automatically.
160
+ #
161
+ # @return [Array,nil] List of things values must be equal to, or nil if
162
+ # equal_to is unspecified.
163
+ #
164
+ def _pv_equal_to(opts, key, to_be)
165
+ value = _pv_opts_lookup(opts, key)
166
+ unless value.nil?
167
+ to_be = Array(to_be)
168
+ to_be.each do |tb|
169
+ return true if value == tb
120
170
  end
171
+ raise Exceptions::ValidationFailed, "Option #{key} must be equal to one of: #{to_be.join(", ")}! You passed #{value.inspect}."
121
172
  end
173
+ end
122
174
 
123
- # Raise an exception if the parameter is not found.
124
- def _pv_required(opts, key, is_required=true)
125
- if is_required
126
- if (opts.has_key?(key.to_s) && !opts[key.to_s].nil?) ||
127
- (opts.has_key?(key.to_sym) && !opts[key.to_sym].nil?)
128
- true
129
- else
130
- raise Exceptions::ValidationFailed, "Required argument #{key} is missing!"
131
- end
175
+ #
176
+ # List of things values must be instances of.
177
+ #
178
+ # Uses value.kind_of?(kind_of) to evaluate. At least one must match for
179
+ # the value to be valid.
180
+ #
181
+ # `nil` automatically passes this validation.
182
+ #
183
+ def _pv_kind_of(opts, key, to_be)
184
+ value = _pv_opts_lookup(opts, key)
185
+ unless value.nil?
186
+ to_be = Array(to_be)
187
+ to_be.each do |tb|
188
+ return true if value.kind_of?(tb)
132
189
  end
190
+ raise Exceptions::ValidationFailed, "Option #{key} must be a kind of #{to_be}! You passed #{value.inspect}."
133
191
  end
192
+ end
134
193
 
135
- def _pv_equal_to(opts, key, to_be)
136
- value = _pv_opts_lookup(opts, key)
137
- unless value.nil?
138
- passes = false
139
- Array(to_be).each do |tb|
140
- passes = true if value == tb
141
- end
142
- unless passes
143
- raise Exceptions::ValidationFailed, "Option #{key} must be equal to one of: #{to_be.join(", ")}! You passed #{value.inspect}."
194
+ #
195
+ # List of method names values must respond to.
196
+ #
197
+ # Uses value.respond_to?(respond_to) to evaluate. At least one must match
198
+ # for the value to be valid.
199
+ #
200
+ def _pv_respond_to(opts, key, method_name_list)
201
+ value = _pv_opts_lookup(opts, key)
202
+ unless value.nil?
203
+ Array(method_name_list).each do |method_name|
204
+ unless value.respond_to?(method_name)
205
+ raise Exceptions::ValidationFailed, "Option #{key} must have a #{method_name} method!"
144
206
  end
145
207
  end
146
208
  end
209
+ end
147
210
 
148
- # Raise an exception if the parameter is not a kind_of?(to_be)
149
- def _pv_kind_of(opts, key, to_be)
150
- value = _pv_opts_lookup(opts, key)
151
- unless value.nil?
152
- passes = false
153
- Array(to_be).each do |tb|
154
- passes = true if value.kind_of?(tb)
155
- end
156
- unless passes
157
- raise Exceptions::ValidationFailed, "Option #{key} must be a kind of #{to_be}! You passed #{value.inspect}."
211
+ #
212
+ # List of things that must not be true about the value.
213
+ #
214
+ # Calls `value.<thing>?` All responses must be false for the value to be
215
+ # valid.
216
+ # Values which do not respond to <thing>? are considered valid (because if
217
+ # a value doesn't respond to `:readable?`, then it probably isn't
218
+ # readable.)
219
+ #
220
+ # @example
221
+ # ```ruby
222
+ # property :x, cannot_be: [ :nil, :empty ]
223
+ # x [ 1, 2 ] #=> valid
224
+ # x 1 #=> valid
225
+ # x [] #=> invalid
226
+ # x nil #=> invalid
227
+ # ```
228
+ #
229
+ def _pv_cannot_be(opts, key, predicate_method_base_name)
230
+ value = _pv_opts_lookup(opts, key)
231
+ if !value.nil?
232
+ Array(predicate_method_base_name).each do |method_name|
233
+ predicate_method = :"#{method_name}?"
234
+
235
+ if value.respond_to?(predicate_method)
236
+ if value.send(predicate_method)
237
+ raise Exceptions::ValidationFailed, "Option #{key} cannot be #{predicate_method_base_name}"
238
+ end
158
239
  end
159
240
  end
160
241
  end
242
+ end
161
243
 
162
- # Raise an exception if the parameter does not respond to a given set of methods.
163
- def _pv_respond_to(opts, key, method_name_list)
164
- value = _pv_opts_lookup(opts, key)
165
- unless value.nil?
166
- Array(method_name_list).each do |method_name|
167
- unless value.respond_to?(method_name)
168
- raise Exceptions::ValidationFailed, "Option #{key} must have a #{method_name} method!"
169
- end
170
- end
244
+ #
245
+ # The default value for a property.
246
+ #
247
+ # When the property is not assigned, this will be used.
248
+ #
249
+ # If this is a lazy value, it will either be passed the resource as a value,
250
+ # or if the lazy proc does not take parameters, it will be run in the
251
+ # context of the instance with instance_eval.
252
+ #
253
+ # @example
254
+ # ```ruby
255
+ # property :x, default: 10
256
+ # ```
257
+ #
258
+ # @example
259
+ # ```ruby
260
+ # property :x
261
+ # property :y, default: lazy { x+2 }
262
+ # ```
263
+ #
264
+ # @example
265
+ # ```ruby
266
+ # property :x
267
+ # property :y, default: lazy { |r| r.x+2 }
268
+ # ```
269
+ #
270
+ def _pv_default(opts, key, default_value)
271
+ value = _pv_opts_lookup(opts, key)
272
+ if value.nil?
273
+ default_value = default_value.freeze if !default_value.is_a?(DelayedEvaluator)
274
+ opts[key] = default_value
275
+ end
276
+ end
277
+
278
+ #
279
+ # List of regexes values that must match.
280
+ #
281
+ # Uses regex.match() to evaluate. At least one must match for the value to
282
+ # be valid.
283
+ #
284
+ # `nil` passes regex validation automatically.
285
+ #
286
+ # @example
287
+ # ```ruby
288
+ # property :x, regex: [ /abc/, /xyz/ ]
289
+ # ```
290
+ #
291
+ def _pv_regex(opts, key, regex)
292
+ value = _pv_opts_lookup(opts, key)
293
+ if !value.nil?
294
+ Array(regex).flatten.each do |r|
295
+ return true if r.match(value.to_s)
171
296
  end
297
+ raise Exceptions::ValidationFailed, "Option #{key}'s value #{value} does not match regular expression #{regex.inspect}"
172
298
  end
299
+ end
173
300
 
174
- # Assert that parameter returns false when passed a predicate method.
175
- # For example, :cannot_be => :blank will raise a Exceptions::ValidationFailed
176
- # error value.blank? returns a 'truthy' (not nil or false) value.
177
- #
178
- # Note, this will *PASS* if the object doesn't respond to the method.
179
- # So, to make sure a value is not nil and not blank, you need to do
180
- # both :cannot_be => :blank *and* :cannot_be => :nil (or :required => true)
181
- def _pv_cannot_be(opts, key, predicate_method_base_name)
182
- value = _pv_opts_lookup(opts, key)
183
- predicate_method = (predicate_method_base_name.to_s + "?").to_sym
184
-
185
- if value.respond_to?(predicate_method)
186
- if value.send(predicate_method)
187
- raise Exceptions::ValidationFailed, "Option #{key} cannot be #{predicate_method_base_name}"
301
+ #
302
+ # List of procs we pass the value to.
303
+ #
304
+ # All procs must return true for the value to be valid. If any procs do
305
+ # not return true, the key will be used for the message: `"Property x's
306
+ # value :y <message>"`.
307
+ #
308
+ # @example
309
+ # ```ruby
310
+ # property :x, callbacks: { "is bigger than 10" => proc { |v| v <= 10 }, "is not awesome" => proc { |v| !v.awesome }}
311
+ # ```
312
+ #
313
+ def _pv_callbacks(opts, key, callbacks)
314
+ raise ArgumentError, "Callback list must be a hash!" unless callbacks.kind_of?(Hash)
315
+ value = _pv_opts_lookup(opts, key)
316
+ if !value.nil?
317
+ callbacks.each do |message, zeproc|
318
+ unless zeproc.call(value)
319
+ raise Exceptions::ValidationFailed, "Option #{key}'s value #{value} #{message}!"
188
320
  end
189
321
  end
190
322
  end
323
+ end
191
324
 
192
- # Assign a default value to a parameter.
193
- def _pv_default(opts, key, default_value)
194
- value = _pv_opts_lookup(opts, key)
195
- if value == nil
196
- opts[key] = default_value
325
+ #
326
+ # Allows a parameter to default to the value of the resource name.
327
+ #
328
+ # @example
329
+ # ```ruby
330
+ # property :x, name_property: true
331
+ # ```
332
+ #
333
+ def _pv_name_property(opts, key, is_name_property=true)
334
+ if is_name_property
335
+ if opts[key].nil?
336
+ opts[key] = self.instance_variable_get(:"@name")
197
337
  end
198
338
  end
339
+ end
340
+ alias :_pv_name_attribute :_pv_name_property
199
341
 
200
- # Check a parameter against a regular expression.
201
- def _pv_regex(opts, key, regex)
202
- value = _pv_opts_lookup(opts, key)
203
- if value != nil
204
- passes = false
205
- [ regex ].flatten.each do |r|
206
- if value != nil
207
- if r.match(value.to_s)
208
- passes = true
209
- end
210
- end
211
- end
212
- unless passes
213
- raise Exceptions::ValidationFailed, "Option #{key}'s value #{value} does not match regular expression #{regex.inspect}"
214
- end
342
+ #
343
+ # List of valid things values can be.
344
+ #
345
+ # Uses Ruby's `===` to evaluate (is === value). At least one must match
346
+ # for the value to be valid.
347
+ #
348
+ # If a proc is passed, it is instance_eval'd in the resource, passed the
349
+ # value, and must return a truthy or falsey value.
350
+ #
351
+ # @example Class
352
+ # ```ruby
353
+ # property :x, String
354
+ # x 'valid' #=> valid
355
+ # x 1 #=> invalid
356
+ # x nil #=> invalid
357
+ #
358
+ # @example Value
359
+ # ```ruby
360
+ # property :x, [ :a, :b, :c, nil ]
361
+ # x :a #=> valid
362
+ # x nil #=> valid
363
+ # ```
364
+ #
365
+ # @example Regex
366
+ # ```ruby
367
+ # property :x, /bar/
368
+ # x 'foobar' #=> valid
369
+ # x 'foo' #=> invalid
370
+ # x nil #=> invalid
371
+ # ```
372
+ #
373
+ # @example Proc
374
+ # ```ruby
375
+ # property :x, proc { |x| x > y }
376
+ # property :y, default: 2
377
+ # x 3 #=> valid
378
+ # x 1 #=> invalid
379
+ # ```
380
+ #
381
+ # @example Property
382
+ # ```ruby
383
+ # type = Property.new(is: String)
384
+ # property :x, type
385
+ # x 'foo' #=> valid
386
+ # x 1 #=> invalid
387
+ # x nil #=> invalid
388
+ # ```
389
+ #
390
+ # @example RSpec Matcher
391
+ # ```ruby
392
+ # include RSpec::Matchers
393
+ # property :x, a_string_matching /bar/
394
+ # x 'foobar' #=> valid
395
+ # x 'foo' #=> invalid
396
+ # x nil #=> invalid
397
+ # ```
398
+ #
399
+ def _pv_is(opts, key, to_be, raise_error: true)
400
+ return true if !opts.has_key?(key.to_s) && !opts.has_key?(key.to_sym)
401
+ value = _pv_opts_lookup(opts, key)
402
+ to_be = [ to_be ].flatten(1)
403
+ to_be.each do |tb|
404
+ case tb
405
+ when Proc
406
+ return true if instance_exec(value, &tb)
407
+ when Property
408
+ validate(opts, { key => tb.validation_options })
409
+ return true
410
+ else
411
+ return true if tb === value
215
412
  end
216
413
  end
217
414
 
218
- # Check a parameter against a hash of proc's.
219
- def _pv_callbacks(opts, key, callbacks)
220
- raise ArgumentError, "Callback list must be a hash!" unless callbacks.kind_of?(Hash)
221
- value = _pv_opts_lookup(opts, key)
222
- if value != nil
223
- callbacks.each do |message, zeproc|
224
- if zeproc.call(value) != true
225
- raise Exceptions::ValidationFailed, "Option #{key}'s value #{value} #{message}!"
226
- end
227
- end
415
+ if raise_error
416
+ raise Exceptions::ValidationFailed, "Option #{key} must be one of: #{to_be.join(", ")}! You passed #{value.inspect}."
417
+ else
418
+ false
419
+ end
420
+ end
421
+
422
+ #
423
+ # Method to mess with a value before it is validated and stored.
424
+ #
425
+ # Allows you to transform values into a canonical form that is easy to
426
+ # work with.
427
+ #
428
+ # This is passed the value to transform, and is run in the context of the
429
+ # instance (so it has access to other resource properties). It must return
430
+ # the value that will be stored in the instance.
431
+ #
432
+ # @example
433
+ # ```ruby
434
+ # property :x, Integer, coerce: { |v| v.to_i }
435
+ # ```
436
+ #
437
+ def _pv_coerce(opts, key, coercer)
438
+ if opts.has_key?(key.to_s)
439
+ opts[key.to_s] = instance_exec(opts[key], &coercer)
440
+ elsif opts.has_key?(key.to_sym)
441
+ opts[key.to_sym] = instance_exec(opts[key], &coercer)
442
+ end
443
+ end
444
+
445
+ # Used by #set_or_return to avoid emitting a deprecation warning for
446
+ # "value nil" and to keep default stickiness working exactly the same
447
+ # @api private
448
+ class SetOrReturnProperty < Chef::Property
449
+ def get(resource)
450
+ value = super
451
+ # All values are sticky, frozen or not
452
+ if !is_set?(resource)
453
+ set_value(resource, value)
228
454
  end
455
+ value
229
456
  end
230
457
 
231
- # Allow a parameter to default to @name
232
- def _pv_name_attribute(opts, key, is_name_attribute=true)
233
- if is_name_attribute
234
- if opts[key] == nil
235
- opts[key] = self.instance_variable_get("@name")
236
- end
458
+ def call(resource, value=NOT_PASSED)
459
+ # setting to nil does a get
460
+ if value.nil? && !explicitly_accepts_nil?(resource)
461
+ get(resource)
462
+ else
463
+ super
237
464
  end
238
465
  end
466
+ end
239
467
  end
240
468
  end
241
469
  end
242
-