chef 10.28.2-x86-mingw32 → 10.30.0.rc.0-x86-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 (64) hide show
  1. data/lib/chef.rb +1 -0
  2. data/lib/chef/application/knife.rb +2 -0
  3. data/lib/chef/client.rb +1 -1
  4. data/lib/chef/config.rb +5 -1
  5. data/lib/chef/cookbook_uploader.rb +7 -14
  6. data/lib/chef/data_bag.rb +2 -3
  7. data/lib/chef/exceptions.rb +9 -1
  8. data/lib/chef/formatters/error_inspectors/registration_error_inspector.rb +4 -0
  9. data/lib/chef/knife.rb +3 -0
  10. data/lib/chef/mixin/deep_merge.rb +53 -21
  11. data/lib/chef/monkey_patches/net_http.rb +34 -0
  12. data/lib/chef/monkey_patches/uri.rb +70 -0
  13. data/lib/chef/node.rb +5 -5
  14. data/lib/chef/platform.rb +1 -0
  15. data/lib/chef/provider/cookbook_file.rb +14 -6
  16. data/lib/chef/provider/directory.rb +16 -10
  17. data/lib/chef/provider/file.rb +23 -17
  18. data/lib/chef/provider/group.rb +50 -31
  19. data/lib/chef/provider/group/dscl.rb +26 -4
  20. data/lib/chef/provider/group/gpasswd.rb +14 -19
  21. data/lib/chef/provider/group/groupadd.rb +41 -1
  22. data/lib/chef/provider/group/groupmod.rb +46 -36
  23. data/lib/chef/provider/group/pw.rb +59 -16
  24. data/lib/chef/provider/group/suse.rb +16 -13
  25. data/lib/chef/provider/group/usermod.rb +40 -18
  26. data/lib/chef/provider/group/windows.rb +13 -6
  27. data/lib/chef/provider/package/yum.rb +1 -0
  28. data/lib/chef/provider/remote_file.rb +8 -2
  29. data/lib/chef/provider/ruby_block.rb +1 -1
  30. data/lib/chef/provider/template.rb +11 -5
  31. data/lib/chef/provider/user/useradd.rb +9 -1
  32. data/lib/chef/provider/whyrun_safe_ruby_block.rb +30 -0
  33. data/lib/chef/providers.rb +1 -0
  34. data/lib/chef/resource/group.rb +11 -1
  35. data/lib/chef/resource/whyrun_safe_ruby_block.rb +31 -0
  36. data/lib/chef/resources.rb +1 -0
  37. data/lib/chef/rest.rb +6 -2
  38. data/lib/chef/rest/rest_request.rb +6 -2
  39. data/lib/chef/util/windows/net_group.rb +5 -1
  40. data/lib/chef/version.rb +1 -1
  41. data/spec/functional/resource/base.rb +40 -0
  42. data/spec/functional/resource/group_spec.rb +343 -0
  43. data/spec/spec_helper.rb +4 -0
  44. data/spec/support/platform_helpers.rb +17 -0
  45. data/spec/unit/client_spec.rb +1 -1
  46. data/spec/unit/data_bag_spec.rb +4 -6
  47. data/spec/unit/mixin/deep_merge_spec.rb +416 -190
  48. data/spec/unit/monkey_patches/uri_spec.rb +34 -0
  49. data/spec/unit/node/attribute_spec.rb +49 -14
  50. data/spec/unit/node_spec.rb +31 -0
  51. data/spec/unit/provider/file_spec.rb +27 -27
  52. data/spec/unit/provider/group/dscl_spec.rb +1 -0
  53. data/spec/unit/provider/group/gpasswd_spec.rb +16 -9
  54. data/spec/unit/provider/group/groupadd_spec.rb +3 -4
  55. data/spec/unit/provider/group/groupmod_spec.rb +0 -1
  56. data/spec/unit/provider/group/pw_spec.rb +12 -15
  57. data/spec/unit/provider/group/usermod_spec.rb +21 -6
  58. data/spec/unit/provider/group/windows_spec.rb +0 -8
  59. data/spec/unit/provider/group_spec.rb +26 -4
  60. data/spec/unit/provider/user/useradd_spec.rb +21 -0
  61. data/spec/unit/provider/whyrun_safe_ruby_block_spec.rb +47 -0
  62. data/spec/unit/rest_spec.rb +55 -22
  63. metadata +171 -74
  64. checksums.yaml +0 -7
@@ -59,8 +59,8 @@ class Chef
59
59
  # find the lowest-level directory in @new_resource.path that already exists
60
60
  # make sure we have write permissions to that directory
61
61
  is_parent_writable = lambda do |base_dir|
62
- base_dir = ::File.dirname(base_dir)
63
- if ::File.exist?(base_dir)
62
+ base_dir = ::File.dirname(base_dir)
63
+ if ::File.exist?(base_dir)
64
64
  ::File.writable?(base_dir)
65
65
  else
66
66
  is_parent_writable.call(base_dir)
@@ -70,27 +70,27 @@ class Chef
70
70
  else
71
71
  # in why run mode & parent directory does not exist no permissions check is required
72
72
  # If not in why run, permissions must be valid and we rely on prior assertion that dir exists
73
- if !whyrun_mode? || ::File.exist?(parent_directory)
73
+ if !whyrun_mode? || ::File.exist?(parent_directory)
74
74
  ::File.writable?(parent_directory)
75
75
  else
76
76
  true
77
77
  end
78
78
  end
79
79
  end
80
- a.failure_message(Chef::Exceptions::InsufficientPermissions,
80
+ a.failure_message(Chef::Exceptions::InsufficientPermissions,
81
81
  "Cannot create #{@new_resource} at #{@new_resource.path} due to insufficient permissions")
82
82
  end
83
83
 
84
- requirements.assert(:delete) do |a|
85
- a.assertion do
84
+ requirements.assert(:delete) do |a|
85
+ a.assertion do
86
86
  if ::File.exist?(@new_resource.path)
87
- ::File.directory?(@new_resource.path) && ::File.writable?(@new_resource.path)
87
+ ::File.directory?(@new_resource.path) && ::File.writable?(@new_resource.path)
88
88
  else
89
89
  true
90
90
  end
91
91
  end
92
92
  a.failure_message(RuntimeError, "Cannot delete #{@new_resource} at #{@new_resource.path}!")
93
- # No why-run handling here:
93
+ # No why-run handling here:
94
94
  # * if we don't have permissions, this is unlikely to be changed earlier in the run
95
95
  # * if the target is a file (not a dir), there's no reasonable path by which this would have been changed
96
96
  end
@@ -98,14 +98,14 @@ class Chef
98
98
 
99
99
  def action_create
100
100
  unless ::File.exist?(@new_resource.path)
101
- converge_by("create new directory #{@new_resource.path}") do
101
+ converge_by("create new directory #{@new_resource.path}") do
102
102
  if @new_resource.recursive == true
103
103
  ::FileUtils.mkdir_p(@new_resource.path)
104
104
  else
105
105
  ::Dir.mkdir(@new_resource.path)
106
106
  end
107
107
  Chef::Log.info("#{@new_resource} created directory #{@new_resource.path}")
108
- end
108
+ end
109
109
  end
110
110
  set_all_access_controls
111
111
  end
@@ -123,6 +123,12 @@ class Chef
123
123
  end
124
124
  end
125
125
  end
126
+
127
+ private
128
+
129
+ def managing_content?
130
+ false
131
+ end
126
132
  end
127
133
  end
128
134
  end
@@ -48,9 +48,9 @@ class Chef
48
48
 
49
49
  def diff_current_from_content(new_content)
50
50
  result = nil
51
- Tempfile.open("chef-diff") do |file|
51
+ Tempfile.open("chef-diff") do |file|
52
52
  file.write new_content
53
- file.close
53
+ file.close
54
54
  result = diff_current file.path
55
55
  end
56
56
  result
@@ -96,12 +96,12 @@ class Chef
96
96
  # -u: Unified diff format
97
97
  result = shell_out("diff -u #{target_path} #{temp_path}" )
98
98
  rescue Exception => e
99
- # Should *not* receive this, but in some circumstances it seems that
99
+ # Should *not* receive this, but in some circumstances it seems that
100
100
  # an exception can be thrown even using shell_out instead of shell_out!
101
101
  return [ "Could not determine diff. Error: #{e.message}" ]
102
102
  end
103
103
 
104
- # diff will set a non-zero return code even when there's
104
+ # diff will set a non-zero return code even when there's
105
105
  # valid stdout results, if it encounters something unexpected
106
106
  # So as long as we have output, we'll show it.
107
107
  if not result.stdout.empty?
@@ -118,7 +118,7 @@ class Chef
118
118
  else
119
119
  [ "(no diff)" ]
120
120
  end
121
- end
121
+ end
122
122
 
123
123
  def whyrun_supported?
124
124
  true
@@ -132,14 +132,14 @@ class Chef
132
132
  @current_resource.path(@new_resource.path)
133
133
  if !::File.directory?(@new_resource.path)
134
134
  if ::File.exist?(@new_resource.path)
135
- if @action != :create_if_missing
135
+ if managing_content?
136
136
  @current_resource.checksum(checksum(@new_resource.path))
137
137
  end
138
138
  end
139
139
  end
140
140
  load_current_resource_attrs
141
141
  setup_acl
142
-
142
+
143
143
  @current_resource
144
144
  end
145
145
 
@@ -159,7 +159,7 @@ class Chef
159
159
 
160
160
  if @new_resource.group.nil?
161
161
  @new_resource.group(@current_resource.group)
162
- end
162
+ end
163
163
  if @new_resource.owner.nil?
164
164
  @new_resource.owner(@current_resource.owner)
165
165
  end
@@ -168,7 +168,7 @@ class Chef
168
168
  end
169
169
  end
170
170
  end
171
-
171
+
172
172
  def setup_acl
173
173
  @acl_scanner = ScanAccessControl.new(@new_resource, @current_resource)
174
174
  @acl_scanner.set_all!
@@ -191,7 +191,7 @@ class Chef
191
191
  # Make sure the file is deletable if it exists. Otherwise, fail.
192
192
  requirements.assert(:delete) do |a|
193
193
  a.assertion do
194
- if ::File.exists?(@new_resource.path)
194
+ if ::File.exists?(@new_resource.path)
195
195
  ::File.writable?(@new_resource.path)
196
196
  else
197
197
  true
@@ -211,7 +211,7 @@ class Chef
211
211
  unless compare_content
212
212
  description = []
213
213
  description << "update content in file #{@new_resource.path} from #{short_cksum(@current_resource.checksum)} to #{short_cksum(new_resource_content_checksum)}"
214
- description << diff_current_from_content(@new_resource.content)
214
+ description << diff_current_from_content(@new_resource.content)
215
215
  converge_by(description) do
216
216
  backup @new_resource.path if ::File.exists?(@new_resource.path)
217
217
  ::File.open(@new_resource.path, "w") {|f| f.write @new_resource.content }
@@ -221,10 +221,10 @@ class Chef
221
221
  end
222
222
 
223
223
  # if you are using a tempfile before creating, you must
224
- # override the default with the tempfile, since the
224
+ # override the default with the tempfile, since the
225
225
  # file at @new_resource.path will not be updated on converge
226
226
  def update_new_file_state(path=@new_resource.path)
227
- if !::File.directory?(path)
227
+ if !::File.directory?(path)
228
228
  @new_resource.checksum(checksum(path))
229
229
  end
230
230
 
@@ -247,8 +247,8 @@ class Chef
247
247
  desc = "create new file #{@new_resource.path}"
248
248
  desc << " with content checksum #{short_cksum(new_resource_content_checksum)}" if new_resource.content
249
249
  description << desc
250
- description << diff_current_from_content(@new_resource.content)
251
-
250
+ description << diff_current_from_content(@new_resource.content)
251
+
252
252
  converge_by(description) do
253
253
  Chef::Log.info("entered create")
254
254
  ::File.open(@new_resource.path, "w+") {|f| f.write @new_resource.content }
@@ -264,7 +264,7 @@ class Chef
264
264
 
265
265
  def set_all_access_controls
266
266
  if access_controls.requires_changes?
267
- converge_by(access_controls.describe_changes) do
267
+ converge_by(access_controls.describe_changes) do
268
268
  access_controls.set_all
269
269
  #Update file state with new access values
270
270
  update_new_file_state
@@ -282,7 +282,7 @@ class Chef
282
282
 
283
283
  def action_delete
284
284
  if ::File.exists?(@new_resource.path)
285
- converge_by("delete file #{@new_resource.path}") do
285
+ converge_by("delete file #{@new_resource.path}") do
286
286
  backup unless ::File.symlink?(@new_resource.path)
287
287
  ::File.delete(@new_resource.path)
288
288
  Chef::Log.info("#{@new_resource} deleted file at #{@new_resource.path}")
@@ -342,6 +342,12 @@ class Chef
342
342
 
343
343
  private
344
344
 
345
+ def managing_content?
346
+ return true if @new_resource.checksum
347
+ return true if !@new_resource.content.nil? && @action != :create_if_missing
348
+ false
349
+ end
350
+
345
351
  def short_cksum(checksum)
346
352
  return "none" if checksum.nil?
347
353
  checksum.slice(0,6)
@@ -6,9 +6,9 @@
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
7
7
  # you may not use this file except in compliance with the License.
8
8
  # You may obtain a copy of the License at
9
- #
9
+ #
10
10
  # http://www.apache.org/licenses/LICENSE-2.0
11
- #
11
+ #
12
12
  # Unless required by applicable law or agreed to in writing, software
13
13
  # distributed under the License is distributed on an "AS IS" BASIS,
14
14
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -36,11 +36,11 @@ class Chef
36
36
  super
37
37
  @group_exists = true
38
38
  end
39
-
39
+
40
40
  def load_current_resource
41
41
  @current_resource = Chef::Resource::Group.new(@new_resource.name)
42
42
  @current_resource.group_name(@new_resource.group_name)
43
-
43
+
44
44
  group_info = nil
45
45
  begin
46
46
  group_info = Etc.getgrnam(@new_resource.group_name)
@@ -48,37 +48,47 @@ class Chef
48
48
  @group_exists = false
49
49
  Chef::Log.debug("#{@new_resource} group does not exist")
50
50
  end
51
-
51
+
52
52
  if group_info
53
53
  @new_resource.gid(group_info.gid) unless @new_resource.gid
54
54
  @current_resource.gid(group_info.gid)
55
55
  @current_resource.members(group_info.mem)
56
56
  end
57
-
57
+
58
58
  @current_resource
59
59
  end
60
60
 
61
61
  def define_resource_requirements
62
- requirements.assert(:modify) do |a|
63
- a.assertion { @group_exists }
62
+ requirements.assert(:modify) do |a|
63
+ a.assertion { @group_exists }
64
64
  a.failure_message(Chef::Exceptions::Group, "Cannot modify #{@new_resource} - group does not exist!")
65
65
  a.whyrun("Group #{@new_resource} does not exist. Unless it would have been created earlier in this run, this attempt to modify it would fail.")
66
66
  end
67
+
68
+ requirements.assert(:all_actions) do |a|
69
+ # Make sure that the resource doesn't contain any common
70
+ # user names in the members and exclude_members properties.
71
+ if !@new_resource.members.nil? && !@new_resource.excluded_members.nil?
72
+ common_members = @new_resource.members & @new_resource.excluded_members
73
+ a.assertion { common_members.empty? }
74
+ a.failure_message(Chef::Exceptions::ConflictingMembersInGroup, "Attempting to both add and remove users from a group: '#{common_members.join(', ')}'")
75
+ # No why-run alternative
76
+ end
77
+ end
67
78
  end
68
-
69
- # Check to see if a group needs any changes. Populate
70
- # @change_desc with a description of why a change must occur
79
+
80
+ # Check to see if a group needs any changes. Populate
81
+ # @change_desc with a description of why a change must occur
71
82
  #
72
83
  # ==== Returns
73
84
  # <true>:: If a change is required
74
85
  # <false>:: If a change is not required
75
86
  def compare_group
76
- @change_desc = nil
87
+ @change_desc = [ ]
77
88
  if @new_resource.gid != @current_resource.gid
78
- @change_desc = "change gid #{@current_resource.gid} to #{@new_resource.gid}"
79
- return true
89
+ @change_desc << "change gid #{@current_resource.gid} to #{@new_resource.gid}"
80
90
  end
81
-
91
+
82
92
  if(@new_resource.append)
83
93
  missing_members = []
84
94
  @new_resource.members.each do |member|
@@ -86,35 +96,44 @@ class Chef
86
96
  missing_members << member
87
97
  end
88
98
  if missing_members.length > 0
89
- @change_desc = "add missing member(s): #{missing_members.join(", ")}"
90
- return true
99
+ @change_desc << "add missing member(s): #{missing_members.join(", ")}"
100
+ end
101
+
102
+ members_to_be_removed = []
103
+ @new_resource.excluded_members.each do |member|
104
+ if @current_resource.members.include?(member)
105
+ members_to_be_removed << member
106
+ end
107
+ end
108
+ if members_to_be_removed.length > 0
109
+ @change_desc << "remove existing member(s): #{members_to_be_removed.join(", ")}"
91
110
  end
92
111
  else
93
112
  if @new_resource.members != @current_resource.members
94
- @change_desc = "replace group members with new list of members"
95
- return true
113
+ @change_desc << "replace group members with new list of members"
96
114
  end
97
115
  end
98
- return false
116
+
117
+ !@change_desc.empty?
99
118
  end
100
-
119
+
101
120
  def action_create
102
121
  case @group_exists
103
122
  when false
104
- converge_by("create #{@new_resource}") do
123
+ converge_by("create #{@new_resource}") do
105
124
  create_group
106
125
  Chef::Log.info("#{@new_resource} created")
107
126
  end
108
- else
127
+ else
109
128
  if compare_group
110
- converge_by(["alter group #{@new_resource}", @change_desc ]) do
129
+ converge_by(["alter group #{@new_resource}"] + change_desc) do
111
130
  manage_group
112
131
  Chef::Log.info("#{@new_resource} altered")
113
132
  end
114
133
  end
115
134
  end
116
135
  end
117
-
136
+
118
137
  def action_remove
119
138
  if @group_exists
120
139
  converge_by("remove group #{@new_resource}") do
@@ -123,25 +142,25 @@ class Chef
123
142
  end
124
143
  end
125
144
  end
126
-
145
+
127
146
  def action_manage
128
147
  if @group_exists && compare_group
129
- converge_by(["manage group #{@new_resource}", @change_desc]) do
130
- manage_group
148
+ converge_by(["manage group #{@new_resource}"] + change_desc) do
149
+ manage_group
131
150
  Chef::Log.info("#{@new_resource} managed")
132
151
  end
133
152
  end
134
153
  end
135
-
154
+
136
155
  def action_modify
137
156
  if compare_group
138
- converge_by(["modify group #{@new_resource}", @change_desc]) do
157
+ converge_by(["modify group #{@new_resource}"] + change_desc) do
139
158
  manage_group
140
159
  Chef::Log.info("#{@new_resource} modified")
141
160
  end
142
161
  end
143
162
  end
144
-
163
+
145
164
  def create_group
146
165
  raise NotImplementedError, "subclasses of Chef::Provider::Group should define #create_group"
147
166
  end
@@ -73,14 +73,36 @@ class Chef
73
73
  end
74
74
 
75
75
  def set_members
76
+ # First reset the memberships if the append is not set
76
77
  unless @new_resource.append
77
78
  Chef::Log.debug("#{@new_resource} removing group members #{@current_resource.members.join(' ')}") unless @current_resource.members.empty?
78
79
  safe_dscl("create /Groups/#{@new_resource.group_name} GroupMembers ''") # clear guid list
79
80
  safe_dscl("create /Groups/#{@new_resource.group_name} GroupMembership ''") # clear user list
81
+ @current_resource.members([ ])
80
82
  end
81
- unless @new_resource.members.empty?
82
- Chef::Log.debug("#{@new_resource} setting group members #{@new_resource.members.join(', ')}")
83
- safe_dscl("append /Groups/#{@new_resource.group_name} GroupMembership #{@new_resource.members.join(' ')}")
83
+
84
+ # Add any members that need to be added
85
+ if @new_resource.members && !@new_resource.members.empty?
86
+ members_to_be_added = [ ]
87
+ @new_resource.members.each do |member|
88
+ members_to_be_added << member if !@current_resource.members.include?(member)
89
+ end
90
+ unless members_to_be_added.empty?
91
+ Chef::Log.debug("#{@new_resource} setting group members #{members_to_be_added.join(', ')}")
92
+ safe_dscl("append /Groups/#{@new_resource.group_name} GroupMembership #{members_to_be_added.join(' ')}")
93
+ end
94
+ end
95
+
96
+ # Remove any members that need to be removed
97
+ if @new_resource.excluded_members && !@new_resource.excluded_members.empty?
98
+ members_to_be_removed = [ ]
99
+ @new_resource.excluded_members.each do |member|
100
+ members_to_be_removed << member if @current_resource.members.include?(member)
101
+ end
102
+ unless members_to_be_removed.empty?
103
+ Chef::Log.debug("#{@new_resource} removing group members #{members_to_be_removed.join(', ')}")
104
+ safe_dscl("delete /Groups/#{@new_resource.group_name} GroupMembership #{members_to_be_removed.join(' ')}")
105
+ end
84
106
  end
85
107
  end
86
108
 
@@ -110,7 +132,7 @@ class Chef
110
132
  if @new_resource.gid && (@current_resource.gid != @new_resource.gid)
111
133
  set_gid
112
134
  end
113
- if @new_resource.members && (@current_resource.members != @new_resource.members)
135
+ if @new_resource.members || @new_resource.excluded_members
114
136
  set_members
115
137
  end
116
138
  end
@@ -39,25 +39,20 @@ class Chef
39
39
  end
40
40
  end
41
41
 
42
- def modify_group_members
43
- if(@new_resource.append)
44
- unless @new_resource.members.empty?
45
- @new_resource.members.each do |member|
46
- Chef::Log.debug("#{@new_resource} appending member #{member} to group #{@new_resource.group_name}")
47
- shell_out!("gpasswd -a #{member} #{@new_resource.group_name}")
48
- end
49
- else
50
- Chef::Log.debug("#{@new_resource} not changing group members, the group has no members to add")
51
- end
52
- else
53
- unless @new_resource.members.empty?
54
- Chef::Log.debug("#{@new_resource} setting group members to #{@new_resource.members.join(', ')}")
55
- shell_out!("gpasswd -M #{@new_resource.members.join(',')} #{@new_resource.group_name}")
56
- else
57
- Chef::Log.debug("#{@new_resource} setting group members to: none")
58
- shell_out!("gpasswd -M \"\" #{@new_resource.group_name}")
59
- end
60
- end
42
+ def set_members(members)
43
+ unless members.empty?
44
+ shell_out!("gpasswd -M #{members.join(',')} #{@new_resource.group_name}")
45
+ else
46
+ shell_out!("gpasswd -M \"\" #{@new_resource.group_name}")
47
+ end
48
+ end
49
+
50
+ def add_member(member)
51
+ shell_out!("gpasswd -a #{member} #{@new_resource.group_name}")
52
+ end
53
+
54
+ def remove_member(member)
55
+ shell_out!("gpasswd -d #{member} #{@new_resource.group_name}")
61
56
  end
62
57
  end
63
58
  end