chef 0.8.16 → 0.9.0.a3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of chef might be problematic. Click here for more details.

Files changed (185) hide show
  1. data/bin/shef +1 -0
  2. data/distro/common/man/man1/chef-server-webui.1 +106 -0
  3. data/distro/common/man/man1/chef-server.1 +0 -1
  4. data/distro/common/man/man1/chef-solr-indexer.1 +55 -0
  5. data/distro/common/man/man1/chef-solr.1 +55 -0
  6. data/distro/common/man/man8/chef-client.8 +4 -2
  7. data/distro/common/man/man8/chef-solo.8 +1 -2
  8. data/distro/common/man/man8/chef-solr-rebuild.8 +37 -0
  9. data/distro/common/man/man8/knife.8 +668 -266
  10. data/distro/common/man/man8/shef.8 +45 -0
  11. data/distro/common/markdown/README +3 -0
  12. data/distro/common/markdown/knife.mkd +520 -0
  13. data/distro/debian/etc/default/chef-client +4 -0
  14. data/distro/debian/etc/default/chef-server +6 -0
  15. data/distro/debian/etc/default/chef-server-webui +6 -0
  16. data/distro/debian/etc/default/chef-solr +4 -0
  17. data/distro/debian/etc/default/chef-solr-indexer +4 -0
  18. data/distro/debian/etc/init.d/chef-client +41 -41
  19. data/distro/debian/etc/init.d/chef-server +10 -10
  20. data/distro/debian/etc/init.d/chef-server-webui +121 -0
  21. data/distro/debian/etc/init.d/chef-solr +177 -0
  22. data/distro/debian/etc/init.d/chef-solr-indexer +176 -0
  23. data/distro/redhat/etc/init.d/chef-client +76 -48
  24. data/distro/redhat/etc/init.d/chef-server +85 -51
  25. data/distro/redhat/etc/init.d/chef-server-webui +85 -51
  26. data/distro/redhat/etc/init.d/chef-solr +77 -49
  27. data/distro/redhat/etc/init.d/chef-solr-indexer +77 -48
  28. data/distro/redhat/etc/logrotate.d/chef-client +8 -0
  29. data/distro/redhat/etc/logrotate.d/chef-server +8 -0
  30. data/distro/redhat/etc/logrotate.d/chef-server-webui +8 -0
  31. data/distro/redhat/etc/logrotate.d/chef-solr +8 -0
  32. data/distro/redhat/etc/logrotate.d/chef-solr-indexer +8 -0
  33. data/distro/redhat/etc/sysconfig/chef-client +9 -4
  34. data/distro/redhat/etc/sysconfig/chef-server +10 -6
  35. data/distro/redhat/etc/sysconfig/chef-server-webui +10 -6
  36. data/distro/redhat/etc/sysconfig/chef-solr +3 -4
  37. data/distro/redhat/etc/sysconfig/chef-solr-indexer +3 -3
  38. data/lib/chef.rb +16 -5
  39. data/lib/chef/application/knife.rb +2 -2
  40. data/lib/chef/application/solo.rb +1 -7
  41. data/lib/chef/cache/checksum.rb +12 -5
  42. data/lib/chef/cache/file_cache_by_checksum.rb +52 -0
  43. data/lib/chef/checksum.rb +115 -0
  44. data/lib/chef/client.rb +193 -185
  45. data/lib/chef/config.rb +9 -1
  46. data/lib/chef/cookbook/cookbook_collection.rb +43 -0
  47. data/lib/chef/cookbook/file_system_file_vendor.rb +53 -0
  48. data/lib/chef/cookbook/file_vendor.rb +47 -0
  49. data/lib/chef/cookbook/metadata.rb +34 -35
  50. data/lib/chef/cookbook/metadata/version.rb +1 -1
  51. data/lib/chef/cookbook_loader.rb +70 -45
  52. data/lib/chef/cookbook_version.rb +760 -0
  53. data/lib/chef/couchdb.rb +8 -5
  54. data/lib/chef/data_bag_item.rb +5 -5
  55. data/lib/chef/exceptions.rb +10 -0
  56. data/lib/chef/file_access_control.rb +134 -0
  57. data/lib/chef/handler.rb +62 -0
  58. data/lib/chef/handler/json_file.rb +47 -0
  59. data/lib/chef/knife.rb +14 -2
  60. data/lib/chef/knife/bootstrap.rb +126 -0
  61. data/lib/chef/knife/cookbook_bulk_delete.rb +1 -1
  62. data/lib/chef/knife/cookbook_delete.rb +4 -4
  63. data/lib/chef/knife/cookbook_download.rb +57 -26
  64. data/lib/chef/knife/cookbook_metadata.rb +2 -2
  65. data/lib/chef/knife/cookbook_show.rb +30 -11
  66. data/lib/chef/knife/cookbook_upload.rb +113 -86
  67. data/lib/chef/knife/ec2_server_create.rb +146 -0
  68. data/lib/chef/knife/ec2_server_delete.rb +84 -0
  69. data/lib/chef/knife/ec2_server_list.rb +82 -0
  70. data/lib/chef/knife/status.rb +51 -0
  71. data/lib/chef/mixin/language_include_attribute.rb +16 -11
  72. data/lib/chef/mixin/language_include_recipe.rb +15 -16
  73. data/lib/chef/mixin/recipe_definition_dsl_core.rb +17 -20
  74. data/lib/chef/mixin/shell_out.rb +38 -0
  75. data/lib/chef/mixins.rb +1 -1
  76. data/lib/chef/node.rb +190 -63
  77. data/lib/chef/node/attribute.rb +92 -78
  78. data/lib/chef/platform.rb +24 -4
  79. data/lib/chef/provider.rb +28 -10
  80. data/lib/chef/provider/breakpoint.rb +2 -2
  81. data/lib/chef/provider/cookbook_file.rb +96 -0
  82. data/lib/chef/provider/cron.rb +2 -2
  83. data/lib/chef/provider/deploy.rb +12 -10
  84. data/lib/chef/provider/env.rb +152 -0
  85. data/lib/chef/provider/env/windows.rb +75 -0
  86. data/lib/chef/provider/file.rb +10 -14
  87. data/lib/chef/provider/group.rb +15 -2
  88. data/lib/chef/provider/group/dscl.rb +17 -25
  89. data/lib/chef/provider/group/gpasswd.rb +6 -3
  90. data/lib/chef/provider/group/pw.rb +3 -7
  91. data/lib/chef/provider/group/windows.rb +79 -0
  92. data/lib/chef/provider/link.rb +4 -5
  93. data/lib/chef/provider/mdadm.rb +25 -18
  94. data/lib/chef/provider/mount/mount.rb +28 -27
  95. data/lib/chef/provider/package.rb +35 -35
  96. data/lib/chef/provider/package/dpkg.rb +13 -10
  97. data/lib/chef/provider/package/easy_install.rb +6 -6
  98. data/lib/chef/provider/package/freebsd.rb +17 -51
  99. data/lib/chef/provider/package/rpm.rb +1 -1
  100. data/lib/chef/provider/package/rubygems.rb +391 -74
  101. data/lib/chef/provider/package/yum.rb +2 -2
  102. data/lib/chef/provider/package/zypper.rb +2 -1
  103. data/lib/chef/provider/remote_directory.rb +60 -83
  104. data/lib/chef/provider/remote_file.rb +17 -66
  105. data/lib/chef/provider/script.rb +20 -9
  106. data/lib/chef/provider/service.rb +23 -30
  107. data/lib/chef/provider/service/arch.rb +3 -3
  108. data/lib/chef/provider/service/debian.rb +22 -17
  109. data/lib/chef/provider/service/freebsd.rb +4 -4
  110. data/lib/chef/provider/service/init.rb +2 -2
  111. data/lib/chef/provider/service/redhat.rb +14 -16
  112. data/lib/chef/provider/service/simple.rb +7 -3
  113. data/lib/chef/provider/service/solaris.rb +85 -0
  114. data/lib/chef/provider/service/upstart.rb +12 -7
  115. data/lib/chef/provider/service/windows.rb +2 -2
  116. data/lib/chef/provider/template.rb +133 -118
  117. data/lib/chef/provider/user.rb +34 -17
  118. data/lib/chef/provider/user/dscl.rb +117 -114
  119. data/lib/chef/provider/user/windows.rb +124 -0
  120. data/lib/chef/providers.rb +7 -0
  121. data/lib/chef/recipe.rb +39 -20
  122. data/lib/chef/resource.rb +47 -52
  123. data/lib/chef/resource/apt_package.rb +4 -4
  124. data/lib/chef/resource/bash.rb +4 -4
  125. data/lib/chef/resource/cookbook_file.rb +45 -0
  126. data/lib/chef/resource/cron.rb +3 -3
  127. data/lib/chef/resource/csh.rb +4 -4
  128. data/lib/chef/resource/deploy.rb +3 -3
  129. data/lib/chef/resource/directory.rb +4 -4
  130. data/lib/chef/resource/dpkg_package.rb +4 -4
  131. data/lib/chef/resource/easy_install_package.rb +3 -3
  132. data/lib/chef/resource/env.rb +58 -0
  133. data/lib/chef/resource/erl_call.rb +3 -3
  134. data/lib/chef/resource/execute.rb +3 -3
  135. data/lib/chef/resource/file.rb +3 -3
  136. data/lib/chef/resource/freebsd_package.rb +3 -3
  137. data/lib/chef/resource/gem_package.rb +17 -9
  138. data/lib/chef/resource/git.rb +3 -3
  139. data/lib/chef/resource/group.rb +3 -3
  140. data/lib/chef/resource/http_request.rb +4 -4
  141. data/lib/chef/resource/ifconfig.rb +3 -3
  142. data/lib/chef/resource/link.rb +3 -3
  143. data/lib/chef/resource/log.rb +2 -2
  144. data/lib/chef/resource/macports_package.rb +2 -2
  145. data/lib/chef/resource/mdadm.rb +3 -3
  146. data/lib/chef/resource/mount.rb +2 -2
  147. data/lib/chef/resource/package.rb +4 -4
  148. data/lib/chef/resource/pacman_package.rb +4 -4
  149. data/lib/chef/resource/perl.rb +4 -4
  150. data/lib/chef/resource/portage_package.rb +4 -4
  151. data/lib/chef/resource/python.rb +4 -4
  152. data/lib/chef/resource/remote_directory.rb +3 -3
  153. data/lib/chef/resource/remote_file.rb +26 -3
  154. data/lib/chef/resource/route.rb +3 -3
  155. data/lib/chef/resource/ruby.rb +3 -3
  156. data/lib/chef/resource/ruby_block.rb +3 -2
  157. data/lib/chef/resource/scm.rb +7 -5
  158. data/lib/chef/resource/script.rb +4 -4
  159. data/lib/chef/resource/service.rb +3 -3
  160. data/lib/chef/resource/subversion.rb +4 -2
  161. data/lib/chef/resource/template.rb +3 -3
  162. data/lib/chef/resource/user.rb +3 -3
  163. data/lib/chef/resource/yum_package.rb +3 -3
  164. data/lib/chef/resource_collection.rb +9 -5
  165. data/lib/chef/resources.rb +2 -0
  166. data/lib/chef/rest.rb +4 -0
  167. data/lib/chef/role.rb +2 -0
  168. data/lib/chef/run_context.rb +108 -0
  169. data/lib/chef/run_list.rb +75 -98
  170. data/lib/chef/run_list/run_list_expansion.rb +156 -0
  171. data/lib/chef/run_list/run_list_item.rb +71 -0
  172. data/lib/chef/runner.rb +58 -61
  173. data/lib/chef/sandbox.rb +147 -0
  174. data/lib/chef/shef.rb +4 -3
  175. data/lib/chef/shef/ext.rb +12 -4
  176. data/lib/chef/shef/shef_session.rb +27 -23
  177. data/lib/chef/shell_out.rb +375 -0
  178. data/lib/chef/util/windows.rb +56 -0
  179. data/lib/chef/util/windows/net_group.rb +101 -0
  180. data/lib/chef/util/windows/net_user.rb +198 -0
  181. data/lib/chef/version.rb +20 -0
  182. metadata +112 -22
  183. data/lib/chef/compile.rb +0 -158
  184. data/lib/chef/cookbook.rb +0 -201
  185. data/lib/chef/mixin/generate_url.rb +0 -58
@@ -29,8 +29,8 @@ class Chef
29
29
 
30
30
  attr_accessor :user_exists, :locked
31
31
 
32
- def initialize(node, new_resource, collection=nil, definitions=nil, cookbook_loader=nil)
33
- super(node, new_resource, collection, definitions, cookbook_loader)
32
+ def initialize(new_resource, run_context)
33
+ super
34
34
  @user_exists = true
35
35
  @locked = nil
36
36
  end
@@ -47,12 +47,12 @@ class Chef
47
47
  @current_resource = Chef::Resource::User.new(@new_resource.name)
48
48
  @current_resource.username(@new_resource.username)
49
49
 
50
- user_info = nil
51
50
  begin
52
51
  user_info = Etc.getpwnam(@new_resource.username)
53
52
  rescue ArgumentError => e
54
53
  @user_exists = false
55
54
  Chef::Log.debug("User #{@new_resource.username} does not exist")
55
+ user_info = nil
56
56
  end
57
57
 
58
58
  if user_info
@@ -95,17 +95,14 @@ class Chef
95
95
  end
96
96
 
97
97
  def action_create
98
- case @user_exists
99
- when false
98
+ if !@user_exists
100
99
  create_user
101
100
  Chef::Log.info("Created #{@new_resource}")
102
101
  @new_resource.updated = true
103
- else
104
- if compare_user
105
- manage_user
106
- Chef::Log.info("Altered #{@new_resource}")
107
- @new_resource.updated = true
108
- end
102
+ elsif compare_user
103
+ manage_user
104
+ Chef::Log.info("Altered #{@new_resource}")
105
+ @new_resource.updated = true
109
106
  end
110
107
  end
111
108
 
@@ -116,17 +113,25 @@ class Chef
116
113
  Chef::Log.info("Removed #{@new_resource}")
117
114
  end
118
115
  end
119
-
116
+
117
+ def remove_user
118
+ raise NotImplementedError
119
+ end
120
+
120
121
  def action_manage
121
122
  if @user_exists && compare_user
122
- manage_user
123
+ manage_user
123
124
  @new_resource.updated = true
124
125
  Chef::Log.info("Managed #{@new_resource}")
125
126
  end
126
127
  end
127
-
128
+
129
+ def manage_user
130
+ raise NotImplementedError
131
+ end
132
+
128
133
  def action_modify
129
- if @user_exists
134
+ if @user_exists
130
135
  if compare_user
131
136
  manage_user
132
137
  @new_resource.updated = true
@@ -136,7 +141,7 @@ class Chef
136
141
  raise Chef::Exceptions::User, "Cannot modify #{@new_resource} - user does not exist!"
137
142
  end
138
143
  end
139
-
144
+
140
145
  def action_lock
141
146
  if @user_exists
142
147
  if check_lock() == false
@@ -150,7 +155,15 @@ class Chef
150
155
  raise Chef::Exceptions::User, "Cannot lock #{@new_resource} - user does not exist!"
151
156
  end
152
157
  end
153
-
158
+
159
+ def check_lock
160
+ raise NotImplementedError
161
+ end
162
+
163
+ def lock_user
164
+ raise NotImplementedError
165
+ end
166
+
154
167
  def action_unlock
155
168
  if @user_exists
156
169
  if check_lock() == true
@@ -165,6 +178,10 @@ class Chef
165
178
  end
166
179
  end
167
180
 
181
+ def unlock_user
182
+ raise NotImplementedError
183
+ end
184
+
168
185
  end
169
186
  end
170
187
  end
@@ -16,6 +16,7 @@
16
16
  # limitations under the License.
17
17
  #
18
18
 
19
+ require 'chef/mixin/shell_out'
19
20
  require 'chef/provider/user'
20
21
  require 'openssl'
21
22
 
@@ -23,23 +24,21 @@ class Chef
23
24
  class Provider
24
25
  class User
25
26
  class Dscl < Chef::Provider::User
27
+ include Chef::Mixin::ShellOut
28
+
29
+ NFS_HOME_DIRECTORY = %r{^NFSHomeDirectory: (.*)$}
30
+ AUTHENTICATION_AUTHORITY = %r{^AuthenticationAuthority: (.*)$}
26
31
 
27
32
  def dscl(*args)
28
- host = "."
29
- stdout_result = ""; stderr_result = ""; cmd = "dscl #{host} -#{args.join(' ')}"
30
- status = popen4(cmd) do |pid, stdin, stdout, stderr|
31
- stdout.each { |line| stdout_result << line }
32
- stderr.each { |line| stderr_result << line }
33
- end
34
- return [cmd, status, stdout_result, stderr_result]
33
+ shell_out("dscl . -#{args.join(' ')}")
35
34
  end
36
35
 
37
36
  def safe_dscl(*args)
38
37
  result = dscl(*args)
39
- return "" if ( args.first =~ /^delete/ ) && ( result[1].exitstatus != 0 )
40
- raise(Chef::Exceptions::User,"dscl error: #{result.inspect}") unless result[1].exitstatus == 0
41
- raise(Chef::Exceptions::User,"dscl error: #{result.inspect}") if result[2] =~ /No such key: /
42
- return result[2]
38
+ return "" if ( args.first =~ /^delete/ ) && ( result.exitstatus != 0 )
39
+ raise(Chef::Exceptions::DsclCommandFailed,"dscl error: #{result.inspect}") unless result.exitstatus == 0
40
+ raise(Chef::Exceptions::DsclCommandFailed,"dscl error: #{result.inspect}") if result.stdout =~ /No such key: /
41
+ return result.stdout
43
42
  end
44
43
 
45
44
  # This is handled in providers/group.rb by Etc.getgrnam()
@@ -70,56 +69,28 @@ class Chef
70
69
  end
71
70
 
72
71
  def set_uid
73
- @new_resource.uid(get_free_uid) if [nil,""].include? @new_resource.uid
74
- raise(Chef::Exceptions::User,"uid is already in use") if uid_used?(@new_resource.uid)
72
+ @new_resource.uid(get_free_uid) if (@new_resource.uid.nil? || @new_resource.uid == '')
73
+ if uid_used?(@new_resource.uid)
74
+ raise(Chef::Exceptions::RequestedUIDUnavailable, "uid #{@new_resource.uid} is already in use")
75
+ end
75
76
  safe_dscl("create /Users/#{@new_resource.username} UniqueID #{@new_resource.uid}")
76
77
  end
77
78
 
78
79
  def modify_home
79
80
  return safe_dscl("delete /Users/#{@new_resource.username} NFSHomeDirectory") if (@new_resource.home.nil? || @new_resource.home.empty?)
80
81
  if @new_resource.supports[:manage_home]
81
- unless @new_resource.home =~ /^\//
82
- raise(Chef::Exceptions::User,"invalid path spec for User: '#{@new_resource.username}', home directory: '#{@new_resource.home}'")
83
- end
84
-
85
- ch_eq_nh = ( @current_resource.home == @new_resource.home )
86
- cur_home_exists = ::File.exists?("#{@current_resource.home}")
87
- new_home_exists = ::File.exists?("#{@new_resource.home}")
88
- ditto = false
89
- move = false
82
+ validate_home_dir_specification!
90
83
 
91
- if ch_eq_nh
92
- if !new_home_exists
93
- ditto = true
94
- end
95
- else
96
- if !cur_home_exists
97
- if !new_home_exists
98
- ditto = true
99
- end
100
- elsif cur_home_exists
101
- move = true
102
- end
103
- end
104
-
105
- if ditto
106
- skel = "/System/Library/User Template/English.lproj"
107
- raise(Chef::Exceptions::User,"can't find skel at: #{skel}") unless ::File.exists?(skel)
108
- run_command(:command => "ditto '#{skel}' '#{@new_resource.home}'")
109
- ::FileUtils.chown_R(@new_resource.username,@new_resource.gid.to_s,@new_resource.home)
110
- end
111
-
112
- if move
113
- src = @current_resource.home
114
- FileUtils.mkdir_p(@new_resource.home)
115
- files = ::Dir.glob("#{src}/*", ::File::FNM_DOTMATCH) - ["#{src}/.","#{src}/.."]
116
- ::FileUtils.mv(files,@new_resource.home, :force => true)
117
- ::FileUtils.rmdir(src)
118
- ::FileUtils.chown_R(@new_resource.username,@new_resource.gid.to_s,@new_resource.home)
84
+ if (@current_resource.home == @new_resource.home) && !new_home_exists?
85
+ ditto_home
86
+ elsif !current_home_exists? && !new_home_exists?
87
+ ditto_home
88
+ elsif current_home_exists?
89
+ move_home
119
90
  end
120
91
  end
121
92
  safe_dscl("create /Users/#{@new_resource.username} NFSHomeDirectory '#{@new_resource.home}'")
122
- end
93
+ end
123
94
 
124
95
  def osx_shadow_hash?(string)
125
96
  return !! ( string =~ /^[[:xdigit:]]{1240}$/ )
@@ -130,15 +101,16 @@ class Chef
130
101
  end
131
102
 
132
103
  def guid
133
- safe_dscl("read /Users/#{@new_resource.username} GeneratedUID").gsub(/GeneratedUID: /,"").gsub!(/\n/,"")
104
+ safe_dscl("read /Users/#{@new_resource.username} GeneratedUID").gsub(/GeneratedUID: /,"").strip
134
105
  end
135
106
 
136
107
  def shadow_hash_set?
137
- if safe_dscl("read /Users/#{@new_resource.username}") =~ /AuthenticationAuthority: /
138
- auth_auth = safe_dscl("read /Users/#{@new_resource.username} AuthenticationAuthority")
139
- return !! ( auth_auth =~ /ShadowHash/ )
108
+ user_data = safe_dscl("read /Users/#{@new_resource.username}")
109
+ if user_data =~ /AuthenticationAuthority: / && user_data =~ /ShadowHash/
110
+ true
111
+ else
112
+ false
140
113
  end
141
- return false
142
114
  end
143
115
 
144
116
  def modify_password
@@ -149,12 +121,12 @@ class Chef
149
121
  if osx_shadow_hash?(@new_resource.password)
150
122
  shadow_hash = @new_resource.password.upcase
151
123
  else
152
- salted_sha1 = nil
153
124
  if osx_salted_sha1?(@new_resource.password)
154
125
  salted_sha1 = @new_resource.password.upcase
155
126
  else
156
- hex_salt = ""; chars = ("0".."9").to_a + ("a".."f").to_a
157
- 1.upto(8) { |i| hex_salt << chars[::Kernel.rand(chars.size-1)] }
127
+ hex_salt = ""
128
+ OpenSSL::Random.random_bytes(10).each_byte { |b| hex_salt << b.to_i.to_s(16) }
129
+ hex_salt = hex_salt.slice(0...8)
158
130
  salt = [hex_salt].pack("H*")
159
131
  sha1 = ::OpenSSL::Digest::SHA1.hexdigest(salt+@new_resource.password)
160
132
  salted_sha1 = (hex_salt+sha1).upcase
@@ -179,62 +151,52 @@ class Chef
179
151
  end
180
152
 
181
153
  def create_user
182
- manage_user(false)
154
+ dscl_create_user
155
+ dscl_create_comment
156
+ set_uid
157
+ dscl_set_gid
158
+ modify_home
159
+ dscl_set_shell
160
+ modify_password
183
161
  end
184
162
 
185
- def manage_user(manage = true)
186
- fields = []
187
- if manage
188
- [:username,:comment,:uid,:gid,:home,:shell,:password].each do |field|
189
- if @current_resource.send(field) != @new_resource.send(field)
190
- fields << field if @new_resource.send(field)
191
- end
192
- end
193
- if @new_resource.send(:supports)[:manage_home]
194
- fields << :home if @new_resource.send(:home)
195
- end
196
- fields << :shell if fields.include?(:password)
163
+ def manage_user
164
+ dscl_create_user if diverged?(:username)
165
+ dscl_create_comment if diverged?(:comment)
166
+ set_uid if diverged?(:uid)
167
+ dscl_set_gid if diverged?(:uid)
168
+ modify_home if diverged?(:home)
169
+ dscl_set_shell if diverged?(:shell)
170
+ modify_password if diverged?(:password)
171
+ end
172
+
173
+ def dscl_create_user
174
+ safe_dscl("create /Users/#{@new_resource.username}")
175
+ end
176
+
177
+ def dscl_create_comment
178
+ safe_dscl("create /Users/#{@new_resource.username} RealName '#{@new_resource.comment}'")
179
+ end
180
+
181
+ def dscl_set_gid
182
+ safe_dscl("create /Users/#{@new_resource.username} PrimaryGroupID '#{@new_resource.gid}'")
183
+ end
184
+
185
+ def dscl_set_shell
186
+ if @new_resource.password || ::File.exists?("#{@new_resource.shell}")
187
+ safe_dscl("create /Users/#{@new_resource.username} UserShell '#{@new_resource.shell}'")
197
188
  else
198
- # create
199
- fields = [:username,:comment,:uid,:gid,:home,:shell,:password]
200
- end
201
- fields.uniq!
202
- fields.each do |field|
203
- case field
204
- when :username
205
- safe_dscl("create /Users/#{@new_resource.username}")
206
-
207
- when :comment
208
- safe_dscl("create /Users/#{@new_resource.username} RealName '#{@new_resource.comment}'")
209
-
210
- when :uid
211
- set_uid
212
-
213
- when :gid
214
- safe_dscl("create /Users/#{@new_resource.username} PrimaryGroupID '#{@new_resource.gid}'")
215
-
216
- when :home
217
- modify_home
218
-
219
- when :shell
220
- if @new_resource.password || ::File.exists?("#{@new_resource.shell}")
221
- safe_dscl("create /Users/#{@new_resource.username} UserShell '#{@new_resource.shell}'")
222
- else
223
- safe_dscl("create /Users/#{@new_resource.username} UserShell '/usr/bin/false'")
224
- end
225
-
226
- when :password
227
- modify_password
228
- end
189
+ safe_dscl("create /Users/#{@new_resource.username} UserShell '/usr/bin/false'")
229
190
  end
230
191
  end
231
192
 
232
193
  def remove_user
233
194
  if @new_resource.supports[:manage_home]
234
- # remove home directory
235
- if safe_dscl("read /Users/#{@new_resource.username}") =~ /NFSHomeDirectory/
236
- nfs_home = safe_dscl("read /Users/#{@new_resource.username} NFSHomeDirectory")
237
- nfs_home.gsub!(/NFSHomeDirectory: /,"").gsub!(/\n$/,"")
195
+ user_info = safe_dscl("read /Users/#{@new_resource.username}")
196
+ if nfs_home_match = user_info.match(NFS_HOME_DIRECTORY)
197
+ #nfs_home = safe_dscl("read /Users/#{@new_resource.username} NFSHomeDirectory")
198
+ #nfs_home.gsub!(/NFSHomeDirectory: /,"").gsub!(/\n$/,"")
199
+ nfs_home = nfs_home_match[1]
238
200
  FileUtils.rm_rf(nfs_home)
239
201
  end
240
202
  end
@@ -251,11 +213,12 @@ class Chef
251
213
  end
252
214
 
253
215
  def locked?
254
- if safe_dscl("read /Users/#{@new_resource.username}") =~ /AuthenticationAuthority: /
255
- auth_auth = safe_dscl("read /Users/#{@new_resource.username} AuthenticationAuthority")
256
- return !! ( auth_auth =~ /DisabledUser/ )
216
+ user_info = safe_dscl("read /Users/#{@new_resource.username}")
217
+ if auth_authority_md = AUTHENTICATION_AUTHORITY.match(user_info)
218
+ !!(auth_authority_md[1] =~ /DisabledUser/ )
219
+ else
220
+ false
257
221
  end
258
- return false
259
222
  end
260
223
 
261
224
  def check_lock
@@ -267,9 +230,49 @@ class Chef
267
230
  end
268
231
 
269
232
  def unlock_user
270
- auth_auth = safe_dscl("read /Users/#{@new_resource.username} AuthenticationAuthority")
271
- auth_auth.gsub!(/AuthenticationAuthority: /,"").gsub!(/DisabledUser/,"").gsub!(/[; ]*$/,"")
272
- safe_dscl("create /Users/#{@new_resource.username} AuthenticationAuthority '#{auth_auth}'")
233
+ auth_info = safe_dscl("read /Users/#{@new_resource.username} AuthenticationAuthority")
234
+ auth_string = auth_info.gsub(/AuthenticationAuthority: /,"").gsub(/;DisabledUser;/,"").strip#.gsub!(/[; ]*$/,"")
235
+ safe_dscl("create /Users/#{@new_resource.username} AuthenticationAuthority '#{auth_string}'")
236
+ end
237
+
238
+ def validate_home_dir_specification!
239
+ unless @new_resource.home =~ /^\//
240
+ raise(Chef::Exceptions::InvalidHomeDirectory,"invalid path spec for User: '#{@new_resource.username}', home directory: '#{@new_resource.home}'")
241
+ end
242
+ end
243
+
244
+ def current_home_exists?
245
+ ::File.exist?("#{@current_resource.home}")
246
+ end
247
+
248
+ def new_home_exists?
249
+ ::File.exist?("#{@new_resource.home}")
250
+ end
251
+
252
+ def ditto_home
253
+ skel = "/System/Library/User Template/English.lproj"
254
+ raise(Chef::Exceptions::User,"can't find skel at: #{skel}") unless ::File.exists?(skel)
255
+ shell_out! "ditto '#{skel}' '#{@new_resource.home}'"
256
+ ::FileUtils.chown_R(@new_resource.username,@new_resource.gid.to_s,@new_resource.home)
257
+ end
258
+
259
+ def move_home
260
+ Chef::Log.debug("moving #{self} home from #{@current_resource.home} to #{@new_resource.home}")
261
+
262
+ src = @current_resource.home
263
+ FileUtils.mkdir_p(@new_resource.home)
264
+ files = ::Dir.glob("#{src}/*", ::File::FNM_DOTMATCH) - ["#{src}/.","#{src}/.."]
265
+ ::FileUtils.mv(files,@new_resource.home, :force => true)
266
+ ::FileUtils.rmdir(src)
267
+ ::FileUtils.chown_R(@new_resource.username,@new_resource.gid.to_s,@new_resource.home)
268
+ end
269
+
270
+ def diverged?(parameter)
271
+ parameter_updated?(parameter) && (not @new_resource.send(parameter).nil?)
272
+ end
273
+
274
+ def parameter_updated?(parameter)
275
+ not (@new_resource.send(parameter) == @current_resource.send(parameter))
273
276
  end
274
277
  end
275
278
  end
@@ -0,0 +1,124 @@
1
+ #
2
+ # Author:: Doug MacEachern (<dougm@vmware.com>)
3
+ # Copyright:: Copyright (c) 2010 VMware, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'chef/provider/user'
20
+ if RUBY_PLATFORM =~ /mswin|mingw32|windows/
21
+ require 'chef/util/windows/net_user'
22
+ end
23
+
24
+ class Chef
25
+ class Provider
26
+ class User
27
+ class Windows < Chef::Provider::User
28
+
29
+ def initialize(new_resource,run_context)
30
+ super
31
+ @net_user = Chef::Util::Windows::NetUser.new(@new_resource.name)
32
+ end
33
+
34
+ def load_current_resource
35
+ @current_resource = Chef::Resource::User.new(@new_resource.name)
36
+ @current_resource.username(@new_resource.username)
37
+ user_info = nil
38
+ begin
39
+ user_info = @net_user.get_info
40
+ rescue
41
+ @user_exists = false
42
+ Chef::Log.debug("User #{@new_resource.username} does not exist")
43
+ end
44
+
45
+ if user_info
46
+ @current_resource.uid(user_info[:user_id])
47
+ @current_resource.gid(user_info[:primary_group_id])
48
+ @current_resource.comment(user_info[:full_name])
49
+ @current_resource.home(user_info[:home_dir])
50
+ @current_resource.shell(user_info[:script_path])
51
+ end
52
+
53
+ @current_resource
54
+ end
55
+
56
+ # Check to see if the user needs any changes
57
+ #
58
+ # === Returns
59
+ # <true>:: If a change is required
60
+ # <false>:: If the users are identical
61
+ def compare_user
62
+ unless @net_user.validate_credentials(@new_resource.password)
63
+ Chef::Log.debug("User #{@new_resource.username} password has changed")
64
+ return true
65
+ end
66
+ [ :uid, :gid, :comment, :home, :shell ].any? do |user_attrib|
67
+ !@new_resource.send(user_attrib).nil? && @new_resource.send(user_attrib) != @current_resource.send(user_attrib)
68
+ end
69
+ end
70
+
71
+ def create_user
72
+ @net_user.add(set_options)
73
+ end
74
+
75
+ def manage_user
76
+ @net_user.update(set_options)
77
+ end
78
+
79
+ def remove_user
80
+ @net_user.delete
81
+ end
82
+
83
+ def check_lock
84
+ @net_user.check_enabled
85
+ end
86
+
87
+ def lock_user
88
+ @net_user.disable_account
89
+ end
90
+
91
+ def unlock_user
92
+ @net_user.enable_account
93
+ end
94
+
95
+ def set_options
96
+ opts = {:name => @new_resource.username}
97
+
98
+ field_list = {
99
+ 'comment' => 'full_name',
100
+ 'home' => 'home_dir',
101
+ 'gid' => 'primary_group_id',
102
+ 'uid' => 'user_id',
103
+ 'shell' => 'script_path',
104
+ 'password' => 'password'
105
+ }
106
+
107
+ field_list.sort{ |a,b| a[0] <=> b[0] }.each do |field, option|
108
+ field_symbol = field.to_sym
109
+ if @current_resource.send(field_symbol) != @new_resource.send(field_symbol)
110
+ if @new_resource.send(field_symbol)
111
+ unless field_symbol == :password
112
+ Chef::Log.debug("Setting #{@new_resource} #{field} to #{@new_resource.send(field_symbol)}")
113
+ end
114
+ opts[option.to_sym] = @new_resource.send(field_symbol)
115
+ end
116
+ end
117
+ end
118
+ opts
119
+ end
120
+
121
+ end
122
+ end
123
+ end
124
+ end