chef 12.5.1-universal-mingw32 → 12.6.0-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 (221) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +6 -1
  3. data/README.md +6 -4
  4. data/Rakefile +1 -4
  5. data/chef-windows.gemspec +21 -0
  6. data/chef.gemspec +58 -0
  7. data/lib/chef/api_client/registration.rb +9 -4
  8. data/lib/chef/application.rb +3 -84
  9. data/lib/chef/application/apply.rb +9 -2
  10. data/lib/chef/application/client.rb +8 -3
  11. data/lib/chef/application/solo.rb +7 -1
  12. data/lib/chef/application/windows_service.rb +21 -6
  13. data/lib/chef/application/windows_service_manager.rb +2 -3
  14. data/lib/chef/audit/runner.rb +1 -0
  15. data/lib/chef/chef_class.rb +1 -11
  16. data/lib/chef/chef_fs/chef_fs_data_store.rb +181 -2
  17. data/lib/chef/chef_fs/file_system/cookbook_subdir.rb +5 -0
  18. data/lib/chef/chef_fs/file_system/file_system_entry.rb +11 -7
  19. data/lib/chef/client.rb +28 -1
  20. data/lib/chef/cookbook/cookbook_collection.rb +14 -1
  21. data/lib/chef/cookbook/cookbook_version_loader.rb +1 -1
  22. data/lib/chef/cookbook/metadata.rb +115 -9
  23. data/lib/chef/cookbook/remote_file_vendor.rb +1 -1
  24. data/lib/chef/cookbook_version.rb +6 -2
  25. data/lib/chef/data_bag.rb +1 -1
  26. data/lib/chef/data_bag_item.rb +1 -1
  27. data/lib/chef/digester.rb +5 -1
  28. data/lib/chef/dsl/chef_provisioning.rb +57 -0
  29. data/lib/chef/dsl/cheffish.rb +64 -0
  30. data/lib/chef/dsl/declare_resource.rb +108 -0
  31. data/lib/chef/dsl/platform_introspection.rb +3 -3
  32. data/lib/chef/dsl/recipe.rb +3 -73
  33. data/lib/chef/dsl/resources.rb +27 -1
  34. data/lib/chef/event_dispatch/base.rb +3 -0
  35. data/lib/chef/event_dispatch/dispatcher.rb +5 -0
  36. data/lib/chef/event_dispatch/events_output_stream.rb +8 -0
  37. data/lib/chef/exceptions.rb +21 -1
  38. data/lib/chef/file_access_control/unix.rb +12 -12
  39. data/lib/chef/file_content_management/deploy/cp.rb +2 -2
  40. data/lib/chef/file_content_management/deploy/mv_unix.rb +4 -4
  41. data/lib/chef/file_content_management/deploy/mv_windows.rb +1 -1
  42. data/lib/chef/formatters/base.rb +7 -0
  43. data/lib/chef/formatters/error_inspectors/compile_error_inspector.rb +2 -2
  44. data/lib/chef/formatters/indentable_output_stream.rb +5 -0
  45. data/lib/chef/http.rb +19 -3
  46. data/lib/chef/http/decompressor.rb +2 -2
  47. data/lib/chef/json_compat.rb +1 -0
  48. data/lib/chef/knife.rb +16 -2
  49. data/lib/chef/knife/bootstrap.rb +55 -10
  50. data/lib/chef/knife/cookbook_site_install.rb +5 -1
  51. data/lib/chef/knife/core/bootstrap_context.rb +2 -1
  52. data/lib/chef/knife/core/node_presenter.rb +1 -1
  53. data/lib/chef/knife/ssh.rb +30 -16
  54. data/lib/chef/knife/ssl_check.rb +4 -2
  55. data/lib/chef/knife/ssl_fetch.rb +3 -2
  56. data/lib/chef/knife/status.rb +14 -1
  57. data/lib/chef/log.rb +14 -0
  58. data/lib/chef/mixin/get_source_from_package.rb +7 -2
  59. data/lib/chef/mixin/properties.rb +302 -0
  60. data/lib/chef/mixin/proxified_socket.rb +38 -0
  61. data/lib/chef/mixin/subclass_directive.rb +37 -0
  62. data/lib/chef/node.rb +13 -5
  63. data/lib/chef/platform/query_helpers.rb +14 -3
  64. data/lib/chef/platform/service_helpers.rb +20 -38
  65. data/lib/chef/policy_builder/expand_node_object.rb +3 -0
  66. data/lib/chef/policy_builder/policyfile.rb +1 -0
  67. data/lib/chef/property.rb +51 -12
  68. data/lib/chef/provider.rb +40 -35
  69. data/lib/chef/provider/deploy.rb +1 -1
  70. data/lib/chef/provider/dsc_resource.rb +54 -20
  71. data/lib/chef/provider/execute.rb +25 -4
  72. data/lib/chef/provider/group.rb +1 -1
  73. data/lib/chef/provider/lwrp_base.rb +1 -0
  74. data/lib/chef/provider/package.rb +76 -30
  75. data/lib/chef/provider/package/dpkg.rb +152 -69
  76. data/lib/chef/provider/package/openbsd.rb +6 -8
  77. data/lib/chef/provider/package/solaris.rb +2 -0
  78. data/lib/chef/provider/package/windows.rb +95 -14
  79. data/lib/chef/provider/package/windows/exe.rb +129 -0
  80. data/lib/chef/provider/package/windows/msi.rb +37 -13
  81. data/lib/chef/provider/package/windows/registry_uninstall_entry.rb +89 -0
  82. data/lib/chef/provider/package/yum.rb +13 -3
  83. data/lib/chef/provider/powershell_script.rb +3 -0
  84. data/lib/chef/provider/remote_file/cache_control_data.rb +37 -4
  85. data/lib/chef/provider/remote_file/http.rb +1 -1
  86. data/lib/chef/provider/script.rb +1 -0
  87. data/lib/chef/provider/service.rb +13 -10
  88. data/lib/chef/provider/service/solaris.rb +43 -17
  89. data/lib/chef/provider/service/upstart.rb +3 -3
  90. data/lib/chef/provider/user.rb +1 -1
  91. data/lib/chef/provider/user/dscl.rb +111 -100
  92. data/lib/chef/provider/user/windows.rb +5 -3
  93. data/lib/chef/recipe.rb +3 -5
  94. data/lib/chef/resource.rb +77 -320
  95. data/lib/chef/resource/action_class.rb +4 -0
  96. data/lib/chef/resource/dpkg_package.rb +4 -3
  97. data/lib/chef/resource/dsc_resource.rb +40 -2
  98. data/lib/chef/resource/execute.rb +9 -1
  99. data/lib/chef/resource/ksh.rb +32 -0
  100. data/lib/chef/resource/lwrp_base.rb +6 -10
  101. data/lib/chef/resource/package.rb +8 -9
  102. data/lib/chef/resource/registry_key.rb +1 -1
  103. data/lib/chef/resource/resource_notification.rb +14 -1
  104. data/lib/chef/resource/script.rb +1 -1
  105. data/lib/chef/resource/windows_package.rb +1 -1
  106. data/lib/chef/resource_builder.rb +14 -7
  107. data/lib/chef/resource_reporter.rb +6 -0
  108. data/lib/chef/resources.rb +1 -7
  109. data/lib/chef/rest.rb +1 -1
  110. data/lib/chef/run_context.rb +45 -2
  111. data/lib/chef/run_list/run_list_expansion.rb +47 -0
  112. data/lib/chef/runner.rb +25 -0
  113. data/lib/chef/search/query.rb +16 -2
  114. data/lib/chef/util/diff.rb +2 -2
  115. data/lib/chef/util/powershell/ps_credential.rb +2 -3
  116. data/lib/chef/version.rb +1 -1
  117. data/lib/chef/win32/api/file.rb +51 -1
  118. data/lib/chef/win32/file.rb +5 -0
  119. data/lib/chef/win32/file/version_info.rb +93 -0
  120. data/lib/chef/win32/mutex.rb +1 -1
  121. data/spec/data/apt/chef-integration-test2-1.0/debian/changelog +5 -0
  122. data/spec/data/apt/chef-integration-test2-1.0/debian/chef-integration-test2.debhelper.log +45 -0
  123. data/spec/data/apt/chef-integration-test2-1.0/debian/chef-integration-test2.substvars +1 -0
  124. data/spec/data/apt/chef-integration-test2-1.0/debian/chef-integration-test2/DEBIAN/conffiles +1 -0
  125. data/spec/data/apt/chef-integration-test2-1.0/debian/chef-integration-test2/DEBIAN/control +10 -0
  126. data/spec/data/apt/chef-integration-test2-1.0/debian/chef-integration-test2/DEBIAN/md5sums +1 -0
  127. data/spec/data/apt/chef-integration-test2-1.0/debian/compat +1 -0
  128. data/spec/data/apt/chef-integration-test2-1.0/debian/conffiles +1 -0
  129. data/spec/data/apt/chef-integration-test2-1.0/debian/control +13 -0
  130. data/spec/data/apt/chef-integration-test2-1.0/debian/copyright +34 -0
  131. data/spec/data/apt/chef-integration-test2-1.0/debian/files +1 -0
  132. data/spec/data/apt/chef-integration-test2-1.0/debian/rules +13 -0
  133. data/spec/data/apt/chef-integration-test2-1.0/debian/source/format +1 -0
  134. data/spec/data/apt/chef-integration-test2_1.0-1.debian.tar.gz +0 -0
  135. data/spec/data/apt/chef-integration-test2_1.0-1.dsc +18 -0
  136. data/spec/data/apt/chef-integration-test2_1.0-1_amd64.build +91 -0
  137. data/spec/data/apt/chef-integration-test2_1.0-1_amd64.changes +31 -0
  138. data/spec/data/apt/chef-integration-test2_1.0-1_amd64.deb +0 -0
  139. data/spec/data/apt/chef-integration-test2_1.0.orig.tar.gz +0 -0
  140. data/spec/functional/application_spec.rb +1 -1
  141. data/spec/functional/audit/runner_spec.rb +4 -0
  142. data/spec/functional/knife/ssh_spec.rb +5 -5
  143. data/spec/functional/notifications_spec.rb +74 -4
  144. data/spec/functional/resource/aix_service_spec.rb +2 -2
  145. data/spec/functional/resource/dpkg_package_spec.rb +339 -0
  146. data/spec/functional/resource/ifconfig_spec.rb +3 -1
  147. data/spec/functional/resource/mount_spec.rb +5 -2
  148. data/spec/functional/resource/package_spec.rb +1 -1
  149. data/spec/functional/resource/user/windows_spec.rb +8 -0
  150. data/spec/functional/resource/windows_package_spec.rb +177 -0
  151. data/spec/functional/win32/version_info_spec.rb +50 -0
  152. data/spec/integration/client/client_spec.rb +80 -0
  153. data/spec/integration/knife/download_spec.rb +9 -0
  154. data/spec/integration/knife/upload_spec.rb +28 -1
  155. data/spec/integration/recipes/lwrp_inline_resources_spec.rb +93 -23
  156. data/spec/integration/recipes/resource_action_spec.rb +211 -116
  157. data/spec/integration/recipes/resource_converge_if_changed_spec.rb +72 -0
  158. data/spec/integration/solo/solo_spec.rb +34 -0
  159. data/spec/spec_helper.rb +11 -1
  160. data/spec/support/platform_helpers.rb +8 -0
  161. data/spec/support/shared/integration/integration_helper.rb +6 -0
  162. data/spec/support/shared/unit/execute_resource.rb +5 -0
  163. data/spec/support/shared/unit/platform_introspector.rb +7 -0
  164. data/spec/tiny_server.rb +6 -2
  165. data/spec/unit/api_client/registration_spec.rb +5 -4
  166. data/spec/unit/application_spec.rb +1 -181
  167. data/spec/unit/chef_fs/file_system/cookbook_subdir_spec.rb +34 -0
  168. data/spec/unit/cookbook/metadata_spec.rb +122 -2
  169. data/spec/unit/http_spec.rb +102 -0
  170. data/spec/unit/knife/bootstrap_spec.rb +55 -13
  171. data/spec/unit/knife/core/bootstrap_context_spec.rb +10 -3
  172. data/spec/unit/knife/ssl_check_spec.rb +7 -3
  173. data/spec/unit/knife/ssl_fetch_spec.rb +2 -2
  174. data/spec/unit/knife/status_spec.rb +13 -13
  175. data/spec/unit/knife_spec.rb +26 -2
  176. data/spec/unit/lwrp_spec.rb +1 -1
  177. data/spec/unit/mixin/properties_spec.rb +97 -0
  178. data/spec/unit/mixin/proxified_socket_spec.rb +94 -0
  179. data/spec/unit/mixin/subclass_directive_spec.rb +45 -0
  180. data/spec/unit/node_spec.rb +9 -1
  181. data/spec/unit/policy_builder/policyfile_spec.rb +2 -0
  182. data/spec/unit/property/validation_spec.rb +14 -12
  183. data/spec/unit/property_spec.rb +56 -0
  184. data/spec/unit/provider/deploy_spec.rb +1 -1
  185. data/spec/unit/provider/dsc_resource_spec.rb +63 -24
  186. data/spec/unit/provider/execute_spec.rb +95 -28
  187. data/spec/unit/provider/package/dpkg_spec.rb +185 -96
  188. data/spec/unit/provider/package/windows/exe_spec.rb +251 -0
  189. data/spec/unit/provider/package/windows/msi_spec.rb +94 -10
  190. data/spec/unit/provider/package/windows_spec.rb +227 -26
  191. data/spec/unit/provider/package/yum_spec.rb +6 -0
  192. data/spec/unit/provider/package_spec.rb +495 -366
  193. data/spec/unit/provider/remote_file/cache_control_data_spec.rb +62 -36
  194. data/spec/unit/provider/script_spec.rb +2 -2
  195. data/spec/unit/provider/service/solaris_smf_service_spec.rb +110 -39
  196. data/spec/unit/provider/service/upstart_service_spec.rb +19 -0
  197. data/spec/unit/provider/user/dscl_spec.rb +14 -0
  198. data/spec/unit/provider/user/windows_spec.rb +2 -2
  199. data/spec/unit/provider/user_spec.rb +9 -0
  200. data/spec/unit/provider_resolver_spec.rb +6 -30
  201. data/spec/unit/recipe_spec.rb +46 -20
  202. data/spec/unit/resource/chef_gem_spec.rb +1 -1
  203. data/spec/unit/resource/dsc_resource_spec.rb +14 -3
  204. data/spec/unit/resource/ksh_spec.rb +40 -0
  205. data/spec/unit/resource/registry_key_spec.rb +2 -2
  206. data/spec/unit/resource/resource_notification_spec.rb +44 -45
  207. data/spec/unit/resource_reporter_spec.rb +7 -0
  208. data/spec/unit/resource_spec.rb +268 -253
  209. data/spec/unit/rest_spec.rb +2 -2
  210. data/spec/unit/run_list/run_list_expansion_spec.rb +18 -3
  211. data/spec/unit/search/query_spec.rb +19 -1
  212. data/spec/unit/util/powershell/ps_credential_spec.rb +8 -1
  213. data/spec/unit/windows_service_spec.rb +83 -38
  214. data/tasks/external_tests.rb +19 -9
  215. data/tasks/rspec.rb +1 -1
  216. metadata +70 -21
  217. data/spec/support/pedant/Gemfile +0 -3
  218. data/spec/support/pedant/pedant_config.rb +0 -129
  219. data/spec/support/pedant/run_pedant.rb +0 -63
  220. data/spec/support/pedant/stickywicket.pem +0 -27
  221. data/spec/unit/provider/package_spec.rbe +0 -0
@@ -30,7 +30,7 @@ class Chef
30
30
  Chef::Platform::ServiceHelpers.service_resource_providers.include?(:upstart)
31
31
  end
32
32
 
33
- UPSTART_STATE_FORMAT = /\w+ \(?(\w+)\)?[\/ ](\w+)/
33
+ UPSTART_STATE_FORMAT = /\S+ \(?(start|stop)?\)? ?[\/ ](\w+)/
34
34
 
35
35
  def self.supports?(resource, action)
36
36
  Chef::Platform::ServiceHelpers.config_for_service(resource.service_name).include?(:upstart)
@@ -224,10 +224,10 @@ class Chef
224
224
  command = "/sbin/status #{@job}"
225
225
  status = popen4(command) do |pid, stdin, stdout, stderr|
226
226
  stdout.each_line do |line|
227
- # rsyslog stop/waiting
228
227
  # service goal/state
229
228
  # OR
230
- # rsyslog (stop) waiting
229
+ # service (instance) goal/state
230
+ # OR
231
231
  # service (goal) state
232
232
  line =~ UPSTART_STATE_FORMAT
233
233
  data = Regexp.last_match
@@ -89,7 +89,7 @@ class Chef
89
89
  end
90
90
 
91
91
  def define_resource_requirements
92
- requirements.assert(:all_actions) do |a|
92
+ requirements.assert(:create, :modify, :manage, :lock, :unlock) do |a|
93
93
  a.assertion { @group_name_resolved }
94
94
  a.failure_message Chef::Exceptions::User, "Couldn't lookup integer GID for group name #{@new_resource.gid}"
95
95
  a.whyrun "group name #{@new_resource.gid} does not exist. This will cause group assignment to fail. Assuming this group will have been created previously."
@@ -44,6 +44,10 @@ class Chef
44
44
  # This provider only supports Mac OSX versions 10.7 and above
45
45
  class Dscl < Chef::Provider::User
46
46
 
47
+ attr_accessor :user_info
48
+ attr_accessor :authentication_authority
49
+ attr_accessor :password_shadow_conversion_algorithm
50
+
47
51
  provides :user, os: "darwin"
48
52
 
49
53
  def define_resource_requirements
@@ -56,19 +60,19 @@ class Chef
56
60
 
57
61
  requirements.assert(:all_actions) do |a|
58
62
  a.assertion { ::File.exists?("/usr/bin/dscl") }
59
- a.failure_message(Chef::Exceptions::User, "Cannot find binary '/usr/bin/dscl' on the system for #{@new_resource}!")
63
+ a.failure_message(Chef::Exceptions::User, "Cannot find binary '/usr/bin/dscl' on the system for #{new_resource}!")
60
64
  end
61
65
 
62
66
  requirements.assert(:all_actions) do |a|
63
67
  a.assertion { ::File.exists?("/usr/bin/plutil") }
64
- a.failure_message(Chef::Exceptions::User, "Cannot find binary '/usr/bin/plutil' on the system for #{@new_resource}!")
68
+ a.failure_message(Chef::Exceptions::User, "Cannot find binary '/usr/bin/plutil' on the system for #{new_resource}!")
65
69
  end
66
70
 
67
71
  requirements.assert(:create, :modify, :manage) do |a|
68
72
  a.assertion do
69
- if @new_resource.password && mac_osx_version_greater_than_10_7?
73
+ if new_resource.password && mac_osx_version_greater_than_10_7?
70
74
  # SALTED-SHA512 password shadow hashes are not supported on 10.8 and above.
71
- !salted_sha512?(@new_resource.password)
75
+ !salted_sha512?(new_resource.password)
72
76
  else
73
77
  true
74
78
  end
@@ -80,10 +84,10 @@ in 'password', with the associated 'salt' and 'iterations'.")
80
84
 
81
85
  requirements.assert(:create, :modify, :manage) do |a|
82
86
  a.assertion do
83
- if @new_resource.password && mac_osx_version_greater_than_10_7? && salted_sha512_pbkdf2?(@new_resource.password)
87
+ if new_resource.password && mac_osx_version_greater_than_10_7? && salted_sha512_pbkdf2?(new_resource.password)
84
88
  # salt and iterations should be specified when
85
89
  # SALTED-SHA512-PBKDF2 password shadow hash is given
86
- !@new_resource.salt.nil? && !@new_resource.iterations.nil?
90
+ !new_resource.salt.nil? && !new_resource.iterations.nil?
87
91
  else
88
92
  true
89
93
  end
@@ -94,9 +98,9 @@ in 'password', with the associated 'salt' and 'iterations'.")
94
98
 
95
99
  requirements.assert(:create, :modify, :manage) do |a|
96
100
  a.assertion do
97
- if @new_resource.password && !mac_osx_version_greater_than_10_7?
101
+ if new_resource.password && !mac_osx_version_greater_than_10_7?
98
102
  # On 10.7 SALTED-SHA512-PBKDF2 is not supported
99
- !salted_sha512_pbkdf2?(@new_resource.password)
103
+ !salted_sha512_pbkdf2?(new_resource.password)
100
104
  else
101
105
  true
102
106
  end
@@ -109,21 +113,21 @@ user password using shadow hash.")
109
113
  end
110
114
 
111
115
  def load_current_resource
112
- @current_resource = Chef::Resource::User.new(@new_resource.username)
113
- @current_resource.username(@new_resource.username)
116
+ @current_resource = Chef::Resource::User.new(new_resource.username)
117
+ current_resource.username(new_resource.username)
114
118
 
115
119
  @user_info = read_user_info
116
- if @user_info
117
- @current_resource.uid(dscl_get(@user_info, :uid))
118
- @current_resource.gid(dscl_get(@user_info, :gid))
119
- @current_resource.home(dscl_get(@user_info, :home))
120
- @current_resource.shell(dscl_get(@user_info, :shell))
121
- @current_resource.comment(dscl_get(@user_info, :comment))
122
- @authentication_authority = dscl_get(@user_info, :auth_authority)
123
-
124
- if @new_resource.password && dscl_get(@user_info, :password) == "********"
120
+ if user_info
121
+ current_resource.uid(dscl_get(user_info, :uid))
122
+ current_resource.gid(dscl_get(user_info, :gid))
123
+ current_resource.home(dscl_get(user_info, :home))
124
+ current_resource.shell(dscl_get(user_info, :shell))
125
+ current_resource.comment(dscl_get(user_info, :comment))
126
+ @authentication_authority = dscl_get(user_info, :auth_authority)
127
+
128
+ if new_resource.password && dscl_get(user_info, :password) == "********"
125
129
  # A password is set. Let's get the password information from shadow file
126
- shadow_hash_binary = dscl_get(@user_info, :shadow_hash)
130
+ shadow_hash_binary = dscl_get(user_info, :shadow_hash)
127
131
 
128
132
  # Calling shell_out directly since we want to give an input stream
129
133
  shadow_hash_xml = convert_binary_plist_to_xml(shadow_hash_binary.string)
@@ -132,26 +136,26 @@ user password using shadow hash.")
132
136
  if shadow_hash["SALTED-SHA512"]
133
137
  # Convert the shadow value from Base64 encoding to hex before consuming them
134
138
  @password_shadow_conversion_algorithm = "SALTED-SHA512"
135
- @current_resource.password(shadow_hash["SALTED-SHA512"].string.unpack('H*').first)
139
+ current_resource.password(shadow_hash["SALTED-SHA512"].string.unpack('H*').first)
136
140
  elsif shadow_hash["SALTED-SHA512-PBKDF2"]
137
141
  @password_shadow_conversion_algorithm = "SALTED-SHA512-PBKDF2"
138
142
  # Convert the entropy from Base64 encoding to hex before consuming them
139
- @current_resource.password(shadow_hash["SALTED-SHA512-PBKDF2"]["entropy"].string.unpack('H*').first)
140
- @current_resource.iterations(shadow_hash["SALTED-SHA512-PBKDF2"]["iterations"])
143
+ current_resource.password(shadow_hash["SALTED-SHA512-PBKDF2"]["entropy"].string.unpack('H*').first)
144
+ current_resource.iterations(shadow_hash["SALTED-SHA512-PBKDF2"]["iterations"])
141
145
  # Convert the salt from Base64 encoding to hex before consuming them
142
- @current_resource.salt(shadow_hash["SALTED-SHA512-PBKDF2"]["salt"].string.unpack('H*').first)
146
+ current_resource.salt(shadow_hash["SALTED-SHA512-PBKDF2"]["salt"].string.unpack('H*').first)
143
147
  else
144
148
  raise(Chef::Exceptions::User,"Unknown shadow_hash format: #{shadow_hash.keys.join(' ')}")
145
149
  end
146
150
  end
147
151
 
148
- convert_group_name if @new_resource.gid
152
+ convert_group_name if new_resource.gid
149
153
  else
150
154
  @user_exists = false
151
- Chef::Log.debug("#{@new_resource} user does not exist")
155
+ Chef::Log.debug("#{new_resource} user does not exist")
152
156
  end
153
157
 
154
- @current_resource
158
+ current_resource
155
159
  end
156
160
 
157
161
  #
@@ -190,15 +194,16 @@ user password using shadow hash.")
190
194
  # Create a user using dscl
191
195
  #
192
196
  def dscl_create_user
193
- run_dscl("create /Users/#{@new_resource.username}")
197
+ run_dscl("create /Users/#{new_resource.username}")
194
198
  end
195
199
 
196
200
  #
197
201
  # Saves the specified Chef user `comment` into RealName attribute
198
- # of Mac user.
202
+ # of Mac user. If `comment` is not specified, it takes `username` value.
199
203
  #
200
204
  def dscl_create_comment
201
- run_dscl("create /Users/#{@new_resource.username} RealName '#{@new_resource.comment}'")
205
+ comment = new_resource.comment || new_resource.username
206
+ run_dscl("create /Users/#{new_resource.username} RealName '#{comment}'")
202
207
  end
203
208
 
204
209
  #
@@ -207,13 +212,14 @@ user password using shadow hash.")
207
212
  # from 200 if `system` is set, 500 otherwise.
208
213
  #
209
214
  def dscl_set_uid
210
- @new_resource.uid(get_free_uid) if (@new_resource.uid.nil? || @new_resource.uid == '')
215
+ # XXX: mutates the new resource
216
+ new_resource.uid(get_free_uid) if (new_resource.uid.nil? || new_resource.uid == '')
211
217
 
212
- if uid_used?(@new_resource.uid)
213
- raise(Chef::Exceptions::RequestedUIDUnavailable, "uid #{@new_resource.uid} is already in use")
218
+ if uid_used?(new_resource.uid)
219
+ raise(Chef::Exceptions::RequestedUIDUnavailable, "uid #{new_resource.uid} is already in use")
214
220
  end
215
221
 
216
- run_dscl("create /Users/#{@new_resource.username} UniqueID #{@new_resource.uid}")
222
+ run_dscl("create /Users/#{new_resource.username} UniqueID #{new_resource.uid}")
217
223
  end
218
224
 
219
225
  #
@@ -222,7 +228,7 @@ user password using shadow hash.")
222
228
  #
223
229
  def get_free_uid(search_limit=1000)
224
230
  uid = nil
225
- base_uid = @new_resource.system ? 200 : 500
231
+ base_uid = new_resource.system ? 200 : 500
226
232
  next_uid_guess = base_uid
227
233
  users_uids = run_dscl("list /Users uid")
228
234
  while(next_uid_guess < search_limit + base_uid)
@@ -248,7 +254,7 @@ user password using shadow hash.")
248
254
  tmap
249
255
  end
250
256
  if uid_map[uid.to_s]
251
- unless uid_map[uid.to_s] == @new_resource.username.to_s
257
+ unless uid_map[uid.to_s] == new_resource.username.to_s
252
258
  return true
253
259
  end
254
260
  end
@@ -257,18 +263,23 @@ user password using shadow hash.")
257
263
 
258
264
  #
259
265
  # Sets the group id for the user using dscl. Fails if a group doesn't
260
- # exist on the system with given group id.
266
+ # exist on the system with given group id. If `gid` is not specified, it
267
+ # sets a default Mac user group "staff", with id 20.
261
268
  #
262
269
  def dscl_set_gid
263
- unless @new_resource.gid && @new_resource.gid.to_s.match(/^\d+$/)
270
+ if new_resource.gid.nil?
271
+ # XXX: mutates the new resource
272
+ new_resource.gid(20)
273
+ elsif !new_resource.gid.to_s.match(/^\d+$/)
264
274
  begin
265
- possible_gid = run_dscl("read /Groups/#{@new_resource.gid} PrimaryGroupID").split(" ").last
275
+ possible_gid = run_dscl("read /Groups/#{new_resource.gid} PrimaryGroupID").split(" ").last
266
276
  rescue Chef::Exceptions::DsclCommandFailed => e
267
- raise Chef::Exceptions::GroupIDNotFound.new("Group not found for #{@new_resource.gid} when creating user #{@new_resource.username}")
277
+ raise Chef::Exceptions::GroupIDNotFound.new("Group not found for #{new_resource.gid} when creating user #{new_resource.username}")
268
278
  end
269
- @new_resource.gid(possible_gid) if possible_gid && possible_gid.match(/^\d+$/)
279
+ # XXX: mutates the new resource
280
+ new_resource.gid(possible_gid) if possible_gid && possible_gid.match(/^\d+$/)
270
281
  end
271
- run_dscl("create /Users/#{@new_resource.username} PrimaryGroupID '#{@new_resource.gid}'")
282
+ run_dscl("create /Users/#{new_resource.username} PrimaryGroupID '#{new_resource.gid}'")
272
283
  end
273
284
 
274
285
  #
@@ -276,15 +287,15 @@ user password using shadow hash.")
276
287
  # directory is managed (moved / created) for the user.
277
288
  #
278
289
  def dscl_set_home
279
- if @new_resource.home.nil? || @new_resource.home.empty?
280
- run_dscl("delete /Users/#{@new_resource.username} NFSHomeDirectory")
290
+ if new_resource.home.nil? || new_resource.home.empty?
291
+ run_dscl("delete /Users/#{new_resource.username} NFSHomeDirectory")
281
292
  return
282
293
  end
283
294
 
284
- if @new_resource.supports[:manage_home]
295
+ if new_resource.supports[:manage_home]
285
296
  validate_home_dir_specification!
286
297
 
287
- if (@current_resource.home == @new_resource.home) && !new_home_exists?
298
+ if (current_resource.home == new_resource.home) && !new_home_exists?
288
299
  ditto_home
289
300
  elsif !current_home_exists? && !new_home_exists?
290
301
  ditto_home
@@ -292,49 +303,49 @@ user password using shadow hash.")
292
303
  move_home
293
304
  end
294
305
  end
295
- run_dscl("create /Users/#{@new_resource.username} NFSHomeDirectory '#{@new_resource.home}'")
306
+ run_dscl("create /Users/#{new_resource.username} NFSHomeDirectory '#{new_resource.home}'")
296
307
  end
297
308
 
298
309
  def validate_home_dir_specification!
299
- unless @new_resource.home =~ /^\//
300
- raise(Chef::Exceptions::InvalidHomeDirectory,"invalid path spec for User: '#{@new_resource.username}', home directory: '#{@new_resource.home}'")
310
+ unless new_resource.home =~ /^\//
311
+ raise(Chef::Exceptions::InvalidHomeDirectory,"invalid path spec for User: '#{new_resource.username}', home directory: '#{new_resource.home}'")
301
312
  end
302
313
  end
303
314
 
304
315
  def current_home_exists?
305
- ::File.exist?("#{@current_resource.home}")
316
+ ::File.exist?("#{current_resource.home}")
306
317
  end
307
318
 
308
319
  def new_home_exists?
309
- ::File.exist?("#{@new_resource.home}")
320
+ ::File.exist?("#{new_resource.home}")
310
321
  end
311
322
 
312
323
  def ditto_home
313
324
  skel = "/System/Library/User Template/English.lproj"
314
325
  raise(Chef::Exceptions::User,"can't find skel at: #{skel}") unless ::File.exists?(skel)
315
- shell_out! "ditto '#{skel}' '#{@new_resource.home}'"
316
- ::FileUtils.chown_R(@new_resource.username,@new_resource.gid.to_s,@new_resource.home)
326
+ shell_out! "ditto '#{skel}' '#{new_resource.home}'"
327
+ ::FileUtils.chown_R(new_resource.username,new_resource.gid.to_s,new_resource.home)
317
328
  end
318
329
 
319
330
  def move_home
320
- Chef::Log.debug("#{@new_resource} moving #{self} home from #{@current_resource.home} to #{@new_resource.home}")
331
+ Chef::Log.debug("#{new_resource} moving #{self} home from #{current_resource.home} to #{new_resource.home}")
321
332
 
322
- src = @current_resource.home
323
- FileUtils.mkdir_p(@new_resource.home)
333
+ src = current_resource.home
334
+ FileUtils.mkdir_p(new_resource.home)
324
335
  files = ::Dir.glob("#{Chef::Util::PathHelper.escape_glob(src)}/*", ::File::FNM_DOTMATCH) - ["#{src}/.","#{src}/.."]
325
- ::FileUtils.mv(files,@new_resource.home, :force => true)
336
+ ::FileUtils.mv(files,new_resource.home, :force => true)
326
337
  ::FileUtils.rmdir(src)
327
- ::FileUtils.chown_R(@new_resource.username,@new_resource.gid.to_s,@new_resource.home)
338
+ ::FileUtils.chown_R(new_resource.username,new_resource.gid.to_s,new_resource.home)
328
339
  end
329
340
 
330
341
  #
331
342
  # Sets the shell for the user using dscl.
332
343
  #
333
344
  def dscl_set_shell
334
- if @new_resource.shell || ::File.exists?("#{@new_resource.shell}")
335
- run_dscl("create /Users/#{@new_resource.username} UserShell '#{@new_resource.shell}'")
345
+ if new_resource.shell || ::File.exists?("#{new_resource.shell}")
346
+ run_dscl("create /Users/#{new_resource.username} UserShell '#{new_resource.shell}'")
336
347
  else
337
- run_dscl("create /Users/#{@new_resource.username} UserShell '/usr/bin/false'")
348
+ run_dscl("create /Users/#{new_resource.username} UserShell '/usr/bin/false'")
338
349
  end
339
350
  end
340
351
 
@@ -345,7 +356,7 @@ user password using shadow hash.")
345
356
  #
346
357
  def set_password
347
358
  # Return if there is no password to set
348
- return if @new_resource.password.nil?
359
+ return if new_resource.password.nil?
349
360
 
350
361
  shadow_info = prepare_password_shadow_info
351
362
 
@@ -355,7 +366,7 @@ user password using shadow hash.")
355
366
  :input => shadow_info.to_plist, :live_stream => shadow_info_binary)
356
367
  command.run_command
357
368
 
358
- if @user_info.nil?
369
+ if user_info.nil?
359
370
  # User is just created. read_user_info() will read the fresh information
360
371
  # for the user with a cache flush. However with experimentation we've seen
361
372
  # that dscl cache is not immediately updated after the creation of the user
@@ -365,8 +376,8 @@ user password using shadow hash.")
365
376
  end
366
377
 
367
378
  # Replace the shadow info in user's plist
368
- dscl_set(@user_info, :shadow_hash, shadow_info_binary)
369
- save_user_info(@user_info)
379
+ dscl_set(user_info, :shadow_hash, shadow_info_binary)
380
+ save_user_info(user_info)
370
381
  end
371
382
 
372
383
  #
@@ -379,12 +390,12 @@ user password using shadow hash.")
379
390
  iterations = nil
380
391
 
381
392
  if mac_osx_version_10_7?
382
- hash_value = if salted_sha512?(@new_resource.password)
383
- @new_resource.password
393
+ hash_value = if salted_sha512?(new_resource.password)
394
+ new_resource.password
384
395
  else
385
396
  # Create a random 4 byte salt
386
397
  salt = OpenSSL::Random.random_bytes(4)
387
- encoded_password = OpenSSL::Digest::SHA512.hexdigest(salt + @new_resource.password)
398
+ encoded_password = OpenSSL::Digest::SHA512.hexdigest(salt + new_resource.password)
388
399
  hash_value = salt.unpack('H*').first + encoded_password
389
400
  end
390
401
 
@@ -392,16 +403,16 @@ user password using shadow hash.")
392
403
  shadow_info["SALTED-SHA512"].string = convert_to_binary(hash_value)
393
404
  shadow_info
394
405
  else
395
- if salted_sha512_pbkdf2?(@new_resource.password)
396
- entropy = convert_to_binary(@new_resource.password)
397
- salt = convert_to_binary(@new_resource.salt)
398
- iterations = @new_resource.iterations
406
+ if salted_sha512_pbkdf2?(new_resource.password)
407
+ entropy = convert_to_binary(new_resource.password)
408
+ salt = convert_to_binary(new_resource.salt)
409
+ iterations = new_resource.iterations
399
410
  else
400
411
  salt = OpenSSL::Random.random_bytes(32)
401
- iterations = @new_resource.iterations # Use the default if not specified by the user
412
+ iterations = new_resource.iterations # Use the default if not specified by the user
402
413
 
403
414
  entropy = OpenSSL::PKCS5::pbkdf2_hmac(
404
- @new_resource.password,
415
+ new_resource.password,
405
416
  salt,
406
417
  iterations,
407
418
  128,
@@ -427,43 +438,43 @@ user password using shadow hash.")
427
438
  # and deleting home directory if needed.
428
439
  #
429
440
  def remove_user
430
- if @new_resource.supports[:manage_home]
441
+ if new_resource.supports[:manage_home]
431
442
  # Remove home directory
432
- FileUtils.rm_rf(@current_resource.home)
443
+ FileUtils.rm_rf(current_resource.home)
433
444
  end
434
445
 
435
446
  # Remove the user from its groups
436
447
  run_dscl("list /Groups").each_line do |group|
437
448
  if member_of_group?(group.chomp)
438
- run_dscl("delete /Groups/#{group.chomp} GroupMembership '#{@new_resource.username}'")
449
+ run_dscl("delete /Groups/#{group.chomp} GroupMembership '#{new_resource.username}'")
439
450
  end
440
451
  end
441
452
 
442
453
  # Remove user account
443
- run_dscl("delete /Users/#{@new_resource.username}")
454
+ run_dscl("delete /Users/#{new_resource.username}")
444
455
  end
445
456
 
446
457
  #
447
458
  # Locks the user.
448
459
  #
449
460
  def lock_user
450
- run_dscl("append /Users/#{@new_resource.username} AuthenticationAuthority ';DisabledUser;'")
461
+ run_dscl("append /Users/#{new_resource.username} AuthenticationAuthority ';DisabledUser;'")
451
462
  end
452
463
 
453
464
  #
454
465
  # Unlocks the user
455
466
  #
456
467
  def unlock_user
457
- auth_string = @authentication_authority.gsub(/AuthenticationAuthority: /,"").gsub(/;DisabledUser;/,"").strip
458
- run_dscl("create /Users/#{@new_resource.username} AuthenticationAuthority '#{auth_string}'")
468
+ auth_string = authentication_authority.gsub(/AuthenticationAuthority: /,"").gsub(/;DisabledUser;/,"").strip
469
+ run_dscl("create /Users/#{new_resource.username} AuthenticationAuthority '#{auth_string}'")
459
470
  end
460
471
 
461
472
  #
462
473
  # Returns true if the user is locked, false otherwise.
463
474
  #
464
475
  def locked?
465
- if @authentication_authority
466
- !!(@authentication_authority =~ /DisabledUser/ )
476
+ if authentication_authority
477
+ !!(authentication_authority =~ /DisabledUser/ )
467
478
  else
468
479
  false
469
480
  end
@@ -485,11 +496,11 @@ user password using shadow hash.")
485
496
  # given attribute.
486
497
  #
487
498
  def diverged?(parameter)
488
- parameter_updated?(parameter) && (not @new_resource.send(parameter).nil?)
499
+ parameter_updated?(parameter) && (not new_resource.send(parameter).nil?)
489
500
  end
490
501
 
491
502
  def parameter_updated?(parameter)
492
- not (@new_resource.send(parameter) == @current_resource.send(parameter))
503
+ not (new_resource.send(parameter) == current_resource.send(parameter))
493
504
  end
494
505
 
495
506
  #
@@ -500,11 +511,11 @@ user password using shadow hash.")
500
511
  # type of the password specified.
501
512
  #
502
513
  def diverged_password?
503
- return false if @new_resource.password.nil?
514
+ return false if new_resource.password.nil?
504
515
 
505
516
  # Dscl provider supports both plain text passwords and shadow hashes.
506
517
  if mac_osx_version_10_7?
507
- if salted_sha512?(@new_resource.password)
518
+ if salted_sha512?(new_resource.password)
508
519
  diverged?(:password)
509
520
  else
510
521
  !salted_sha512_password_match?
@@ -514,14 +525,14 @@ user password using shadow hash.")
514
525
  # will be updated when the user logs in. So it's possible that we will have
515
526
  # SALTED-SHA512 password in the current_resource. In that case we will force
516
527
  # password to be updated.
517
- return true if salted_sha512?(@current_resource.password)
528
+ return true if salted_sha512?(current_resource.password)
518
529
 
519
530
  # Some system users don't have salts; this can happen if the system is
520
531
  # upgraded and the user hasn't logged in yet. In this case, we will force
521
532
  # the password to be updated.
522
- return true if @current_resource.salt.nil?
533
+ return true if current_resource.salt.nil?
523
534
 
524
- if salted_sha512_pbkdf2?(@new_resource.password)
535
+ if salted_sha512_pbkdf2?(new_resource.password)
525
536
  diverged?(:password) || diverged?(:salt) || diverged?(:iterations)
526
537
  else
527
538
  !salted_sha512_pbkdf2_password_match?
@@ -543,7 +554,7 @@ user password using shadow hash.")
543
554
  # GroupMembership: root admin etc
544
555
  members = membership_info.split(" ")
545
556
  members.shift # Get rid of GroupMembership: string
546
- members.include?(@new_resource.username)
557
+ members.include?(new_resource.username)
547
558
  end
548
559
 
549
560
  #
@@ -577,7 +588,7 @@ user password using shadow hash.")
577
588
  shell_out("dscacheutil '-flushcache'")
578
589
 
579
590
  begin
580
- user_plist_file = "#{USER_PLIST_DIRECTORY}/#{@new_resource.username}.plist"
591
+ user_plist_file = "#{USER_PLIST_DIRECTORY}/#{new_resource.username}.plist"
581
592
  user_plist_info = run_plutil("convert xml1 -o - #{user_plist_file}")
582
593
  user_info = Plist::parse_xml(user_plist_info)
583
594
  rescue Chef::Exceptions::PlistUtilCommandFailed
@@ -591,7 +602,7 @@ user password using shadow hash.")
591
602
  # in DSCL_PROPERTY_MAP to the disk.
592
603
  #
593
604
  def save_user_info(user_info)
594
- user_plist_file = "#{USER_PLIST_DIRECTORY}/#{@new_resource.username}.plist"
605
+ user_plist_file = "#{USER_PLIST_DIRECTORY}/#{new_resource.username}.plist"
595
606
  Plist::Emit.save_plist(user_info, user_plist_file)
596
607
  run_plutil("convert binary1 #{user_plist_file}")
597
608
  end
@@ -673,9 +684,9 @@ user password using shadow hash.")
673
684
 
674
685
  def salted_sha512_password_match?
675
686
  # Salt is included in the first 4 bytes of shadow data
676
- salt = @current_resource.password.slice(0,8)
677
- shadow = OpenSSL::Digest::SHA512.hexdigest(convert_to_binary(salt) + @new_resource.password)
678
- @current_resource.password == salt + shadow
687
+ salt = current_resource.password.slice(0,8)
688
+ shadow = OpenSSL::Digest::SHA512.hexdigest(convert_to_binary(salt) + new_resource.password)
689
+ current_resource.password == salt + shadow
679
690
  end
680
691
 
681
692
  def salted_sha512_pbkdf2?(string)
@@ -683,15 +694,15 @@ user password using shadow hash.")
683
694
  end
684
695
 
685
696
  def salted_sha512_pbkdf2_password_match?
686
- salt = convert_to_binary(@current_resource.salt)
697
+ salt = convert_to_binary(current_resource.salt)
687
698
 
688
699
  OpenSSL::PKCS5::pbkdf2_hmac(
689
- @new_resource.password,
700
+ new_resource.password,
690
701
  salt,
691
- @current_resource.iterations,
702
+ current_resource.iterations,
692
703
  128,
693
704
  OpenSSL::Digest::SHA512.new
694
- ).unpack('H*').first == @current_resource.password
705
+ ).unpack('H*').first == current_resource.password
695
706
  end
696
707
 
697
708
  end