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
@@ -190,4 +190,45 @@ describe Chef::RunContext do
190
190
  expect(run_context.reboot_requested?).to be_falsey
191
191
  end
192
192
  end
193
+
194
+ describe "notifications" do
195
+ let(:notification) { Chef::Resource::Notification.new(nil, nil, notifying_resource) }
196
+
197
+ shared_context "notifying resource is a Chef::Resource" do
198
+ let(:notifying_resource) { Chef::Resource.new("gerbil") }
199
+
200
+ it "should be keyed off the resource name" do
201
+ run_context.send(setter, notification)
202
+ expect(run_context.send(getter, notifying_resource)).to eq([notification])
203
+ end
204
+ end
205
+
206
+ shared_context "notifying resource is a subclass of Chef::Resource" do
207
+ let(:declared_type) { :alpaca }
208
+ let(:notifying_resource) {
209
+ r = Class.new(Chef::Resource).new("guinea pig")
210
+ r.declared_type = declared_type
211
+ r
212
+ }
213
+
214
+ it "should be keyed off the resource declared key" do
215
+ run_context.send(setter, notification)
216
+ expect(run_context.send(getter, notifying_resource)).to eq([notification])
217
+ end
218
+ end
219
+
220
+ describe "of the immediate kind" do
221
+ let(:setter) { :notifies_immediately }
222
+ let(:getter) { :immediate_notifications }
223
+ include_context "notifying resource is a Chef::Resource"
224
+ include_context "notifying resource is a subclass of Chef::Resource"
225
+ end
226
+
227
+ describe "of the delayed kind" do
228
+ let(:setter) { :notifies_delayed }
229
+ let(:getter) { :delayed_notifications }
230
+ include_context "notifying resource is a Chef::Resource"
231
+ include_context "notifying resource is a subclass of Chef::Resource"
232
+ end
233
+ end
193
234
  end
@@ -273,8 +273,8 @@ describe Chef::Runner do
273
273
 
274
274
  expected_message =<<-E
275
275
  Multiple failures occurred:
276
- * FailureProvider::ChefClientFail occurred in delayed notification: [explode] (dynamically defined) had an error: FailureProvider::ChefClientFail: chef had an error of some sort
277
- * FailureProvider::ChefClientFail occurred in delayed notification: [explode again] (dynamically defined) had an error: FailureProvider::ChefClientFail: chef had an error of some sort
276
+ * FailureProvider::ChefClientFail occurred in delayed notification: failure_resource[explode] (dynamically defined) had an error: FailureProvider::ChefClientFail: chef had an error of some sort
277
+ * FailureProvider::ChefClientFail occurred in delayed notification: failure_resource[explode again] (dynamically defined) had an error: FailureProvider::ChefClientFail: chef had an error of some sort
278
278
  E
279
279
  expect(exception.message).to eq(expected_message)
280
280
 
@@ -26,98 +26,141 @@ describe Chef::User do
26
26
  @user = Chef::User.new
27
27
  end
28
28
 
29
+ shared_examples_for "string fields with no contraints" do
30
+ it "should let you set the public key" do
31
+ expect(@user.send(method, "some_string")).to eq("some_string")
32
+ end
33
+
34
+ it "should return the current public key" do
35
+ @user.send(method, "some_string")
36
+ expect(@user.send(method)).to eq("some_string")
37
+ end
38
+
39
+ it "should throw an ArgumentError if you feed it something lame" do
40
+ expect { @user.send(method, Hash.new) }.to raise_error(ArgumentError)
41
+ end
42
+ end
43
+
44
+ shared_examples_for "boolean fields with no constraints" do
45
+ it "should let you set the field" do
46
+ expect(@user.send(method, true)).to eq(true)
47
+ end
48
+
49
+ it "should return the current field value" do
50
+ @user.send(method, true)
51
+ expect(@user.send(method)).to eq(true)
52
+ end
53
+
54
+ it "should return the false value when false" do
55
+ @user.send(method, false)
56
+ expect(@user.send(method)).to eq(false)
57
+ end
58
+
59
+ it "should throw an ArgumentError if you feed it anything but true or false" do
60
+ expect { @user.send(method, Hash.new) }.to raise_error(ArgumentError)
61
+ end
62
+ end
63
+
29
64
  describe "initialize" do
30
65
  it "should be a Chef::User" do
31
66
  expect(@user).to be_a_kind_of(Chef::User)
32
67
  end
33
68
  end
34
69
 
35
- describe "name" do
36
- it "should let you set the name to a string" do
37
- expect(@user.name("ops_master")).to eq("ops_master")
70
+ describe "username" do
71
+ it "should let you set the username to a string" do
72
+ expect(@user.username("ops_master")).to eq("ops_master")
38
73
  end
39
74
 
40
- it "should return the current name" do
41
- @user.name "ops_master"
42
- expect(@user.name).to eq("ops_master")
75
+ it "should return the current username" do
76
+ @user.username "ops_master"
77
+ expect(@user.username).to eq("ops_master")
43
78
  end
44
79
 
45
80
  # It is not feasible to check all invalid characters. Here are a few
46
81
  # that we probably care about.
47
82
  it "should not accept invalid characters" do
48
83
  # capital letters
49
- expect { @user.name "Bar" }.to raise_error(ArgumentError)
84
+ expect { @user.username "Bar" }.to raise_error(ArgumentError)
50
85
  # slashes
51
- expect { @user.name "foo/bar" }.to raise_error(ArgumentError)
86
+ expect { @user.username "foo/bar" }.to raise_error(ArgumentError)
52
87
  # ?
53
- expect { @user.name "foo?" }.to raise_error(ArgumentError)
88
+ expect { @user.username "foo?" }.to raise_error(ArgumentError)
54
89
  # &
55
- expect { @user.name "foo&" }.to raise_error(ArgumentError)
90
+ expect { @user.username "foo&" }.to raise_error(ArgumentError)
56
91
  end
57
92
 
58
93
 
59
94
  it "should not accept spaces" do
60
- expect { @user.name "ops master" }.to raise_error(ArgumentError)
95
+ expect { @user.username "ops master" }.to raise_error(ArgumentError)
61
96
  end
62
97
 
63
98
  it "should throw an ArgumentError if you feed it anything but a string" do
64
- expect { @user.name Hash.new }.to raise_error(ArgumentError)
99
+ expect { @user.username Hash.new }.to raise_error(ArgumentError)
65
100
  end
66
101
  end
67
102
 
68
- describe "admin" do
69
- it "should let you set the admin bit" do
70
- expect(@user.admin(true)).to eq(true)
71
- end
72
-
73
- it "should return the current admin value" do
74
- @user.admin true
75
- expect(@user.admin).to eq(true)
103
+ describe "boolean fields" do
104
+ describe "create_key" do
105
+ it_should_behave_like "boolean fields with no constraints" do
106
+ let(:method) { :create_key }
107
+ end
76
108
  end
109
+ end
77
110
 
78
- it "should default to false" do
79
- expect(@user.admin).to eq(false)
111
+ describe "string fields" do
112
+ describe "public_key" do
113
+ it_should_behave_like "string fields with no contraints" do
114
+ let(:method) { :public_key }
115
+ end
80
116
  end
81
117
 
82
- it "should throw an ArgumentError if you feed it anything but true or false" do
83
- expect { @user.name Hash.new }.to raise_error(ArgumentError)
118
+ describe "private_key" do
119
+ it_should_behave_like "string fields with no contraints" do
120
+ let(:method) { :private_key }
121
+ end
84
122
  end
85
- end
86
123
 
87
- describe "public_key" do
88
- it "should let you set the public key" do
89
- expect(@user.public_key("super public")).to eq("super public")
124
+ describe "display_name" do
125
+ it_should_behave_like "string fields with no contraints" do
126
+ let(:method) { :display_name }
127
+ end
90
128
  end
91
129
 
92
- it "should return the current public key" do
93
- @user.public_key("super public")
94
- expect(@user.public_key).to eq("super public")
130
+ describe "first_name" do
131
+ it_should_behave_like "string fields with no contraints" do
132
+ let(:method) { :first_name }
133
+ end
95
134
  end
96
135
 
97
- it "should throw an ArgumentError if you feed it something lame" do
98
- expect { @user.public_key Hash.new }.to raise_error(ArgumentError)
136
+ describe "middle_name" do
137
+ it_should_behave_like "string fields with no contraints" do
138
+ let(:method) { :middle_name }
139
+ end
99
140
  end
100
- end
101
141
 
102
- describe "private_key" do
103
- it "should let you set the private key" do
104
- expect(@user.private_key("super private")).to eq("super private")
142
+ describe "last_name" do
143
+ it_should_behave_like "string fields with no contraints" do
144
+ let(:method) { :last_name }
145
+ end
105
146
  end
106
147
 
107
- it "should return the private key" do
108
- @user.private_key("super private")
109
- expect(@user.private_key).to eq("super private")
148
+ describe "email" do
149
+ it_should_behave_like "string fields with no contraints" do
150
+ let(:method) { :email }
151
+ end
110
152
  end
111
153
 
112
- it "should throw an ArgumentError if you feed it something lame" do
113
- expect { @user.private_key Hash.new }.to raise_error(ArgumentError)
154
+ describe "password" do
155
+ it_should_behave_like "string fields with no contraints" do
156
+ let(:method) { :password }
157
+ end
114
158
  end
115
159
  end
116
160
 
117
161
  describe "when serializing to JSON" do
118
162
  before(:each) do
119
- @user.name("black")
120
- @user.public_key("crowes")
163
+ @user.username("black")
121
164
  @json = @user.to_json
122
165
  end
123
166
 
@@ -125,16 +168,62 @@ describe Chef::User do
125
168
  expect(@json).to match(/^\{.+\}$/)
126
169
  end
127
170
 
128
- it "includes the name value" do
129
- expect(@json).to include(%q{"name":"black"})
171
+ it "includes the username value" do
172
+ expect(@json).to include(%q{"username":"black"})
173
+ end
174
+
175
+ it "includes the display name when present" do
176
+ @user.display_name("get_displayed")
177
+ expect(@user.to_json).to include(%{"display_name":"get_displayed"})
178
+ end
179
+
180
+ it "does not include the display name if not present" do
181
+ expect(@json).not_to include("display_name")
130
182
  end
131
183
 
132
- it "includes the public key value" do
133
- expect(@json).to include(%{"public_key":"crowes"})
184
+ it "includes the first name when present" do
185
+ @user.first_name("char")
186
+ expect(@user.to_json).to include(%{"first_name":"char"})
134
187
  end
135
188
 
136
- it "includes the 'admin' flag" do
137
- expect(@json).to include(%q{"admin":false})
189
+ it "does not include the first name if not present" do
190
+ expect(@json).not_to include("first_name")
191
+ end
192
+
193
+ it "includes the middle name when present" do
194
+ @user.middle_name("man")
195
+ expect(@user.to_json).to include(%{"middle_name":"man"})
196
+ end
197
+
198
+ it "does not include the middle name if not present" do
199
+ expect(@json).not_to include("middle_name")
200
+ end
201
+
202
+ it "includes the last name when present" do
203
+ @user.last_name("der")
204
+ expect(@user.to_json).to include(%{"last_name":"der"})
205
+ end
206
+
207
+ it "does not include the last name if not present" do
208
+ expect(@json).not_to include("last_name")
209
+ end
210
+
211
+ it "includes the email when present" do
212
+ @user.email("charmander@pokemon.poke")
213
+ expect(@user.to_json).to include(%{"email":"charmander@pokemon.poke"})
214
+ end
215
+
216
+ it "does not include the email if not present" do
217
+ expect(@json).not_to include("email")
218
+ end
219
+
220
+ it "includes the public key when present" do
221
+ @user.public_key("crowes")
222
+ expect(@user.to_json).to include(%{"public_key":"crowes"})
223
+ end
224
+
225
+ it "does not include the public key if not present" do
226
+ expect(@json).not_to include("public_key")
138
227
  end
139
228
 
140
229
  it "includes the private key when present" do
@@ -162,11 +251,18 @@ describe Chef::User do
162
251
 
163
252
  describe "when deserializing from JSON" do
164
253
  before(:each) do
165
- user = { "name" => "mr_spinks",
254
+ user = {
255
+ "username" => "mr_spinks",
256
+ "display_name" => "displayed",
257
+ "first_name" => "char",
258
+ "middle_name" => "man",
259
+ "last_name" => "der",
260
+ "email" => "charmander@pokemon.poke",
261
+ "password" => "password",
166
262
  "public_key" => "turtles",
167
263
  "private_key" => "pandas",
168
- "password" => "password",
169
- "admin" => true }
264
+ "create_key" => false
265
+ }
170
266
  @user = Chef::User.from_json(Chef::JSONCompat.to_json(user))
171
267
  end
172
268
 
@@ -174,32 +270,275 @@ describe Chef::User do
174
270
  expect(@user).to be_a_kind_of(Chef::User)
175
271
  end
176
272
 
177
- it "preserves the name" do
178
- expect(@user.name).to eq("mr_spinks")
273
+ it "preserves the username" do
274
+ expect(@user.username).to eq("mr_spinks")
179
275
  end
180
276
 
181
- it "preserves the public key" do
182
- expect(@user.public_key).to eq("turtles")
277
+ it "preserves the display name if present" do
278
+ expect(@user.display_name).to eq("displayed")
183
279
  end
184
280
 
185
- it "preserves the admin status" do
186
- expect(@user.admin).to be_truthy
281
+ it "preserves the first name if present" do
282
+ expect(@user.first_name).to eq("char")
187
283
  end
188
284
 
189
- it "includes the private key if present" do
190
- expect(@user.private_key).to eq("pandas")
285
+ it "preserves the middle name if present" do
286
+ expect(@user.middle_name).to eq("man")
287
+ end
288
+
289
+ it "preserves the last name if present" do
290
+ expect(@user.last_name).to eq("der")
291
+ end
292
+
293
+ it "preserves the email if present" do
294
+ expect(@user.email).to eq("charmander@pokemon.poke")
191
295
  end
192
296
 
193
297
  it "includes the password if present" do
194
298
  expect(@user.password).to eq("password")
195
299
  end
196
300
 
301
+ it "preserves the public key if present" do
302
+ expect(@user.public_key).to eq("turtles")
303
+ end
304
+
305
+ it "includes the private key if present" do
306
+ expect(@user.private_key).to eq("pandas")
307
+ end
308
+
309
+ it "includes the create key status if not nil" do
310
+ expect(@user.create_key).to be_falsey
311
+ end
197
312
  end
198
313
 
314
+ describe "Versioned API Interactions" do
315
+ let(:response_406) { OpenStruct.new(:code => '406') }
316
+ let(:exception_406) { Net::HTTPServerException.new("406 Not Acceptable", response_406) }
317
+
318
+ before (:each) do
319
+ @user = Chef::User.new
320
+ allow(@user).to receive(:chef_root_rest_v0).and_return(double('chef rest root v0 object'))
321
+ allow(@user).to receive(:chef_root_rest_v1).and_return(double('chef rest root v1 object'))
322
+ end
323
+
324
+ describe "update" do
325
+ before do
326
+ # populate all fields that are valid between V0 and V1
327
+ @user.username "some_username"
328
+ @user.display_name "some_display_name"
329
+ @user.first_name "some_first_name"
330
+ @user.middle_name "some_middle_name"
331
+ @user.last_name "some_last_name"
332
+ @user.email "some_email"
333
+ @user.password "some_password"
334
+ end
335
+
336
+ let(:payload) {
337
+ {
338
+ :username => "some_username",
339
+ :display_name => "some_display_name",
340
+ :first_name => "some_first_name",
341
+ :middle_name => "some_middle_name",
342
+ :last_name => "some_last_name",
343
+ :email => "some_email",
344
+ :password => "some_password"
345
+ }
346
+ }
347
+
348
+ context "when server API V1 is valid on the Chef Server receiving the request" do
349
+ context "when the user submits valid data" do
350
+ it "properly updates the user" do
351
+ expect(@user.chef_root_rest_v1).to receive(:put).with("users/some_username", payload).and_return({})
352
+ @user.update
353
+ end
354
+ end
355
+ end
356
+
357
+ context "when server API V1 is not valid on the Chef Server receiving the request" do
358
+ let(:payload) {
359
+ {
360
+ :username => "some_username",
361
+ :display_name => "some_display_name",
362
+ :first_name => "some_first_name",
363
+ :middle_name => "some_middle_name",
364
+ :last_name => "some_last_name",
365
+ :email => "some_email",
366
+ :password => "some_password",
367
+ :public_key => "some_public_key"
368
+ }
369
+ }
370
+
371
+ before do
372
+ @user.public_key "some_public_key"
373
+ allow(@user.chef_root_rest_v1).to receive(:put)
374
+ end
375
+
376
+ context "when the server returns a 400" do
377
+ let(:response_400) { OpenStruct.new(:code => '400') }
378
+ let(:exception_400) { Net::HTTPServerException.new("400 Bad Request", response_400) }
379
+
380
+ context "when the 400 was due to public / private key fields no longer being supported" do
381
+ let(:response_body_400) { '{"error":["Since Server API v1, all keys must be updated via the keys endpoint. "]}' }
382
+
383
+ before do
384
+ allow(response_400).to receive(:body).and_return(response_body_400)
385
+ allow(@user.chef_root_rest_v1).to receive(:put).and_raise(exception_400)
386
+ end
387
+
388
+ it "proceeds with the V0 PUT since it can handle public / private key fields" do
389
+ expect(@user.chef_root_rest_v0).to receive(:put).with("users/some_username", payload).and_return({})
390
+ @user.update
391
+ end
392
+
393
+ it "does not call server_client_api_version_intersection, since we know to proceed with V0 in this case" do
394
+ expect(@user).to_not receive(:server_client_api_version_intersection)
395
+ allow(@user.chef_root_rest_v0).to receive(:put).and_return({})
396
+ @user.update
397
+ end
398
+ end # when the 400 was due to public / private key fields
399
+
400
+ context "when the 400 was NOT due to public / private key fields no longer being supported" do
401
+ let(:response_body_400) { '{"error":["Some other error. "]}' }
402
+
403
+ before do
404
+ allow(response_400).to receive(:body).and_return(response_body_400)
405
+ allow(@user.chef_root_rest_v1).to receive(:put).and_raise(exception_400)
406
+ end
407
+
408
+ it "will not proceed with the V0 PUT since the original bad request was not key related" do
409
+ expect(@user.chef_root_rest_v0).to_not receive(:put).with("users/some_username", payload)
410
+ expect { @user.update }.to raise_error(exception_400)
411
+ end
412
+
413
+ it "raises the original error" do
414
+ expect { @user.update }.to raise_error(exception_400)
415
+ end
416
+
417
+ end
418
+ end # when the server returns a 400
419
+
420
+ context "when the server returns a 406" do
421
+ # from spec/support/shared/unit/api_versioning.rb
422
+ it_should_behave_like "version handling" do
423
+ let(:object) { @user }
424
+ let(:method) { :update }
425
+ let(:http_verb) { :put }
426
+ let(:rest_v1) { @user.chef_root_rest_v1 }
427
+ end
428
+
429
+ context "when the server supports API V0" do
430
+ before do
431
+ allow(@user).to receive(:server_client_api_version_intersection).and_return([0])
432
+ allow(@user.chef_root_rest_v1).to receive(:put).and_raise(exception_406)
433
+ end
434
+
435
+ it "properly updates the user" do
436
+ expect(@user.chef_root_rest_v0).to receive(:put).with("users/some_username", payload).and_return({})
437
+ @user.update
438
+ end
439
+ end # when the server supports API V0
440
+ end # when the server returns a 406
441
+
442
+ end # when server API V1 is not valid on the Chef Server receiving the request
443
+ end # update
444
+
445
+ describe "create" do
446
+ let(:payload) {
447
+ {
448
+ :username => "some_username",
449
+ :display_name => "some_display_name",
450
+ :first_name => "some_first_name",
451
+ :last_name => "some_last_name",
452
+ :email => "some_email",
453
+ :password => "some_password"
454
+ }
455
+ }
456
+ before do
457
+ @user.username "some_username"
458
+ @user.display_name "some_display_name"
459
+ @user.first_name "some_first_name"
460
+ @user.last_name "some_last_name"
461
+ @user.email "some_email"
462
+ @user.password "some_password"
463
+ end
464
+
465
+ # from spec/support/shared/unit/user_and_client_shared.rb
466
+ it_should_behave_like "user or client create" do
467
+ let(:object) { @user }
468
+ let(:error) { Chef::Exceptions::InvalidUserAttribute }
469
+ let(:rest_v0) { @user.chef_root_rest_v0 }
470
+ let(:rest_v1) { @user.chef_root_rest_v1 }
471
+ let(:url) { "users" }
472
+ end
473
+
474
+ context "when handling API V1" do
475
+ it "creates a new user via the API with a middle_name when it exists" do
476
+ @user.middle_name "some_middle_name"
477
+ expect(@user.chef_root_rest_v1).to receive(:post).with("users", payload.merge({:middle_name => "some_middle_name"})).and_return({})
478
+ @user.create
479
+ end
480
+ end # when server API V1 is valid on the Chef Server receiving the request
481
+
482
+ context "when API V1 is not supported by the server" do
483
+ # from spec/support/shared/unit/api_versioning.rb
484
+ it_should_behave_like "version handling" do
485
+ let(:object) { @user }
486
+ let(:method) { :create }
487
+ let(:http_verb) { :post }
488
+ let(:rest_v1) { @user.chef_root_rest_v1 }
489
+ end
490
+ end
491
+
492
+ context "when handling API V0" do
493
+ before do
494
+ allow(@user).to receive(:server_client_api_version_intersection).and_return([0])
495
+ allow(@user.chef_root_rest_v1).to receive(:post).and_raise(exception_406)
496
+ end
497
+
498
+ it "creates a new user via the API with a middle_name when it exists" do
499
+ @user.middle_name "some_middle_name"
500
+ expect(@user.chef_root_rest_v0).to receive(:post).with("users", payload.merge({:middle_name => "some_middle_name"})).and_return({})
501
+ @user.create
502
+ end
503
+ end # when server API V1 is not valid on the Chef Server receiving the request
504
+
505
+ end # create
506
+
507
+ # DEPRECATION
508
+ # This can be removed after API V0 support is gone
509
+ describe "reregister" do
510
+ let(:payload) {
511
+ {
512
+ "username" => "some_username",
513
+ }
514
+ }
515
+
516
+ before do
517
+ @user.username "some_username"
518
+ end
519
+
520
+ context "when server API V0 is valid on the Chef Server receiving the request" do
521
+ it "creates a new object via the API" do
522
+ expect(@user.chef_root_rest_v0).to receive(:put).with("users/#{@user.username}", payload.merge({"private_key" => true})).and_return({})
523
+ @user.reregister
524
+ end
525
+ end # when server API V0 is valid on the Chef Server receiving the request
526
+
527
+ context "when server API V0 is not supported by the Chef Server" do
528
+ # from spec/support/shared/unit/api_versioning.rb
529
+ it_should_behave_like "user and client reregister" do
530
+ let(:object) { @user }
531
+ let(:rest_v0) { @user.chef_root_rest_v0 }
532
+ end
533
+ end # when server API V0 is not supported by the Chef Server
534
+ end # reregister
535
+
536
+ end # Versioned API Interactions
537
+
199
538
  describe "API Interactions" do
200
539
  before (:each) do
201
540
  @user = Chef::User.new
202
- @user.name "foobar"
541
+ @user.username "foobar"
203
542
  @http_client = double("Chef::REST mock")
204
543
  allow(Chef::REST).to receive(:new).and_return(@http_client)
205
544
  end
@@ -213,57 +552,31 @@ describe Chef::User do
213
552
  @osc_inflated_response = { "admin" => @user }
214
553
  end
215
554
 
216
- it "lists all clients on an OSC server" do
217
- allow(@http_client).to receive(:get_rest).with("users").and_return(@osc_response)
218
- expect(Chef::User.list).to eq(@osc_response)
219
- end
220
-
221
- it "inflate all clients on an OSC server" do
222
- allow(@http_client).to receive(:get_rest).with("users").and_return(@osc_response)
223
- expect(Chef::User.list(true)).to eq(@osc_inflated_response)
224
- end
225
-
226
555
  it "lists all clients on an OHC/OPC server" do
227
- allow(@http_client).to receive(:get_rest).with("users").and_return(@ohc_response)
556
+ allow(@http_client).to receive(:get).with("users").and_return(@ohc_response)
228
557
  # We expect that Chef::User.list will give a consistent response
229
558
  # so OHC API responses should be transformed to OSC-style output.
230
559
  expect(Chef::User.list).to eq(@osc_response)
231
560
  end
232
561
 
233
562
  it "inflate all clients on an OHC/OPC server" do
234
- allow(@http_client).to receive(:get_rest).with("users").and_return(@ohc_response)
563
+ allow(@http_client).to receive(:get).with("users").and_return(@ohc_response)
235
564
  expect(Chef::User.list(true)).to eq(@osc_inflated_response)
236
565
  end
237
566
  end
238
567
 
239
- describe "create" do
240
- it "creates a new user via the API" do
241
- @user.password "password"
242
- expect(@http_client).to receive(:post_rest).with("users", {:name => "foobar", :admin => false, :password => "password"}).and_return({})
243
- @user.create
244
- end
245
- end
246
-
247
568
  describe "read" do
248
569
  it "loads a named user from the API" do
249
- expect(@http_client).to receive(:get_rest).with("users/foobar").and_return({"name" => "foobar", "admin" => true, "public_key" => "pubkey"})
570
+ expect(@http_client).to receive(:get).with("users/foobar").and_return({"username" => "foobar", "admin" => true, "public_key" => "pubkey"})
250
571
  user = Chef::User.load("foobar")
251
- expect(user.name).to eq("foobar")
252
- expect(user.admin).to eq(true)
572
+ expect(user.username).to eq("foobar")
253
573
  expect(user.public_key).to eq("pubkey")
254
574
  end
255
575
  end
256
576
 
257
- describe "update" do
258
- it "updates an existing user on via the API" do
259
- expect(@http_client).to receive(:put_rest).with("users/foobar", {:name => "foobar", :admin => false}).and_return({})
260
- @user.update
261
- end
262
- end
263
-
264
577
  describe "destroy" do
265
578
  it "deletes the specified user via the API" do
266
- expect(@http_client).to receive(:delete_rest).with("users/foobar")
579
+ expect(@http_client).to receive(:delete).with("users/foobar")
267
580
  @user.destroy
268
581
  end
269
582
  end