chef 12.4.0.rc.0-universal-mingw32 → 12.4.0.rc.2-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 (298) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +12 -1
  3. data/lib/chef/api_client.rb +130 -26
  4. data/lib/chef/application.rb +0 -1
  5. data/lib/chef/application/client.rb +8 -19
  6. data/lib/chef/audit/audit_reporter.rb +12 -7
  7. data/lib/chef/audit/logger.rb +36 -0
  8. data/lib/chef/audit/runner.rb +4 -2
  9. data/lib/chef/chef_class.rb +62 -11
  10. data/lib/chef/client.rb +587 -207
  11. data/lib/chef/config.rb +0 -1
  12. data/lib/chef/dsl/recipe.rb +45 -56
  13. data/lib/chef/dsl/resources.rb +3 -2
  14. data/lib/chef/event_dispatch/base.rb +7 -2
  15. data/lib/chef/exceptions.rb +4 -1
  16. data/lib/chef/file_content_management/deploy/mv_windows.rb +16 -6
  17. data/lib/chef/formatters/doc.rb +15 -7
  18. data/lib/chef/formatters/error_inspectors/api_error_formatting.rb +10 -7
  19. data/lib/chef/guard_interpreter/default_guard_interpreter.rb +2 -0
  20. data/lib/chef/guard_interpreter/resource_guard_interpreter.rb +4 -1
  21. data/lib/chef/http/authenticator.rb +7 -2
  22. data/lib/chef/knife.rb +16 -4
  23. data/lib/chef/knife/client_create.rb +55 -31
  24. data/lib/chef/knife/core/generic_presenter.rb +1 -1
  25. data/lib/chef/knife/core/subcommand_loader.rb +1 -1
  26. data/lib/chef/knife/osc_user_create.rb +97 -0
  27. data/lib/chef/knife/osc_user_delete.rb +51 -0
  28. data/lib/chef/knife/osc_user_edit.rb +58 -0
  29. data/lib/chef/knife/osc_user_list.rb +47 -0
  30. data/lib/chef/knife/osc_user_reregister.rb +64 -0
  31. data/lib/chef/knife/osc_user_show.rb +54 -0
  32. data/lib/chef/knife/user_create.rb +95 -36
  33. data/lib/chef/knife/user_delete.rb +52 -2
  34. data/lib/chef/knife/user_edit.rb +37 -7
  35. data/lib/chef/knife/user_list.rb +3 -0
  36. data/lib/chef/knife/user_reregister.rb +39 -8
  37. data/lib/chef/knife/user_show.rb +30 -1
  38. data/lib/chef/mixin/api_version_request_handling.rb +66 -0
  39. data/lib/chef/mixin/convert_to_class_name.rb +10 -4
  40. data/lib/chef/mixin/deprecation.rb +24 -0
  41. data/lib/chef/mixin/powershell_out.rb +98 -0
  42. data/lib/chef/mixin/provides.rb +5 -18
  43. data/lib/chef/mixin/uris.rb +11 -0
  44. data/lib/chef/mixin/windows_architecture_helper.rb +5 -2
  45. data/lib/chef/mixin/windows_env_helper.rb +11 -2
  46. data/lib/chef/node_map.rb +130 -75
  47. data/lib/chef/osc_user.rb +194 -0
  48. data/lib/chef/platform/provider_mapping.rb +2 -269
  49. data/lib/chef/platform/provider_priority_map.rb +6 -69
  50. data/lib/chef/platform/query_helpers.rb +5 -0
  51. data/lib/chef/platform/resource_priority_map.rb +12 -15
  52. data/lib/chef/policy_builder/policyfile.rb +1 -0
  53. data/lib/chef/provider.rb +19 -0
  54. data/lib/chef/provider/directory.rb +3 -0
  55. data/lib/chef/provider/dsc_resource.rb +8 -1
  56. data/lib/chef/provider/file.rb +1 -0
  57. data/lib/chef/provider/group/aix.rb +1 -0
  58. data/lib/chef/provider/group/dscl.rb +1 -1
  59. data/lib/chef/provider/group/gpasswd.rb +1 -0
  60. data/lib/chef/provider/group/groupmod.rb +1 -1
  61. data/lib/chef/provider/group/pw.rb +1 -0
  62. data/lib/chef/provider/group/suse.rb +2 -0
  63. data/lib/chef/provider/group/usermod.rb +2 -1
  64. data/lib/chef/provider/group/windows.rb +1 -1
  65. data/lib/chef/provider/ifconfig.rb +2 -0
  66. data/lib/chef/provider/ifconfig/aix.rb +1 -0
  67. data/lib/chef/provider/ifconfig/debian.rb +2 -0
  68. data/lib/chef/provider/ifconfig/redhat.rb +1 -0
  69. data/lib/chef/provider/lwrp_base.rb +4 -0
  70. data/lib/chef/provider/mount.rb +0 -1
  71. data/lib/chef/provider/mount/aix.rb +1 -0
  72. data/lib/chef/provider/mount/mount.rb +2 -0
  73. data/lib/chef/provider/mount/solaris.rb +2 -0
  74. data/lib/chef/provider/package.rb +55 -0
  75. data/lib/chef/provider/package/aix.rb +7 -7
  76. data/lib/chef/provider/package/apt.rb +3 -3
  77. data/lib/chef/provider/package/dpkg.rb +4 -4
  78. data/lib/chef/provider/package/easy_install.rb +5 -5
  79. data/lib/chef/provider/package/freebsd/base.rb +2 -2
  80. data/lib/chef/provider/package/freebsd/pkg.rb +6 -6
  81. data/lib/chef/provider/package/freebsd/pkgng.rb +5 -5
  82. data/lib/chef/provider/package/freebsd/port.rb +4 -4
  83. data/lib/chef/provider/package/homebrew.rb +2 -2
  84. data/lib/chef/provider/package/ips.rb +4 -4
  85. data/lib/chef/provider/package/macports.rb +5 -6
  86. data/lib/chef/provider/package/openbsd.rb +4 -5
  87. data/lib/chef/provider/package/pacman.rb +4 -4
  88. data/lib/chef/provider/package/portage.rb +2 -0
  89. data/lib/chef/provider/package/rpm.rb +7 -8
  90. data/lib/chef/provider/package/rubygems.rb +5 -12
  91. data/lib/chef/provider/package/smartos.rb +4 -4
  92. data/lib/chef/provider/package/solaris.rb +7 -7
  93. data/lib/chef/provider/package/windows/msi.rb +1 -1
  94. data/lib/chef/provider/package/yum.rb +4 -6
  95. data/lib/chef/provider/package/zypper.rb +16 -14
  96. data/lib/chef/provider/powershell_script.rb +129 -47
  97. data/lib/chef/provider/remote_file/content.rb +4 -1
  98. data/lib/chef/provider/remote_file/local_file.rb +10 -4
  99. data/lib/chef/provider/service.rb +44 -0
  100. data/lib/chef/provider/service/freebsd.rb +1 -1
  101. data/lib/chef/provider/service/init.rb +1 -0
  102. data/lib/chef/provider/service/macosx.rb +1 -1
  103. data/lib/chef/provider/service/windows.rb +0 -1
  104. data/lib/chef/provider/user.rb +1 -1
  105. data/lib/chef/provider/user/aix.rb +3 -2
  106. data/lib/chef/provider/user/pw.rb +1 -0
  107. data/lib/chef/provider/user/solaris.rb +2 -0
  108. data/lib/chef/provider/user/useradd.rb +1 -0
  109. data/lib/chef/provider_resolver.rb +87 -134
  110. data/lib/chef/resource.rb +274 -68
  111. data/lib/chef/resource/apt_package.rb +0 -2
  112. data/lib/chef/resource/bash.rb +0 -2
  113. data/lib/chef/resource/batch.rb +1 -1
  114. data/lib/chef/resource/bff_package.rb +0 -7
  115. data/lib/chef/resource/breakpoint.rb +3 -6
  116. data/lib/chef/resource/chef_gem.rb +0 -3
  117. data/lib/chef/resource/cookbook_file.rb +1 -3
  118. data/lib/chef/resource/cron.rb +2 -4
  119. data/lib/chef/resource/csh.rb +0 -2
  120. data/lib/chef/resource/deploy.rb +9 -6
  121. data/lib/chef/resource/deploy_revision.rb +0 -14
  122. data/lib/chef/resource/directory.rb +2 -4
  123. data/lib/chef/resource/dpkg_package.rb +0 -5
  124. data/lib/chef/resource/dsc_resource.rb +2 -3
  125. data/lib/chef/resource/dsc_script.rb +2 -3
  126. data/lib/chef/resource/easy_install_package.rb +0 -7
  127. data/lib/chef/resource/env.rb +3 -3
  128. data/lib/chef/resource/erl_call.rb +2 -5
  129. data/lib/chef/resource/execute.rb +2 -4
  130. data/lib/chef/resource/file.rb +2 -4
  131. data/lib/chef/resource/freebsd_package.rb +0 -5
  132. data/lib/chef/resource/gem_package.rb +0 -3
  133. data/lib/chef/resource/git.rb +0 -3
  134. data/lib/chef/resource/group.rb +2 -4
  135. data/lib/chef/resource/homebrew_package.rb +0 -2
  136. data/lib/chef/resource/http_request.rb +3 -4
  137. data/lib/chef/resource/ifconfig.rb +3 -4
  138. data/lib/chef/resource/ips_package.rb +2 -2
  139. data/lib/chef/resource/link.rb +3 -5
  140. data/lib/chef/resource/log.rb +2 -4
  141. data/lib/chef/resource/lwrp_base.rb +10 -61
  142. data/lib/chef/resource/macosx_service.rb +1 -2
  143. data/lib/chef/resource/macports_package.rb +0 -7
  144. data/lib/chef/resource/mdadm.rb +2 -5
  145. data/lib/chef/resource/mount.rb +2 -4
  146. data/lib/chef/resource/ohai.rb +2 -4
  147. data/lib/chef/resource/openbsd_package.rb +0 -6
  148. data/lib/chef/resource/package.rb +9 -6
  149. data/lib/chef/resource/pacman_package.rb +0 -7
  150. data/lib/chef/resource/paludis_package.rb +2 -3
  151. data/lib/chef/resource/perl.rb +0 -3
  152. data/lib/chef/resource/portage_package.rb +0 -3
  153. data/lib/chef/resource/powershell_script.rb +1 -2
  154. data/lib/chef/resource/python.rb +0 -3
  155. data/lib/chef/resource/reboot.rb +1 -3
  156. data/lib/chef/resource/registry_key.rb +3 -5
  157. data/lib/chef/resource/remote_directory.rb +3 -5
  158. data/lib/chef/resource/remote_file.rb +4 -5
  159. data/lib/chef/resource/route.rb +3 -5
  160. data/lib/chef/resource/rpm_package.rb +0 -2
  161. data/lib/chef/resource/ruby.rb +0 -4
  162. data/lib/chef/resource/ruby_block.rb +2 -4
  163. data/lib/chef/resource/scm.rb +3 -5
  164. data/lib/chef/resource/script.rb +0 -3
  165. data/lib/chef/resource/service.rb +3 -5
  166. data/lib/chef/resource/smartos_package.rb +0 -9
  167. data/lib/chef/resource/solaris_package.rb +0 -10
  168. data/lib/chef/resource/subversion.rb +1 -3
  169. data/lib/chef/resource/template.rb +0 -4
  170. data/lib/chef/resource/timestamped_deploy.rb +0 -4
  171. data/lib/chef/resource/user.rb +2 -5
  172. data/lib/chef/resource/whyrun_safe_ruby_block.rb +0 -7
  173. data/lib/chef/resource/windows_package.rb +3 -3
  174. data/lib/chef/resource/windows_script.rb +2 -2
  175. data/lib/chef/resource/windows_service.rb +3 -3
  176. data/lib/chef/resource/yum_package.rb +0 -3
  177. data/lib/chef/resource/zypper_package.rb +27 -0
  178. data/lib/chef/resource_builder.rb +7 -0
  179. data/lib/chef/resource_reporter.rb +1 -1
  180. data/lib/chef/resource_resolver.rb +108 -62
  181. data/lib/chef/resources.rb +1 -0
  182. data/lib/chef/rest.rb +1 -0
  183. data/lib/chef/server_api.rb +2 -0
  184. data/lib/chef/user.rb +193 -42
  185. data/lib/chef/util/backup.rb +9 -1
  186. data/lib/chef/util/path_helper.rb +0 -1
  187. data/lib/chef/version.rb +1 -1
  188. data/spec/functional/audit/runner_spec.rb +22 -42
  189. data/spec/functional/mixin/powershell_out_spec.rb +43 -0
  190. data/spec/functional/resource/execute_spec.rb +9 -2
  191. data/spec/functional/resource/file_spec.rb +25 -0
  192. data/spec/functional/resource/group_spec.rb +5 -0
  193. data/spec/functional/resource/link_spec.rb +5 -11
  194. data/spec/functional/resource/powershell_spec.rb +40 -5
  195. data/spec/functional/resource/user/useradd_spec.rb +10 -18
  196. data/spec/integration/recipes/lwrp_spec.rb +57 -0
  197. data/spec/integration/recipes/provider_choice.rb +2 -7
  198. data/spec/integration/recipes/recipe_dsl_spec.rb +517 -19
  199. data/spec/spec_helper.rb +1 -1
  200. data/spec/support/lib/chef/provider/openldap_includer.rb +29 -0
  201. data/spec/support/lib/chef/resource/cat.rb +0 -2
  202. data/spec/support/lib/chef/resource/one_two_three_four.rb +0 -6
  203. data/spec/support/lib/chef/resource/openldap_includer.rb +27 -0
  204. data/spec/support/lib/chef/resource/with_state.rb +0 -9
  205. data/spec/support/lib/chef/resource/zen_follower.rb +0 -6
  206. data/spec/support/lib/chef/resource/zen_master.rb +1 -6
  207. data/spec/support/shared/context/client.rb +277 -0
  208. data/spec/support/shared/examples/client.rb +53 -0
  209. data/spec/support/shared/functional/file_resource.rb +0 -4
  210. data/spec/support/shared/functional/securable_resource.rb +0 -24
  211. data/spec/support/shared/functional/securable_resource_with_reporting.rb +4 -4
  212. data/spec/support/shared/functional/windows_script.rb +1 -1
  213. data/spec/support/shared/unit/api_versioning.rb +77 -0
  214. data/spec/support/shared/unit/knife_shared.rb +40 -0
  215. data/spec/support/shared/unit/user_and_client_shared.rb +115 -0
  216. data/spec/unit/api_client_spec.rb +189 -14
  217. data/spec/unit/application/client_spec.rb +0 -5
  218. data/spec/unit/audit/audit_reporter_spec.rb +58 -14
  219. data/spec/unit/audit/logger_spec.rb +42 -0
  220. data/spec/unit/audit/runner_spec.rb +2 -2
  221. data/spec/unit/chef_fs/file_pattern_spec.rb +3 -15
  222. data/spec/unit/client_spec.rb +58 -374
  223. data/spec/unit/cookbook_spec.rb +0 -9
  224. data/spec/unit/cookbook_version_spec.rb +0 -20
  225. data/spec/unit/deprecation_spec.rb +55 -0
  226. data/spec/unit/dsl/resources_spec.rb +85 -0
  227. data/spec/unit/exceptions_spec.rb +2 -2
  228. data/spec/unit/file_content_management/deploy/mv_windows_spec.rb +60 -0
  229. data/spec/unit/formatters/doc_spec.rb +46 -0
  230. data/spec/unit/formatters/error_inspectors/api_error_formatting_spec.rb +12 -10
  231. data/spec/unit/guard_interpreter/resource_guard_interpreter_spec.rb +8 -0
  232. data/spec/unit/http/authenticator_spec.rb +11 -2
  233. data/spec/unit/knife/client_create_spec.rb +122 -51
  234. data/spec/unit/knife/core/subcommand_loader_spec.rb +19 -3
  235. data/spec/unit/knife/core/ui_spec.rb +14 -0
  236. data/spec/unit/knife/osc_user_create_spec.rb +93 -0
  237. data/spec/unit/knife/osc_user_delete_spec.rb +44 -0
  238. data/spec/unit/knife/osc_user_edit_spec.rb +52 -0
  239. data/spec/unit/knife/osc_user_list_spec.rb +37 -0
  240. data/spec/unit/knife/osc_user_reregister_spec.rb +58 -0
  241. data/spec/unit/knife/osc_user_show_spec.rb +46 -0
  242. data/spec/unit/knife/user_create_spec.rb +177 -51
  243. data/spec/unit/knife/user_delete_spec.rb +34 -8
  244. data/spec/unit/knife/user_edit_spec.rb +31 -12
  245. data/spec/unit/knife/user_list_spec.rb +7 -3
  246. data/spec/unit/knife/user_reregister_spec.rb +38 -17
  247. data/spec/unit/knife/user_show_spec.rb +35 -11
  248. data/spec/unit/knife_spec.rb +10 -4
  249. data/spec/unit/lwrp_spec.rb +228 -54
  250. data/spec/unit/mixin/api_version_request_handling_spec.rb +127 -0
  251. data/spec/unit/mixin/command_spec.rb +1 -2
  252. data/spec/unit/mixin/powershell_out_spec.rb +70 -0
  253. data/spec/unit/mixin/uris_spec.rb +23 -11
  254. data/spec/unit/node_map_spec.rb +4 -1
  255. data/spec/unit/osc_user_spec.rb +276 -0
  256. data/spec/unit/platform_spec.rb +0 -60
  257. data/spec/unit/provider/deploy_spec.rb +1 -1
  258. data/spec/unit/provider/directory_spec.rb +199 -135
  259. data/spec/unit/provider/ifconfig/debian_spec.rb +0 -10
  260. data/spec/unit/provider/package/aix_spec.rb +16 -16
  261. data/spec/unit/provider/package/dpkg_spec.rb +2 -2
  262. data/spec/unit/provider/package/freebsd/pkg_spec.rb +13 -13
  263. data/spec/unit/provider/package/freebsd/pkgng_spec.rb +9 -9
  264. data/spec/unit/provider/package/freebsd/port_spec.rb +7 -7
  265. data/spec/unit/provider/package/ips_spec.rb +22 -22
  266. data/spec/unit/provider/package/macports_spec.rb +10 -10
  267. data/spec/unit/provider/package/openbsd_spec.rb +4 -26
  268. data/spec/unit/provider/package/pacman_spec.rb +5 -5
  269. data/spec/unit/provider/package/rpm_spec.rb +14 -14
  270. data/spec/unit/provider/package/rubygems_spec.rb +10 -44
  271. data/spec/unit/provider/package/smartos_spec.rb +4 -4
  272. data/spec/unit/provider/package/solaris_spec.rb +11 -11
  273. data/spec/unit/provider/package/zypper_spec.rb +125 -90
  274. data/spec/unit/provider/package_spec.rb +34 -0
  275. data/spec/unit/provider/powershell_spec.rb +53 -11
  276. data/spec/unit/provider/remote_directory_spec.rb +2 -2
  277. data/spec/unit/provider/remote_file/local_file_spec.rb +25 -6
  278. data/spec/unit/provider/service/freebsd_service_spec.rb +0 -12
  279. data/spec/unit/provider/user_spec.rb +3 -3
  280. data/spec/unit/provider_resolver_spec.rb +463 -327
  281. data/spec/unit/recipe_spec.rb +42 -15
  282. data/spec/unit/resource/breakpoint_spec.rb +1 -1
  283. data/spec/unit/resource/erl_call_spec.rb +1 -1
  284. data/spec/unit/resource/file_spec.rb +1 -1
  285. data/spec/unit/resource/ifconfig_spec.rb +10 -6
  286. data/spec/unit/resource/remote_file_spec.rb +5 -0
  287. data/spec/unit/resource/route_spec.rb +1 -1
  288. data/spec/unit/resource/ruby_block_spec.rb +2 -2
  289. data/spec/unit/resource/template_spec.rb +1 -1
  290. data/spec/unit/resource/timestamped_deploy_spec.rb +1 -2
  291. data/spec/unit/resource/windows_service_spec.rb +1 -1
  292. data/spec/unit/resource_spec.rb +99 -13
  293. data/spec/unit/rest_spec.rb +5 -5
  294. data/spec/unit/run_context_spec.rb +41 -0
  295. data/spec/unit/runner_spec.rb +2 -2
  296. data/spec/unit/user_spec.rb +406 -93
  297. data/tasks/maintainers.rb +69 -0
  298. metadata +37 -4
@@ -4,30 +4,17 @@ require 'chef/mixin/descendants_tracker'
4
4
  class Chef
5
5
  module Mixin
6
6
  module Provides
7
+ # TODO no longer needed, remove or deprecate?
7
8
  include Chef::Mixin::DescendantsTracker
8
9
 
9
- def node_map
10
- @node_map ||= Chef::NodeMap.new
11
- end
12
-
13
10
  def provides(short_name, opts={}, &block)
14
- if !short_name.kind_of?(Symbol)
15
- # YAGNI: this is probably completely unnecessary and can be removed?
16
- Chef::Log.deprecation "Passing a non-Symbol to Chef::Resource#provides will be removed"
17
- if short_name.kind_of?(String)
18
- short_name.downcase!
19
- short_name.gsub!(/\s/, "_")
20
- end
21
- short_name = short_name.to_sym
22
- end
23
- node_map.set(short_name, true, opts, &block)
11
+ raise NotImplementedError, :provides
24
12
  end
25
13
 
26
14
  # Check whether this resource provides the resource_name DSL for the given
27
- # node
28
- def provides?(node, resource_name)
29
- resource_name = resource_name.resource_name if resource_name.is_a?(Chef::Resource)
30
- node_map.get(node, resource_name)
15
+ # node. TODO remove this when we stop checking unregistered things.
16
+ def provides?(node, resource)
17
+ raise NotImplementedError, :provides?
31
18
  end
32
19
 
33
20
  # Get the list of recipe DSL this resource is responsible for on the given
@@ -28,6 +28,17 @@ class Chef
28
28
  # From open-uri
29
29
  !!(%r{\A[A-Za-z][A-Za-z0-9+\-\.]*://} =~ source)
30
30
  end
31
+
32
+
33
+ def as_uri(source)
34
+ begin
35
+ URI.parse(source)
36
+ rescue URI::InvalidURIError
37
+ Chef::Log.warn("#{source} was an invalid URI. Trying to escape invalid characters")
38
+ URI.parse(URI.escape(source))
39
+ end
40
+ end
41
+
31
42
  end
32
43
  end
33
44
  end
@@ -42,7 +42,7 @@ class Chef
42
42
  is_i386_process_on_x86_64_windows?
43
43
  end
44
44
 
45
- def with_os_architecture(node)
45
+ def with_os_architecture(node, architecture: nil)
46
46
  node ||= begin
47
47
  os_arch = ENV['PROCESSOR_ARCHITEW6432'] ||
48
48
  ENV['PROCESSOR_ARCHITECTURE']
@@ -51,9 +51,12 @@ class Chef
51
51
  n[:kernel][:machine] = os_arch == 'AMD64' ? :x86_64 : :i386
52
52
  end
53
53
  end
54
+
55
+ architecture ||= node_windows_architecture(node)
56
+
54
57
  wow64_redirection_state = nil
55
58
 
56
- if wow64_architecture_override_required?(node, node_windows_architecture(node))
59
+ if wow64_architecture_override_required?(node, architecture)
57
60
  wow64_redirection_state = disable_wow64_file_redirection(node)
58
61
  end
59
62
 
@@ -21,11 +21,11 @@ require 'chef/exceptions'
21
21
  require 'chef/platform/query_helpers'
22
22
  require 'chef/win32/error' if Chef::Platform.windows?
23
23
  require 'chef/win32/api/system' if Chef::Platform.windows?
24
+ require 'chef/win32/api/unicode' if Chef::Platform.windows?
24
25
 
25
26
  class Chef
26
27
  module Mixin
27
28
  module WindowsEnvHelper
28
-
29
29
  if Chef::Platform.windows?
30
30
  include Chef::ReservedNames::Win32::API::System
31
31
  end
@@ -39,7 +39,16 @@ class Chef
39
39
 
40
40
  def broadcast_env_change
41
41
  flags = SMTO_BLOCK | SMTO_ABORTIFHUNG | SMTO_NOTIMEOUTIFNOTHUNG
42
- SendMessageTimeoutA(HWND_BROADCAST, WM_SETTINGCHANGE, 0, FFI::MemoryPointer.from_string('Environment').address, flags, 5000, nil)
42
+ # for why two calls, see:
43
+ # http://stackoverflow.com/questions/4968373/why-doesnt-sendmessagetimeout-update-the-environment-variables
44
+ if ( SendMessageTimeoutA(HWND_BROADCAST, WM_SETTINGCHANGE, 0, FFI::MemoryPointer.from_string('Environment').address, flags, 5000, nil) == 0 )
45
+ Chef::ReservedNames::Win32::Error.raise!
46
+ end
47
+ if ( SendMessageTimeoutW(HWND_BROADCAST, WM_SETTINGCHANGE, 0, FFI::MemoryPointer.from_string(
48
+ Chef::ReservedNames::Win32::Unicode.utf8_to_wide('Environment')
49
+ ).address, flags, 5000, nil) == 0 )
50
+ Chef::ReservedNames::Win32::Error.raise!
51
+ end
43
52
  end
44
53
 
45
54
  def expand_path(path)
@@ -19,128 +19,183 @@
19
19
  class Chef
20
20
  class NodeMap
21
21
 
22
- VALID_OPTS = [
23
- :on_platform,
24
- :on_platforms,
25
- :platform,
26
- :os,
27
- :platform_family,
28
- ]
29
-
30
- DEPRECATED_OPTS = [
31
- :on_platform,
32
- :on_platforms,
33
- ]
34
-
22
+ #
35
23
  # Create a new NodeMap
36
24
  #
37
25
  def initialize
38
26
  @map = {}
39
27
  end
40
28
 
29
+ #
41
30
  # Set a key/value pair on the map with a filter. The filter must be true
42
31
  # when applied to the node in order to retrieve the value.
43
32
  #
44
33
  # @param key [Object] Key to store
45
34
  # @param value [Object] Value associated with the key
46
35
  # @param filters [Hash] Node filter options to apply to key retrieval
36
+ #
47
37
  # @yield [node] Arbitrary node filter as a block which takes a node argument
38
+ #
48
39
  # @return [NodeMap] Returns self for possible chaining
49
40
  #
50
- def set(key, value, filters = {}, &block)
51
- validate_filter!(filters)
52
- deprecate_filter!(filters)
41
+ def set(key, value, platform: nil, platform_version: nil, platform_family: nil, os: nil, on_platform: nil, on_platforms: nil, canonical: nil, &block)
42
+ Chef::Log.deprecation "The on_platform option to node_map has been deprecated" if on_platform
43
+ Chef::Log.deprecation "The on_platforms option to node_map has been deprecated" if on_platforms
44
+ platform ||= on_platform || on_platforms
45
+ filters = { platform: platform, platform_version: platform_version, platform_family: platform_family, os: os }
46
+ new_matcher = { filters: filters, block: block, value: value, canonical: canonical }
53
47
  @map[key] ||= []
54
- # we match on the first value we find, so we want to unshift so that the
55
- # last setter wins
56
- # FIXME: need a test for this behavior
57
- @map[key].unshift({ filters: filters, block: block, value: value })
48
+ # Decide where to insert the matcher; the new value is preferred over
49
+ # anything more specific (see `priority_of`) and is preferred over older
50
+ # values of the same specificity. (So all other things being equal,
51
+ # newest wins.)
52
+ insert_at = nil
53
+ @map[key].each_with_index do |matcher, index|
54
+ if specificity(new_matcher) >= specificity(matcher)
55
+ insert_at = index
56
+ break
57
+ end
58
+ end
59
+ if insert_at
60
+ @map[key].insert(insert_at, new_matcher)
61
+ else
62
+ @map[key] << new_matcher
63
+ end
58
64
  self
59
65
  end
60
66
 
67
+ #
61
68
  # Get a value from the NodeMap via applying the node to the filters that
62
69
  # were set on the key.
63
70
  #
64
- # @param node [Chef::Node] The Chef::Node object for the run
71
+ # @param node [Chef::Node] The Chef::Node object for the run, or `nil` to
72
+ # ignore all filters.
65
73
  # @param key [Object] Key to look up
74
+ # @param canonical [Boolean] `true` or `false` to match canonical or
75
+ # non-canonical values only. `nil` to ignore canonicality. Default: `nil`
76
+ #
66
77
  # @return [Object] Value
67
78
  #
68
- def get(node, key)
69
- # FIXME: real exception
70
- raise "first argument must be a Chef::Node" unless node.is_a?(Chef::Node)
71
- return nil unless @map.has_key?(key)
72
- @map[key].each do |matcher|
73
- if filters_match?(node, matcher[:filters]) &&
74
- block_matches?(node, matcher[:block])
75
- return matcher[:value]
79
+ def get(node, key, canonical: nil)
80
+ raise ArgumentError, "first argument must be a Chef::Node" unless node.is_a?(Chef::Node) || node.nil?
81
+ list(node, key, canonical: canonical).first
82
+ end
83
+
84
+ #
85
+ # List all matches for the given node and key from the NodeMap, from
86
+ # most-recently added to oldest.
87
+ #
88
+ # @param node [Chef::Node] The Chef::Node object for the run, or `nil` to
89
+ # ignore all filters.
90
+ # @param key [Object] Key to look up
91
+ # @param canonical [Boolean] `true` or `false` to match canonical or
92
+ # non-canonical values only. `nil` to ignore canonicality. Default: `nil`
93
+ #
94
+ # @return [Object] Value
95
+ #
96
+ def list(node, key, canonical: nil)
97
+ raise ArgumentError, "first argument must be a Chef::Node" unless node.is_a?(Chef::Node) || node.nil?
98
+ return [] unless @map.has_key?(key)
99
+ @map[key].select do |matcher|
100
+ node_matches?(node, matcher) && canonical_matches?(canonical, matcher)
101
+ end.map { |matcher| matcher[:value] }
102
+ end
103
+
104
+ # Seriously, don't use this, it's nearly certain to change on you
105
+ # @return remaining
106
+ # @api private
107
+ def delete_canonical(key, value)
108
+ remaining = @map[key]
109
+ if remaining
110
+ remaining.delete_if { |matcher| matcher[:canonical] && Array(matcher[:value]) == Array(value) }
111
+ if remaining.empty?
112
+ @map.delete(key)
113
+ remaining = nil
76
114
  end
77
115
  end
78
- nil
116
+ remaining
79
117
  end
80
118
 
81
119
  private
82
120
 
83
- # only allow valid filter options
84
- def validate_filter!(filters)
85
- filters.each_key do |key|
86
- # FIXME: real exception
87
- raise "Bad key #{key} in Chef::NodeMap filter expression" unless VALID_OPTS.include?(key)
121
+ #
122
+ # Gives a value for "how specific" the matcher is.
123
+ # Things which specify more specific filters get a higher number
124
+ # (platform_version > platform > platform_family > os); things
125
+ # with a block have higher specificity than similar things without
126
+ # a block.
127
+ #
128
+ def specificity(matcher)
129
+ if matcher[:filters][:platform_version]
130
+ specificity = 8
131
+ elsif matcher[:filters][:platform]
132
+ specificity = 6
133
+ elsif matcher[:filters][:platform_family]
134
+ specificity = 4
135
+ elsif matcher[:filters][:os]
136
+ specificity = 2
137
+ else
138
+ specificity = 0
88
139
  end
140
+ specificity += 1 if matcher[:block]
141
+ specificity
89
142
  end
90
143
 
91
- # warn on deprecated filter options
92
- def deprecate_filter!(filters)
93
- filters.each_key do |key|
94
- Chef::Log.warn "The #{key} option to node_map has been deprecated" if DEPRECATED_OPTS.include?(key)
95
- end
96
- end
144
+ #
145
+ # Succeeds if:
146
+ # - no negative matches (!value)
147
+ # - at least one positive match (value or :all), or no positive filters
148
+ #
149
+ def matches_black_white_list?(node, filters, attribute)
150
+ # It's super common for the filter to be nil. Catch that so we don't
151
+ # spend any time here.
152
+ return true if !filters[attribute]
153
+ filter_values = Array(filters[attribute])
154
+ value = node[attribute]
97
155
 
98
- # @todo: this works fine, but is probably hard to understand
99
- def negative_match(filter, param)
100
- # We support strings prefaced by '!' to mean 'not'. In particular, this is most useful
101
- # for os matching on '!windows'.
102
- negative_matches = filter.select { |f| f[0] == '!' }
103
- return true if !negative_matches.empty? && negative_matches.include?('!' + param)
156
+ # Split the blacklist and whitelist
157
+ blacklist, whitelist = filter_values.partition { |v| v.is_a?(String) && v.start_with?('!') }
104
158
 
105
- # We support the symbol :all to match everything, for backcompat, but this can and should
106
- # simply be ommitted.
107
- positive_matches = filter.reject { |f| f[0] == '!' || f == :all }
108
- return true if !positive_matches.empty? && !positive_matches.include?(param)
159
+ # If any blacklist value matches, we don't match
160
+ return false if blacklist.any? { |v| v[1..-1] == value }
109
161
 
110
- # sorry double-negative: this means we pass this filter.
111
- false
162
+ # If the whitelist is empty, or anything matches, we match.
163
+ whitelist.empty? || whitelist.any? { |v| v == :all || v == value }
112
164
  end
113
165
 
114
- def filters_match?(node, filters)
115
- return true if filters.empty?
166
+ def matches_version_list?(node, filters, attribute)
167
+ # It's super common for the filter to be nil. Catch that so we don't
168
+ # spend any time here.
169
+ return true if !filters[attribute]
170
+ filter_values = Array(filters[attribute])
171
+ value = node[attribute]
116
172
 
117
- # each filter is applied in turn. if any fail, then it shortcuts and returns false.
118
- # if it passes or does not exist it succeeds and continues on. so multiple filters are
119
- # effectively joined by 'and'. all filters can be single strings, or arrays which are
120
- # effectively joined by 'or'.
121
-
122
- os_filter = [ filters[:os] ].flatten.compact
123
- unless os_filter.empty?
124
- return false if negative_match(os_filter, node[:os])
125
- end
126
-
127
- platform_family_filter = [ filters[:platform_family] ].flatten.compact
128
- unless platform_family_filter.empty?
129
- return false if negative_match(platform_family_filter, node[:platform_family])
130
- end
131
-
132
- # :on_platform and :on_platforms here are synonyms which are deprecated
133
- platform_filter = [ filters[:platform] || filters[:on_platform] || filters[:on_platforms] ].flatten.compact
134
- unless platform_filter.empty?
135
- return false if negative_match(platform_filter, node[:platform])
173
+ filter_values.empty? ||
174
+ Array(filter_values).any? do |v|
175
+ Chef::VersionConstraint::Platform.new(v).include?(value)
136
176
  end
177
+ end
137
178
 
138
- return true
179
+ def filters_match?(node, filters)
180
+ matches_black_white_list?(node, filters, :os) &&
181
+ matches_black_white_list?(node, filters, :platform_family) &&
182
+ matches_black_white_list?(node, filters, :platform) &&
183
+ matches_version_list?(node, filters, :platform_version)
139
184
  end
140
185
 
141
186
  def block_matches?(node, block)
142
187
  return true if block.nil?
143
188
  block.call node
144
189
  end
190
+
191
+ def node_matches?(node, matcher)
192
+ return true if !node
193
+ filters_match?(node, matcher[:filters]) && block_matches?(node, matcher[:block])
194
+ end
195
+
196
+ def canonical_matches?(canonical, matcher)
197
+ return true if canonical.nil?
198
+ !!canonical == !!matcher[:canonical]
199
+ end
145
200
  end
146
201
  end
@@ -0,0 +1,194 @@
1
+ #
2
+ # Author:: Steven Danna (steve@opscode.com)
3
+ # Copyright:: Copyright 2012 Opscode, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+ require 'chef/config'
19
+ require 'chef/mixin/params_validate'
20
+ require 'chef/mixin/from_file'
21
+ require 'chef/mash'
22
+ require 'chef/json_compat'
23
+ require 'chef/search/query'
24
+
25
+ # TODO
26
+ # DEPRECATION NOTE
27
+ # This class was previously Chef::User. It is the code to support the User object
28
+ # corrosponding to the Open Source Chef Server 11 and only still exists to support
29
+ # users still on OSC 11.
30
+ #
31
+ # Chef::User now supports Chef Server 12.
32
+ #
33
+ # New development should occur in Chef::User.
34
+ # This file and corrosponding osc_user knife files
35
+ # should be removed once client support for Open Source Chef Server 11 expires.
36
+ class Chef
37
+ class OscUser
38
+
39
+ include Chef::Mixin::FromFile
40
+ include Chef::Mixin::ParamsValidate
41
+
42
+ def initialize
43
+ @name = ''
44
+ @public_key = nil
45
+ @private_key = nil
46
+ @password = nil
47
+ @admin = false
48
+ end
49
+
50
+ def name(arg=nil)
51
+ set_or_return(:name, arg,
52
+ :regex => /^[a-z0-9\-_]+$/)
53
+ end
54
+
55
+ def admin(arg=nil)
56
+ set_or_return(:admin,
57
+ arg, :kind_of => [TrueClass, FalseClass])
58
+ end
59
+
60
+ def public_key(arg=nil)
61
+ set_or_return(:public_key,
62
+ arg, :kind_of => String)
63
+ end
64
+
65
+ def private_key(arg=nil)
66
+ set_or_return(:private_key,
67
+ arg, :kind_of => String)
68
+ end
69
+
70
+ def password(arg=nil)
71
+ set_or_return(:password,
72
+ arg, :kind_of => String)
73
+ end
74
+
75
+ def to_hash
76
+ result = {
77
+ "name" => @name,
78
+ "public_key" => @public_key,
79
+ "admin" => @admin
80
+ }
81
+ result["private_key"] = @private_key if @private_key
82
+ result["password"] = @password if @password
83
+ result
84
+ end
85
+
86
+ def to_json(*a)
87
+ Chef::JSONCompat.to_json(to_hash, *a)
88
+ end
89
+
90
+ def destroy
91
+ Chef::REST.new(Chef::Config[:chef_server_url]).delete_rest("users/#{@name}")
92
+ end
93
+
94
+ def create
95
+ payload = {:name => self.name, :admin => self.admin, :password => self.password }
96
+ payload[:public_key] = public_key if public_key
97
+ new_user =Chef::REST.new(Chef::Config[:chef_server_url]).post_rest("users", payload)
98
+ Chef::OscUser.from_hash(self.to_hash.merge(new_user))
99
+ end
100
+
101
+ def update(new_key=false)
102
+ payload = {:name => name, :admin => admin}
103
+ payload[:private_key] = new_key if new_key
104
+ payload[:password] = password if password
105
+ updated_user = Chef::REST.new(Chef::Config[:chef_server_url]).put_rest("users/#{name}", payload)
106
+ Chef::OscUser.from_hash(self.to_hash.merge(updated_user))
107
+ end
108
+
109
+ def save(new_key=false)
110
+ begin
111
+ create
112
+ rescue Net::HTTPServerException => e
113
+ if e.response.code == "409"
114
+ update(new_key)
115
+ else
116
+ raise e
117
+ end
118
+ end
119
+ end
120
+
121
+ def reregister
122
+ r = Chef::REST.new(Chef::Config[:chef_server_url])
123
+ reregistered_self = r.put_rest("users/#{name}", { :name => name, :admin => admin, :private_key => true })
124
+ private_key(reregistered_self["private_key"])
125
+ self
126
+ end
127
+
128
+ def to_s
129
+ "user[#{@name}]"
130
+ end
131
+
132
+ def inspect
133
+ "Chef::OscUser name:'#{name}' admin:'#{admin.inspect}'" +
134
+ "public_key:'#{public_key}' private_key:#{private_key}"
135
+ end
136
+
137
+ # Class Methods
138
+
139
+ def self.from_hash(user_hash)
140
+ user = Chef::OscUser.new
141
+ user.name user_hash['name']
142
+ user.private_key user_hash['private_key'] if user_hash.key?('private_key')
143
+ user.password user_hash['password'] if user_hash.key?('password')
144
+ user.public_key user_hash['public_key']
145
+ user.admin user_hash['admin']
146
+ user
147
+ end
148
+
149
+ def self.from_json(json)
150
+ Chef::OscUser.from_hash(Chef::JSONCompat.from_json(json))
151
+ end
152
+
153
+ class << self
154
+ alias_method :json_create, :from_json
155
+ end
156
+
157
+ def self.list(inflate=false)
158
+ response = Chef::REST.new(Chef::Config[:chef_server_url]).get_rest('users')
159
+ users = if response.is_a?(Array)
160
+ transform_ohc_list_response(response) # OHC/OPC
161
+ else
162
+ response # OSC
163
+ end
164
+ if inflate
165
+ users.inject({}) do |user_map, (name, _url)|
166
+ user_map[name] = Chef::OscUser.load(name)
167
+ user_map
168
+ end
169
+ else
170
+ users
171
+ end
172
+ end
173
+
174
+ def self.load(name)
175
+ response = Chef::REST.new(Chef::Config[:chef_server_url]).get_rest("users/#{name}")
176
+ Chef::OscUser.from_hash(response)
177
+ end
178
+
179
+ # Gross. Transforms an API response in the form of:
180
+ # [ { "user" => { "username" => USERNAME }}, ...]
181
+ # into the form
182
+ # { "USERNAME" => "URI" }
183
+ def self.transform_ohc_list_response(response)
184
+ new_response = Hash.new
185
+ response.each do |u|
186
+ name = u['user']['username']
187
+ new_response[name] = Chef::Config[:chef_server_url] + "/users/#{name}"
188
+ end
189
+ new_response
190
+ end
191
+
192
+ private_class_method :transform_ohc_list_response
193
+ end
194
+ end