chef 12.0.0.alpha.0 → 12.0.0.alpha.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (207) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +3 -5
  3. data/lib/chef/api_client.rb +1 -1
  4. data/lib/chef/application.rb +16 -8
  5. data/lib/chef/chef_fs/chef_fs_data_store.rb +1 -1
  6. data/lib/chef/chef_fs/command_line.rb +1 -1
  7. data/lib/chef/chef_fs/file_system.rb +1 -1
  8. data/lib/chef/chef_fs/file_system/acl_entry.rb +1 -1
  9. data/lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb +3 -3
  10. data/lib/chef/chef_fs/file_system/cookbook_file.rb +2 -2
  11. data/lib/chef/chef_fs/file_system/rest_list_dir.rb +2 -2
  12. data/lib/chef/chef_fs/file_system/rest_list_entry.rb +4 -4
  13. data/lib/chef/config.rb +6 -5
  14. data/lib/chef/config_fetcher.rb +1 -1
  15. data/lib/chef/cookbook/cookbook_version_loader.rb +126 -43
  16. data/lib/chef/cookbook/metadata.rb +102 -53
  17. data/lib/chef/cookbook/syntax_check.rb +1 -1
  18. data/lib/chef/cookbook_loader.rb +62 -14
  19. data/lib/chef/cookbook_site_streaming_uploader.rb +12 -1
  20. data/lib/chef/cookbook_version.rb +13 -4
  21. data/lib/chef/data_bag.rb +28 -15
  22. data/lib/chef/data_bag_item.rb +5 -7
  23. data/lib/chef/digester.rb +5 -9
  24. data/lib/chef/dsl/recipe.rb +14 -0
  25. data/lib/chef/encrypted_data_bag_item.rb +1 -0
  26. data/lib/chef/encrypted_data_bag_item/assertions.rb +57 -0
  27. data/lib/chef/encrypted_data_bag_item/decryptor.rb +52 -28
  28. data/lib/chef/encrypted_data_bag_item/encrypted_data_bag_item_assertions.rb +37 -0
  29. data/lib/chef/encrypted_data_bag_item/encryption_failure.rb +22 -0
  30. data/lib/chef/encrypted_data_bag_item/encryptor.rb +79 -8
  31. data/lib/chef/environment.rb +1 -3
  32. data/lib/chef/exceptions.rb +18 -3
  33. data/lib/chef/formatters/base.rb +7 -0
  34. data/lib/chef/formatters/error_inspectors/cookbook_resolve_error_inspector.rb +1 -1
  35. data/lib/chef/handler/json_file.rb +0 -1
  36. data/lib/chef/http/json_output.rb +1 -1
  37. data/lib/chef/json_compat.rb +24 -6
  38. data/lib/chef/knife/bootstrap.rb +2 -2
  39. data/lib/chef/knife/client_delete.rb +1 -1
  40. data/lib/chef/knife/cookbook_site_download.rb +1 -1
  41. data/lib/chef/knife/cookbook_site_list.rb +1 -1
  42. data/lib/chef/knife/cookbook_site_search.rb +1 -1
  43. data/lib/chef/knife/cookbook_site_share.rb +2 -2
  44. data/lib/chef/knife/cookbook_site_show.rb +3 -3
  45. data/lib/chef/knife/cookbook_site_unshare.rb +1 -1
  46. data/lib/chef/knife/core/node_editor.rb +2 -3
  47. data/lib/chef/knife/core/ui.rb +2 -2
  48. data/lib/chef/knife/deps.rb +2 -3
  49. data/lib/chef/mixin/shell_out.rb +1 -1
  50. data/lib/chef/mixin/windows_architecture_helper.rb +1 -0
  51. data/lib/chef/node.rb +1 -2
  52. data/lib/chef/platform/provider_mapping.rb +33 -6
  53. data/lib/chef/provider.rb +0 -2
  54. data/lib/chef/provider/cookbook_file/content.rb +1 -1
  55. data/lib/chef/provider/cron.rb +11 -0
  56. data/lib/chef/provider/deploy.rb +3 -2
  57. data/lib/chef/provider/deploy/revision.rb +2 -2
  58. data/lib/chef/provider/env.rb +1 -1
  59. data/lib/chef/provider/env/windows.rb +5 -9
  60. data/lib/chef/provider/file.rb +84 -33
  61. data/lib/chef/provider/git.rb +2 -1
  62. data/lib/chef/provider/group/aix.rb +17 -2
  63. data/lib/chef/provider/group/dscl.rb +27 -9
  64. data/lib/chef/provider/group/pw.rb +8 -1
  65. data/lib/chef/provider/http_request.rb +4 -4
  66. data/lib/chef/provider/log.rb +4 -14
  67. data/lib/chef/provider/mount/mount.rb +2 -2
  68. data/lib/chef/provider/package/ips.rb +17 -23
  69. data/lib/chef/provider/package/paludis.rb +2 -2
  70. data/lib/chef/provider/package/rpm.rb +2 -2
  71. data/lib/chef/provider/package/rubygems.rb +2 -0
  72. data/lib/chef/provider/package/yum.rb +2 -0
  73. data/lib/chef/provider/package/zypper.rb +1 -1
  74. data/lib/chef/provider/remote_file/cache_control_data.rb +2 -2
  75. data/lib/chef/provider/service/windows.rb +87 -21
  76. data/lib/chef/provider/user/aix.rb +95 -0
  77. data/lib/chef/provider/user/dscl.rb +544 -156
  78. data/lib/chef/provider/user/useradd.rb +1 -0
  79. data/lib/chef/providers.rb +1 -0
  80. data/lib/chef/resource.rb +4 -3
  81. data/lib/chef/resource/freebsd_package.rb +10 -2
  82. data/lib/chef/resource/paludis_package.rb +1 -0
  83. data/lib/chef/resource/scm.rb +10 -0
  84. data/lib/chef/resource/user.rb +27 -0
  85. data/lib/chef/resource/windows_service.rb +53 -0
  86. data/lib/chef/resource_collection.rb +23 -12
  87. data/lib/chef/resource_reporter.rb +10 -10
  88. data/lib/chef/resources.rb +1 -0
  89. data/lib/chef/role.rb +3 -3
  90. data/lib/chef/run_list.rb +6 -3
  91. data/lib/chef/user.rb +1 -1
  92. data/lib/chef/util/diff.rb +1 -2
  93. data/lib/chef/version.rb +1 -1
  94. data/lib/chef/version_constraint.rb +4 -4
  95. data/spec/data/cookbooks/angrybash/metadata.rb +2 -0
  96. data/spec/data/cookbooks/apache2/metadata.rb +2 -0
  97. data/spec/data/cookbooks/borken/metadata.rb +2 -0
  98. data/spec/data/cookbooks/ignorken/metadata.rb +2 -0
  99. data/spec/data/cookbooks/java/metadata.rb +2 -0
  100. data/spec/data/cookbooks/name-mismatch-versionnumber/README.md +4 -0
  101. data/spec/data/cookbooks/name-mismatch-versionnumber/metadata.rb +8 -0
  102. data/spec/data/cookbooks/name-mismatch-versionnumber/recipes/default.rb +8 -0
  103. data/spec/data/cookbooks/openldap/files/default/remotedir/not_a_template.erb +2 -0
  104. data/spec/data/cookbooks/preseed/metadata.rb +2 -0
  105. data/spec/data/incomplete-metadata-chef-repo/incomplete-metadata/README.md +4 -0
  106. data/spec/data/incomplete-metadata-chef-repo/incomplete-metadata/metadata.rb +13 -0
  107. data/spec/data/incomplete-metadata-chef-repo/incomplete-metadata/recipes/default.rb +8 -0
  108. data/spec/data/invalid-metadata-chef-repo/invalid-metadata/README.md +4 -0
  109. data/spec/data/invalid-metadata-chef-repo/invalid-metadata/metadata.rb +10 -0
  110. data/spec/data/invalid-metadata-chef-repo/invalid-metadata/recipes/default.rb +8 -0
  111. data/spec/data/mac_users/10.7-8.plist.xml +559 -0
  112. data/spec/data/mac_users/10.7-8.shadow.xml +11 -0
  113. data/spec/data/mac_users/10.7.plist.xml +559 -0
  114. data/spec/data/mac_users/10.7.shadow.xml +11 -0
  115. data/spec/data/mac_users/10.8.plist.xml +559 -0
  116. data/spec/data/mac_users/10.8.shadow.xml +21 -0
  117. data/spec/data/mac_users/10.9.plist.xml +560 -0
  118. data/spec/data/mac_users/10.9.shadow.xml +21 -0
  119. data/spec/data/object_loader/environments/test.json +2 -0
  120. data/spec/data/object_loader/environments/test_json_class.json +2 -0
  121. data/spec/data/object_loader/nodes/test.json +2 -0
  122. data/spec/data/object_loader/nodes/test_json_class.json +2 -0
  123. data/spec/data/object_loader/roles/test.json +2 -0
  124. data/spec/data/object_loader/roles/test_json_class.json +2 -0
  125. data/spec/functional/resource/bff_spec.rb +1 -1
  126. data/spec/functional/resource/cron_spec.rb +20 -1
  127. data/spec/functional/resource/env_spec.rb +137 -0
  128. data/spec/functional/resource/group_spec.rb +7 -5
  129. data/spec/functional/resource/remote_file_spec.rb +12 -1
  130. data/spec/functional/resource/user/dscl_spec.rb +198 -0
  131. data/spec/functional/resource/{user_spec.rb → user/useradd_spec.rb} +175 -37
  132. data/spec/integration/client/client_spec.rb +6 -4
  133. data/spec/integration/client/ipv6_spec.rb +16 -14
  134. data/spec/integration/knife/chef_fs_data_store_spec.rb +57 -46
  135. data/spec/integration/knife/chef_repo_path_spec.rb +105 -78
  136. data/spec/integration/knife/chef_repository_file_system_spec.rb +100 -84
  137. data/spec/integration/knife/chefignore_spec.rb +76 -46
  138. data/spec/integration/knife/common_options_spec.rb +16 -21
  139. data/spec/integration/knife/cookbook_api_ipv6_spec.rb +3 -3
  140. data/spec/integration/knife/delete_spec.rb +66 -46
  141. data/spec/integration/knife/deps_spec.rb +145 -94
  142. data/spec/integration/knife/diff_spec.rb +176 -110
  143. data/spec/integration/knife/download_spec.rb +229 -133
  144. data/spec/integration/knife/list_spec.rb +62 -54
  145. data/spec/integration/knife/raw_spec.rb +24 -9
  146. data/spec/integration/knife/redirection_spec.rb +2 -2
  147. data/spec/integration/knife/serve_spec.rb +2 -2
  148. data/spec/integration/knife/show_spec.rb +32 -26
  149. data/spec/integration/knife/upload_spec.rb +308 -165
  150. data/spec/integration/recipes/lwrp_inline_resources_spec.rb +10 -8
  151. data/spec/integration/solo/solo_spec.rb +22 -11
  152. data/spec/spec_helper.rb +3 -0
  153. data/spec/support/lib/chef/resource/zen_follower.rb +46 -0
  154. data/spec/support/platform_helpers.rb +12 -0
  155. data/spec/support/shared/functional/file_resource.rb +10 -0
  156. data/spec/support/shared/integration/chef_zero_support.rb +130 -0
  157. data/spec/support/shared/integration/integration_helper.rb +100 -98
  158. data/spec/support/shared/integration/knife_support.rb +0 -1
  159. data/spec/support/shared/unit/provider/file.rb +6 -4
  160. data/spec/support/shared/unit/provider/useradd_based_user_provider.rb +10 -1
  161. data/spec/unit/api_client/registration_spec.rb +83 -74
  162. data/spec/unit/application_spec.rb +32 -9
  163. data/spec/unit/cookbook/cookbook_version_loader_spec.rb +179 -0
  164. data/spec/unit/cookbook/metadata_spec.rb +190 -150
  165. data/spec/unit/cookbook/syntax_check_spec.rb +3 -2
  166. data/spec/unit/cookbook_loader_spec.rb +114 -53
  167. data/spec/unit/{cookbook_site_streaming_uploader.rb → cookbook_site_streaming_uploader_spec.rb} +21 -1
  168. data/spec/unit/data_bag_spec.rb +88 -13
  169. data/spec/unit/deprecation_spec.rb +1 -2
  170. data/spec/unit/encrypted_data_bag_item_spec.rb +145 -9
  171. data/spec/unit/environment_spec.rb +1 -1
  172. data/spec/unit/formatters/base_spec.rb +48 -0
  173. data/spec/unit/json_compat_spec.rb +48 -17
  174. data/spec/unit/knife/client_delete_spec.rb +4 -4
  175. data/spec/unit/knife/client_show_spec.rb +15 -5
  176. data/spec/unit/knife/cookbook_site_download_spec.rb +1 -1
  177. data/spec/unit/knife/cookbook_site_share_spec.rb +3 -3
  178. data/spec/unit/knife/data_bag_from_file_spec.rb +0 -2
  179. data/spec/unit/knife/data_bag_show_spec.rb +23 -14
  180. data/spec/unit/knife/node_show_spec.rb +32 -15
  181. data/spec/unit/knife/role_show_spec.rb +59 -0
  182. data/spec/unit/platform_spec.rb +10 -0
  183. data/spec/unit/provider/deploy_spec.rb +4 -0
  184. data/spec/unit/provider/env_spec.rb +19 -0
  185. data/spec/unit/provider/git_spec.rb +22 -2
  186. data/spec/unit/provider/group/dscl_spec.rb +38 -1
  187. data/spec/unit/provider/group/pw_spec.rb +2 -2
  188. data/spec/unit/provider/http_request_spec.rb +8 -8
  189. data/spec/unit/provider/log_spec.rb +33 -53
  190. data/spec/unit/provider/mount/mount_spec.rb +12 -3
  191. data/spec/unit/provider/package/ips_spec.rb +96 -63
  192. data/spec/unit/provider/package/paludis_spec.rb +5 -5
  193. data/spec/unit/provider/package/rpm_spec.rb +12 -0
  194. data/spec/unit/provider/package/zypper_spec.rb +28 -16
  195. data/spec/unit/provider/service/windows_spec.rb +77 -17
  196. data/spec/unit/provider/user/dscl_spec.rb +659 -264
  197. data/spec/unit/provider/user/useradd_spec.rb +1 -0
  198. data/spec/unit/recipe_spec.rb +41 -0
  199. data/spec/unit/resource/scm_spec.rb +11 -0
  200. data/spec/unit/resource/user_spec.rb +4 -0
  201. data/spec/unit/resource/windows_service_spec.rb +46 -0
  202. data/spec/unit/resource_collection_spec.rb +33 -0
  203. data/spec/unit/resource_reporter_spec.rb +48 -0
  204. data/spec/unit/resource_spec.rb +9 -2
  205. data/spec/unit/role_spec.rb +6 -0
  206. data/spec/unit/version_constraint_spec.rb +28 -0
  207. metadata +61 -4
@@ -18,14 +18,24 @@
18
18
  #
19
19
 
20
20
  require 'spec_helper'
21
+ require 'functional/resource/base'
21
22
  require 'chef/mixin/shell_out'
22
23
 
24
+ def user_provider_for_platform
25
+ case ohai[:platform]
26
+ when "aix"
27
+ Chef::Provider::User::Aix
28
+ else
29
+ Chef::Provider::User::Useradd
30
+ end
31
+ end
32
+
23
33
  metadata = { :unix_only => true,
24
34
  :requires_root => true,
25
- :provider => {:user => Chef::Provider::User::Useradd}
35
+ :provider => {:user => user_provider_for_platform}
26
36
  }
27
37
 
28
- describe Chef::Resource::User, metadata do
38
+ describe Chef::Provider::User::Useradd, metadata do
29
39
 
30
40
  include Chef::Mixin::ShellOut
31
41
 
@@ -46,15 +56,27 @@ describe Chef::Resource::User, metadata do
46
56
  end
47
57
 
48
58
  def etc_shadow
49
- File.open("/etc/shadow") {|f| f.read }
59
+ case ohai[:platform]
60
+ when "aix"
61
+ File.open("/etc/security/passwd") {|f| f.read }
62
+ else
63
+ File.open("/etc/shadow") {|f| f.read }
64
+ end
50
65
  end
51
66
 
52
67
  def supports_quote_in_username?
53
68
  OHAI_SYSTEM["platform_family"] == "debian"
54
69
  end
55
70
 
71
+ def password_should_be_set
72
+ if ohai[:platform] == "aix"
73
+ pw_entry.passwd.should == "!"
74
+ else
75
+ pw_entry.passwd.should == "x"
76
+ end
77
+ end
78
+
56
79
  before do
57
- pending "porting implementation for user provider in aix" if OHAI_SYSTEM[:platform] == 'aix'
58
80
  # Silence shell_out live stream
59
81
  Chef::Log.level = :warn
60
82
  end
@@ -62,7 +84,7 @@ describe Chef::Resource::User, metadata do
62
84
  after do
63
85
  begin
64
86
  pw_entry # will raise if the user doesn't exist
65
- shell_out!("userdel", "-f", "-r", username, :returns => [0,12])
87
+ shell_out!("userdel", "-r", username, :returns => [0,12])
66
88
  rescue UserNotFound
67
89
  # nothing to remove
68
90
  end
@@ -83,7 +105,7 @@ describe Chef::Resource::User, metadata do
83
105
  end
84
106
 
85
107
  let(:username) do
86
- "chef-functional-test"
108
+ "cf-test"
87
109
  end
88
110
 
89
111
  let(:uid) { nil }
@@ -105,6 +127,14 @@ describe Chef::Resource::User, metadata do
105
127
  r
106
128
  end
107
129
 
130
+ let(:expected_shadow) do
131
+ if ohai[:platform] == "aix"
132
+ expected_shadow = "cf-test" # For aix just check user entry in shadow file
133
+ else
134
+ expected_shadow = "cf-test:$1$RRa/wMM/$XltKfoX5ffnexVF4dHZZf/"
135
+ end
136
+ end
137
+
108
138
  let(:skip) { false }
109
139
 
110
140
  describe "action :create" do
@@ -218,10 +248,17 @@ describe Chef::Resource::User, metadata do
218
248
 
219
249
  context "when a password is specified" do
220
250
  # openssl passwd -1 "secretpassword"
221
- let(:password) { "$1$RRa/wMM/$XltKfoX5ffnexVF4dHZZf/" }
251
+ let(:password) do
252
+ case ohai[:platform]
253
+ when "aix"
254
+ "eL5qfEVznSNss"
255
+ else
256
+ "$1$RRa/wMM/$XltKfoX5ffnexVF4dHZZf/"
257
+ end
258
+ end
259
+
222
260
  it "sets the user's shadow password" do
223
- pw_entry.passwd.should == "x"
224
- expected_shadow = "chef-functional-test:$1$RRa/wMM/$XltKfoX5ffnexVF4dHZZf/"
261
+ password_should_be_set
225
262
  etc_shadow.should include(expected_shadow)
226
263
  end
227
264
  end
@@ -229,14 +266,21 @@ describe Chef::Resource::User, metadata do
229
266
  context "when a system user is specified" do
230
267
  let(:system) { true }
231
268
  let(:uid_min) do
232
- # from `man useradd`, login user means uid will be between
233
- # UID_SYS_MIN and UID_SYS_MAX defined in /etc/login.defs. On my
234
- # Ubuntu 13.04 system, these are commented out, so we'll look at
235
- # UID_MIN to find the lower limit of the non-system-user range, and
236
- # use that value in our assertions.
237
- login_defs = File.open("/etc/login.defs", "rb") {|f| f.read }
238
- uid_min_scan = /^UID_MIN\s+(\d+)/
239
- login_defs.match(uid_min_scan)[1]
269
+ case ohai[:platform]
270
+ when "aix"
271
+ # UIDs and GIDs below 100 are typically reserved for system accounts and services
272
+ # http://www.ibm.com/developerworks/aix/library/au-satuidgid/
273
+ 100
274
+ else
275
+ # from `man useradd`, login user means uid will be between
276
+ # UID_SYS_MIN and UID_SYS_MAX defined in /etc/login.defs. On my
277
+ # Ubuntu 13.04 system, these are commented out, so we'll look at
278
+ # UID_MIN to find the lower limit of the non-system-user range, and
279
+ # use that value in our assertions.
280
+ login_defs = File.open("/etc/login.defs", "rb") {|f| f.read }
281
+ uid_min_scan = /^UID_MIN\s+(\d+)/
282
+ login_defs.match(uid_min_scan)[1]
283
+ end
240
284
  end
241
285
 
242
286
  it "ensures the user has the properties of a system user" do
@@ -284,7 +328,15 @@ describe Chef::Resource::User, metadata do
284
328
  let(:home) { "/home/bobo" }
285
329
  let(:manage_home) { true }
286
330
  # openssl passwd -1 "secretpassword"
287
- let(:password) { "$1$RRa/wMM/$XltKfoX5ffnexVF4dHZZf/" }
331
+ let(:password) do
332
+ case ohai[:platform]
333
+ when "aix"
334
+ "eL5qfEVznSNss"
335
+ else
336
+ "$1$RRa/wMM/$XltKfoX5ffnexVF4dHZZf/"
337
+ end
338
+ end
339
+
288
340
  let(:system) { false }
289
341
  let(:comment) { "hello this is dog" }
290
342
 
@@ -347,6 +399,11 @@ describe Chef::Resource::User, metadata do
347
399
  File.should_not exist("/home/foo")
348
400
  File.should exist("/home/bar")
349
401
  end
402
+ elsif ohai[:platform] == "aix"
403
+ it "creates the home dir in the desired location" do
404
+ File.should_not exist("/home/foo")
405
+ File.should exist("/home/bar")
406
+ end
350
407
  else
351
408
  it "does not create the home dir in the desired location (XXX)" do
352
409
  # This behavior seems contrary to expectation and non-convergent.
@@ -370,11 +427,18 @@ describe Chef::Resource::User, metadata do
370
427
 
371
428
  context "and a password is added" do
372
429
  # openssl passwd -1 "secretpassword"
373
- let(:password) { "$1$RRa/wMM/$XltKfoX5ffnexVF4dHZZf/" }
430
+ let(:password) do
431
+ case ohai[:platform]
432
+ when "aix"
433
+ "eL5qfEVznSNss"
434
+ else
435
+ "$1$RRa/wMM/$XltKfoX5ffnexVF4dHZZf/"
436
+ end
437
+ end
438
+
374
439
 
375
440
  it "ensures the password is set" do
376
- pw_entry.passwd.should == "x"
377
- expected_shadow = "chef-functional-test:$1$RRa/wMM/$XltKfoX5ffnexVF4dHZZf/"
441
+ password_should_be_set
378
442
  etc_shadow.should include(expected_shadow)
379
443
  end
380
444
 
@@ -382,13 +446,28 @@ describe Chef::Resource::User, metadata do
382
446
 
383
447
  context "and the password is updated" do
384
448
  # openssl passwd -1 "OLDpassword"
385
- let(:existing_password) { "$1$1dVmwm4z$CftsFn8eBDjDRUytYKkXB." }
449
+ let(:existing_password) do
450
+ case ohai[:platform]
451
+ when "aix"
452
+ "jkzG6MvUxjk2g"
453
+ else
454
+ "$1$1dVmwm4z$CftsFn8eBDjDRUytYKkXB."
455
+ end
456
+ end
457
+
386
458
  # openssl passwd -1 "secretpassword"
387
- let(:password) { "$1$RRa/wMM/$XltKfoX5ffnexVF4dHZZf/" }
459
+ let(:password) do
460
+ case ohai[:platform]
461
+ when "aix"
462
+ "eL5qfEVznSNss"
463
+ else
464
+ "$1$RRa/wMM/$XltKfoX5ffnexVF4dHZZf/"
465
+ end
466
+ end
467
+
388
468
 
389
469
  it "ensures the password is set to the desired value" do
390
- pw_entry.passwd.should == "x"
391
- expected_shadow = "chef-functional-test:$1$RRa/wMM/$XltKfoX5ffnexVF4dHZZf/"
470
+ password_should_be_set
392
471
  etc_shadow.should include(expected_shadow)
393
472
  end
394
473
  end
@@ -427,15 +506,47 @@ describe Chef::Resource::User, metadata do
427
506
  shadow_entry.split(':')[1]
428
507
  end
429
508
 
509
+ def aix_user_lock_status
510
+ lock_info = shell_out!("lsuser -a account_locked #{username}")
511
+ status = /\S+\s+account_locked=(\S+)/.match(lock_info.stdout)[1]
512
+ end
513
+
514
+ def user_account_should_be_locked
515
+ case ohai[:platform]
516
+ when "aix"
517
+ aix_user_lock_status.should == "true"
518
+ else
519
+ shadow_password.should include("!")
520
+ end
521
+ end
522
+
523
+ def user_account_should_be_unlocked
524
+ case ohai[:platform]
525
+ when "aix"
526
+ aix_user_lock_status.should == "false"
527
+ else
528
+ shadow_password.should_not include("!")
529
+ end
530
+ end
531
+
532
+ def lock_user_account
533
+ case ohai[:platform]
534
+ when "aix"
535
+ shell_out!("chuser account_locked=true #{username}")
536
+ else
537
+ shell_out!("usermod -L #{username}")
538
+ end
539
+ end
540
+
430
541
  before do
431
542
  # create user and setup locked/unlocked state
432
543
  user_resource.dup.run_action(:create)
433
544
 
434
545
  if user_locked_context?
435
- shell_out!("usermod -L #{username}")
436
- shadow_password.should include("!")
546
+ lock_user_account
547
+ user_account_should_be_locked
437
548
  elsif password
438
- shadow_password.should_not include("!")
549
+ user_account_should_be_unlocked
439
550
  end
440
551
  end
441
552
  end
@@ -457,16 +568,32 @@ describe Chef::Resource::User, metadata do
457
568
 
458
569
  context "and the user is not locked" do
459
570
  # user will be locked if it has no password
460
- let(:password) { "$1$RRa/wMM/$XltKfoX5ffnexVF4dHZZf/" }
571
+ let(:password) do
572
+ case ohai[:platform]
573
+ when "aix"
574
+ "eL5qfEVznSNss"
575
+ else
576
+ "$1$RRa/wMM/$XltKfoX5ffnexVF4dHZZf/"
577
+ end
578
+ end
579
+
461
580
 
462
581
  it "locks the user's password" do
463
- shadow_password.should include("!")
582
+ user_account_should_be_locked
464
583
  end
465
584
  end
466
585
 
467
586
  context "and the user is locked" do
468
587
  # user will be locked if it has no password
469
- let(:password) { "$1$RRa/wMM/$XltKfoX5ffnexVF4dHZZf/" }
588
+ let(:password) do
589
+ case ohai[:platform]
590
+ when "aix"
591
+ "eL5qfEVznSNss"
592
+ else
593
+ "$1$RRa/wMM/$XltKfoX5ffnexVF4dHZZf/"
594
+ end
595
+ end
596
+
470
597
  let(:user_locked_context?) { true }
471
598
  it "does not update the user" do
472
599
  user_resource.should_not be_updated_by_last_action
@@ -518,14 +645,27 @@ describe Chef::Resource::User, metadata do
518
645
  # DEBUG: ---- End output of usermod -U chef-functional-test ----
519
646
  # DEBUG: Ran usermod -U chef-functional-test returned 0
520
647
  @error.should be_nil
521
- pw_entry.passwd.should == 'x'
522
- shadow_password.should == "!"
648
+ if ohai[:platform] == "aix"
649
+ pw_entry.passwd.should == '*'
650
+ user_account_should_be_unlocked
651
+ else
652
+ pw_entry.passwd.should == 'x'
653
+ shadow_password.should include("!")
654
+ end
523
655
  end
524
656
  end
525
657
  end
526
658
 
527
659
  context "and has a password" do
528
- let(:password) { "$1$RRa/wMM/$XltKfoX5ffnexVF4dHZZf/" }
660
+ let(:password) do
661
+ case ohai[:platform]
662
+ when "aix"
663
+ "eL5qfEVznSNss"
664
+ else
665
+ "$1$RRa/wMM/$XltKfoX5ffnexVF4dHZZf/"
666
+ end
667
+ end
668
+
529
669
  context "and the user is not locked" do
530
670
  it "does not update the user" do
531
671
  user_resource.should_not be_updated_by_last_action
@@ -536,9 +676,7 @@ describe Chef::Resource::User, metadata do
536
676
  let(:user_locked_context?) { true }
537
677
 
538
678
  it "unlocks the user's password" do
539
- shadow_entry = etc_shadow.lines.select {|l| l.include?(username) }.first
540
- shadow_password = shadow_entry.split(':')[1]
541
- shadow_password.should_not include("!")
679
+ user_account_should_be_unlocked
542
680
  end
543
681
  end
544
682
  end
@@ -2,7 +2,7 @@ require 'support/shared/integration/integration_helper'
2
2
  require 'chef/mixin/shell_out'
3
3
 
4
4
  describe "chef-client" do
5
- extend IntegrationSupport
5
+ include IntegrationSupport
6
6
  include Chef::Mixin::ShellOut
7
7
 
8
8
  let(:chef_dir) { File.join(File.dirname(__FILE__), "..", "..", "..", "bin") }
@@ -19,7 +19,7 @@ describe "chef-client" do
19
19
  let(:chef_client) { "ruby #{chef_dir}/chef-client" }
20
20
 
21
21
  when_the_repository "has a cookbook with a no-op recipe" do
22
- file 'cookbooks/x/recipes/default.rb', ''
22
+ before { file 'cookbooks/x/recipes/default.rb', '' }
23
23
 
24
24
  it "should complete with success" do
25
25
  file 'config/client.rb', <<EOM
@@ -49,7 +49,7 @@ EOM
49
49
  end
50
50
 
51
51
  context 'and a config file under .chef/knife.rb' do
52
- file '.chef/knife.rb', 'xxx.xxx'
52
+ before { file '.chef/knife.rb', 'xxx.xxx' }
53
53
 
54
54
  it 'should load .chef/knife.rb when -z is specified' do
55
55
  result = shell_out("#{chef_client} -z -o 'x::default' --config-file-jail \"#{path_to('')}\"", :cwd => path_to(''))
@@ -74,7 +74,8 @@ EOM
74
74
  end
75
75
 
76
76
  context 'and a private key' do
77
- file 'mykey.pem', <<EOM
77
+ before do
78
+ file 'mykey.pem', <<EOM
78
79
  -----BEGIN RSA PRIVATE KEY-----
79
80
  MIIEogIBAAKCAQEApubutqtYYQ5UiA9QhWP7UvSmsfHsAoPKEVVPdVW/e8Svwpyf
80
81
  0Xef6OFWVmBE+W442ZjLOe2y6p2nSnaq4y7dg99NFz6X+16mcKiCbj0RCiGqCvCk
@@ -103,6 +104,7 @@ syHLXYFNy0OxMtH/bBAXBGNHd9gf5uOnqh0pYcbe/uRAxumC7Rl0cL509eURiA2T
103
104
  +vFmf54y9YdnLXaqv+FhJT6B6V7WX7IpU9BMqJY1cJYXHuHG2KA=
104
105
  -----END RSA PRIVATE KEY-----
105
106
  EOM
107
+ end
106
108
 
107
109
  it "should complete with success even with a client key" do
108
110
  file 'config/client.rb', <<EOM
@@ -19,7 +19,7 @@ require 'support/shared/integration/integration_helper'
19
19
  require 'chef/mixin/shell_out'
20
20
 
21
21
  describe "chef-client" do
22
- extend IntegrationSupport
22
+ include IntegrationSupport
23
23
  include Chef::Mixin::ShellOut
24
24
 
25
25
  let(:chef_zero_opts) { {:host => "::1"} }
@@ -87,8 +87,8 @@ END_CLIENT_RB
87
87
  when_the_chef_server "is running on IPv6", :not_supported_on_solaris do
88
88
 
89
89
  when_the_repository "has a cookbook with a no-op recipe" do
90
- cookbook 'noop', '1.0.0', { 'metadata.rb' => 'version "1.0.0"' }, "recipes" => {"default.rb" => "#raise 'foo'"}
91
90
  before do
91
+ cookbook 'noop', '1.0.0', { }, "recipes" => {"default.rb" => "#raise 'foo'"}
92
92
  file 'config/client.rb', client_rb_content
93
93
  file 'config/validator.pem', validation_pem
94
94
  end
@@ -102,21 +102,23 @@ END_CLIENT_RB
102
102
 
103
103
  when_the_repository "has a cookbook that hits server APIs" do
104
104
 
105
- recipe=<<-END_RECIPE
106
- actual_item = data_bag_item("expect_bag", "expect_item")
107
- if actual_item.key?("expect_key") and actual_item["expect_key"] == "expect_value"
108
- Chef::Log.info "lookin good"
109
- else
110
- Chef::Log.error("!" * 80)
111
- raise "unexpected data bag item content \#{actual_item.inspect}"
112
- Chef::Log.error("!" * 80)
113
- end
105
+ before do
106
+ recipe=<<-END_RECIPE
107
+ actual_item = data_bag_item("expect_bag", "expect_item")
108
+ if actual_item.key?("expect_key") and actual_item["expect_key"] == "expect_value"
109
+ Chef::Log.info "lookin good"
110
+ else
111
+ Chef::Log.error("!" * 80)
112
+ raise "unexpected data bag item content \#{actual_item.inspect}"
113
+ Chef::Log.error("!" * 80)
114
+ end
114
115
 
115
- END_RECIPE
116
+ END_RECIPE
116
117
 
117
- data_bag('expect_bag', { 'expect_item' => {"expect_key" => "expect_value"} })
118
+ data_bag('expect_bag', { 'expect_item' => {"expect_key" => "expect_value"} })
118
119
 
119
- cookbook 'api-smoke-test', '1.0.0', { 'metadata.rb' => 'version "1.0.0"' }, "recipes" => {"default.rb" => recipe}
120
+ cookbook 'api-smoke-test', '1.0.0', { }, "recipes" => {"default.rb" => recipe}
121
+ end
120
122
 
121
123
  before do
122
124
  file 'config/client.rb', client_rb_content
@@ -23,17 +23,22 @@ require 'chef/knife/raw'
23
23
  require 'chef/knife/cookbook_upload'
24
24
 
25
25
  describe 'ChefFSDataStore tests' do
26
- extend IntegrationSupport
26
+ include IntegrationSupport
27
27
  include KnifeSupport
28
28
 
29
+ let(:cookbook_x_100_metadata_rb) { cb_metadata("x", "1.0.0") }
30
+ let(:cookbook_z_100_metadata_rb) { cb_metadata("z", "1.0.0") }
31
+
29
32
  when_the_repository "has one of each thing" do
30
- file 'clients/x.json', {}
31
- file 'cookbooks/x/metadata.rb', 'version "1.0.0"'
32
- file 'data_bags/x/y.json', {}
33
- file 'environments/x.json', {}
34
- file 'nodes/x.json', {}
35
- file 'roles/x.json', {}
36
- file 'users/x.json', {}
33
+ before do
34
+ file 'clients/x.json', {}
35
+ file 'cookbooks/x/metadata.rb', cookbook_x_100_metadata_rb
36
+ file 'data_bags/x/y.json', {}
37
+ file 'environments/x.json', {}
38
+ file 'nodes/x.json', {}
39
+ file 'roles/x.json', {}
40
+ file 'users/x.json', {}
41
+ end
37
42
 
38
43
  context 'GET /TYPE' do
39
44
  it 'knife list -z -R returns everything' do
@@ -102,41 +107,43 @@ EOM
102
107
 
103
108
  context 'GET /TYPE/NAME' do
104
109
  it 'knife show -z /clients/x.json works' do
105
- knife('show -z /clients/x.json').should_succeed /"x"/
110
+ knife('show -z /clients/x.json').should_succeed( /"x"/ )
106
111
  end
107
112
 
108
113
  it 'knife show -z /cookbooks/x/metadata.rb works' do
109
- knife('show -z /cookbooks/x/metadata.rb').should_succeed "/cookbooks/x/metadata.rb:\nversion \"1.0.0\"\n"
114
+ knife('show -z /cookbooks/x/metadata.rb').should_succeed "/cookbooks/x/metadata.rb:\n#{cookbook_x_100_metadata_rb}\n"
110
115
  end
111
116
 
112
117
  it 'knife show -z /data_bags/x/y.json works' do
113
- knife('show -z /data_bags/x/y.json').should_succeed /"y"/
118
+ knife('show -z /data_bags/x/y.json').should_succeed( /"y"/ )
114
119
  end
115
120
 
116
121
  it 'knife show -z /environments/x.json works' do
117
- knife('show -z /environments/x.json').should_succeed /"x"/
122
+ knife('show -z /environments/x.json').should_succeed( /"x"/ )
118
123
  end
119
124
 
120
125
  it 'knife show -z /nodes/x.json works' do
121
- knife('show -z /nodes/x.json').should_succeed /"x"/
126
+ knife('show -z /nodes/x.json').should_succeed( /"x"/ )
122
127
  end
123
128
 
124
129
  it 'knife show -z /roles/x.json works' do
125
- knife('show -z /roles/x.json').should_succeed /"x"/
130
+ knife('show -z /roles/x.json').should_succeed( /"x"/ )
126
131
  end
127
132
 
128
133
  it 'knife show -z /users/x.json works' do
129
- knife('show -z /users/x.json').should_succeed /"x"/
134
+ knife('show -z /users/x.json').should_succeed( /"x"/ )
130
135
  end
131
136
  end
132
137
 
133
138
  context 'PUT /TYPE/NAME' do
134
- file 'empty.json', {}
135
- file 'rolestuff.json', '{"description":"hi there","name":"x"}'
136
- file 'cookbooks_to_upload/x/metadata.rb', "version '1.0.0'\n\n"
139
+ before do
140
+ file 'empty.json', {}
141
+ file 'rolestuff.json', '{"description":"hi there","name":"x"}'
142
+ file 'cookbooks_to_upload/x/metadata.rb', cookbook_x_100_metadata_rb
143
+ end
137
144
 
138
145
  it 'knife raw -z -i empty.json -m PUT /clients/x' do
139
- knife("raw -z -i #{path_to('empty.json')} -m PUT /clients/x").should_succeed /"x"/
146
+ knife("raw -z -i #{path_to('empty.json')} -m PUT /clients/x").should_succeed( /"x"/ )
140
147
  knife('list --local /clients').should_succeed "/clients/x.json\n"
141
148
  end
142
149
 
@@ -149,32 +156,32 @@ EOM
149
156
  end
150
157
 
151
158
  it 'knife raw -z -i empty.json -m PUT /data/x/y' do
152
- knife("raw -z -i #{path_to('empty.json')} -m PUT /data/x/y").should_succeed /"y"/
159
+ knife("raw -z -i #{path_to('empty.json')} -m PUT /data/x/y").should_succeed( /"y"/ )
153
160
  knife('list --local -Rfp /data_bags').should_succeed "/data_bags/x/\n/data_bags/x/y.json\n"
154
161
  end
155
162
 
156
163
  it 'knife raw -z -i empty.json -m PUT /environments/x' do
157
- knife("raw -z -i #{path_to('empty.json')} -m PUT /environments/x").should_succeed /"x"/
164
+ knife("raw -z -i #{path_to('empty.json')} -m PUT /environments/x").should_succeed( /"x"/ )
158
165
  knife('list --local /environments').should_succeed "/environments/x.json\n"
159
166
  end
160
167
 
161
168
  it 'knife raw -z -i empty.json -m PUT /nodes/x' do
162
- knife("raw -z -i #{path_to('empty.json')} -m PUT /nodes/x").should_succeed /"x"/
169
+ knife("raw -z -i #{path_to('empty.json')} -m PUT /nodes/x").should_succeed( /"x"/ )
163
170
  knife('list --local /nodes').should_succeed "/nodes/x.json\n"
164
171
  end
165
172
 
166
173
  it 'knife raw -z -i empty.json -m PUT /roles/x' do
167
- knife("raw -z -i #{path_to('empty.json')} -m PUT /roles/x").should_succeed /"x"/
174
+ knife("raw -z -i #{path_to('empty.json')} -m PUT /roles/x").should_succeed( /"x"/ )
168
175
  knife('list --local /roles').should_succeed "/roles/x.json\n"
169
176
  end
170
177
 
171
178
  it 'knife raw -z -i empty.json -m PUT /users/x' do
172
- knife("raw -z -i #{path_to('empty.json')} -m PUT /users/x").should_succeed /"x"/
179
+ knife("raw -z -i #{path_to('empty.json')} -m PUT /users/x").should_succeed( /"x"/ )
173
180
  knife('list --local /users').should_succeed "/users/x.json\n"
174
181
  end
175
182
 
176
183
  it 'After knife raw -z -i rolestuff.json -m PUT /roles/x, the output is pretty', :pending => (RUBY_VERSION < "1.9") do
177
- knife("raw -z -i #{path_to('rolestuff.json')} -m PUT /roles/x").should_succeed /"x"/
184
+ knife("raw -z -i #{path_to('rolestuff.json')} -m PUT /roles/x").should_succeed( /"x"/ )
178
185
  IO.read(path_to('roles/x.json')).should == <<EOM.strip
179
186
  {
180
187
  "name": "x",
@@ -187,14 +194,16 @@ EOM
187
194
 
188
195
  when_the_repository 'is empty' do
189
196
  context 'POST /TYPE/NAME' do
190
- file 'empty.json', { 'name' => 'z' }
191
- file 'empty_x.json', { 'name' => 'x' }
192
- file 'empty_id.json', { 'id' => 'z' }
193
- file 'rolestuff.json', '{"description":"hi there","name":"x"}'
194
- file 'cookbooks_to_upload/z/metadata.rb', "version '1.0.0'"
197
+ before do
198
+ file 'empty.json', { 'name' => 'z' }
199
+ file 'empty_x.json', { 'name' => 'x' }
200
+ file 'empty_id.json', { 'id' => 'z' }
201
+ file 'rolestuff.json', '{"description":"hi there","name":"x"}'
202
+ file 'cookbooks_to_upload/z/metadata.rb', cookbook_z_100_metadata_rb
203
+ end
195
204
 
196
205
  it 'knife raw -z -i empty.json -m POST /clients' do
197
- knife("raw -z -i #{path_to('empty.json')} -m POST /clients").should_succeed /uri/
206
+ knife("raw -z -i #{path_to('empty.json')} -m POST /clients").should_succeed( /uri/ )
198
207
  knife('list --local /clients').should_succeed "/clients/z.json\n"
199
208
  end
200
209
 
@@ -207,38 +216,38 @@ EOM
207
216
  end
208
217
 
209
218
  it 'knife raw -z -i empty.json -m POST /data' do
210
- knife("raw -z -i #{path_to('empty.json')} -m POST /data").should_succeed /uri/
219
+ knife("raw -z -i #{path_to('empty.json')} -m POST /data").should_succeed( /uri/ )
211
220
  knife('list --local -Rfp /data_bags').should_succeed "/data_bags/z/\n"
212
221
  end
213
222
 
214
223
  it 'knife raw -z -i empty.json -m POST /data/x' do
215
- knife("raw -z -i #{path_to('empty_x.json')} -m POST /data").should_succeed /uri/
216
- knife("raw -z -i #{path_to('empty_id.json')} -m POST /data/x").should_succeed /"z"/
224
+ knife("raw -z -i #{path_to('empty_x.json')} -m POST /data").should_succeed( /uri/ )
225
+ knife("raw -z -i #{path_to('empty_id.json')} -m POST /data/x").should_succeed( /"z"/ )
217
226
  knife('list --local -Rfp /data_bags').should_succeed "/data_bags/x/\n/data_bags/x/z.json\n"
218
227
  end
219
228
 
220
229
  it 'knife raw -z -i empty.json -m POST /environments' do
221
- knife("raw -z -i #{path_to('empty.json')} -m POST /environments").should_succeed /uri/
230
+ knife("raw -z -i #{path_to('empty.json')} -m POST /environments").should_succeed( /uri/ )
222
231
  knife('list --local /environments').should_succeed "/environments/z.json\n"
223
232
  end
224
233
 
225
234
  it 'knife raw -z -i empty.json -m POST /nodes' do
226
- knife("raw -z -i #{path_to('empty.json')} -m POST /nodes").should_succeed /uri/
235
+ knife("raw -z -i #{path_to('empty.json')} -m POST /nodes").should_succeed( /uri/ )
227
236
  knife('list --local /nodes').should_succeed "/nodes/z.json\n"
228
237
  end
229
238
 
230
239
  it 'knife raw -z -i empty.json -m POST /roles' do
231
- knife("raw -z -i #{path_to('empty.json')} -m POST /roles").should_succeed /uri/
240
+ knife("raw -z -i #{path_to('empty.json')} -m POST /roles").should_succeed( /uri/ )
232
241
  knife('list --local /roles').should_succeed "/roles/z.json\n"
233
242
  end
234
243
 
235
244
  it 'knife raw -z -i empty.json -m POST /users' do
236
- knife("raw -z -i #{path_to('empty.json')} -m POST /users").should_succeed /uri/
245
+ knife("raw -z -i #{path_to('empty.json')} -m POST /users").should_succeed( /uri/ )
237
246
  knife('list --local /users').should_succeed "/users/z.json\n"
238
247
  end
239
248
 
240
249
  it 'After knife raw -z -i rolestuff.json -m POST /roles, the output is pretty', :pending => (RUBY_VERSION < "1.9") do
241
- knife("raw -z -i #{path_to('rolestuff.json')} -m POST /roles").should_succeed /uri/
250
+ knife("raw -z -i #{path_to('rolestuff.json')} -m POST /roles").should_succeed( /uri/ )
242
251
  IO.read(path_to('roles/x.json')).should == <<EOM.strip
243
252
  {
244
253
  "name": "x",
@@ -325,30 +334,32 @@ EOM
325
334
  end
326
335
 
327
336
  context 'PUT /TYPE/NAME' do
328
- file 'empty.json', {}
337
+ before do
338
+ file 'empty.json', {}
339
+ end
329
340
 
330
341
  it 'knife raw -z -i empty.json -m PUT /clients/x fails with 404' do
331
- knife("raw -z -i #{path_to('empty.json')} -m PUT /clients/x").should_fail /404/
342
+ knife("raw -z -i #{path_to('empty.json')} -m PUT /clients/x").should_fail( /404/ )
332
343
  end
333
344
 
334
345
  it 'knife raw -z -i empty.json -m PUT /data/x/y fails with 404' do
335
- knife("raw -z -i #{path_to('empty.json')} -m PUT /data/x/y").should_fail /404/
346
+ knife("raw -z -i #{path_to('empty.json')} -m PUT /data/x/y").should_fail( /404/ )
336
347
  end
337
348
 
338
349
  it 'knife raw -z -i empty.json -m PUT /environments/x fails with 404' do
339
- knife("raw -z -i #{path_to('empty.json')} -m PUT /environments/x").should_fail /404/
350
+ knife("raw -z -i #{path_to('empty.json')} -m PUT /environments/x").should_fail( /404/ )
340
351
  end
341
352
 
342
353
  it 'knife raw -z -i empty.json -m PUT /nodes/x fails with 404' do
343
- knife("raw -z -i #{path_to('empty.json')} -m PUT /nodes/x").should_fail /404/
354
+ knife("raw -z -i #{path_to('empty.json')} -m PUT /nodes/x").should_fail( /404/ )
344
355
  end
345
356
 
346
357
  it 'knife raw -z -i empty.json -m PUT /roles/x fails with 404' do
347
- knife("raw -z -i #{path_to('empty.json')} -m PUT /roles/x").should_fail /404/
358
+ knife("raw -z -i #{path_to('empty.json')} -m PUT /roles/x").should_fail( /404/ )
348
359
  end
349
360
 
350
361
  it 'knife raw -z -i empty.json -m PUT /users/x fails with 404' do
351
- knife("raw -z -i #{path_to('empty.json')} -m PUT /users/x").should_fail /404/
362
+ knife("raw -z -i #{path_to('empty.json')} -m PUT /users/x").should_fail( /404/ )
352
363
  end
353
364
  end
354
365
  end