chef 10.28.2 → 10.30.0.rc.0

Sign up to get free protection for your applications and to get access to all the features.
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 +119 -44
  64. checksums.yaml +0 -7
@@ -65,8 +65,48 @@ class Chef
65
65
  end
66
66
 
67
67
  def modify_group_members
68
- raise Chef::Exceptions::Group, "you must override modify_group_members in #{self.to_s}"
68
+ if @new_resource.append
69
+ if @new_resource.members && !@new_resource.members.empty?
70
+ members_to_be_added = [ ]
71
+ @new_resource.members.each do |member|
72
+ members_to_be_added << member if !@current_resource.members.include?(member)
73
+ end
74
+ members_to_be_added.each do |member|
75
+ Chef::Log.debug("#{@new_resource} appending member #{member} to group #{@new_resource.group_name}")
76
+ add_member(member)
77
+ end
78
+ end
79
+
80
+ if @new_resource.excluded_members && !@new_resource.excluded_members.empty?
81
+ members_to_be_removed = [ ]
82
+ @new_resource.excluded_members.each do |member|
83
+ members_to_be_removed << member if @current_resource.members.include?(member)
84
+ end
85
+
86
+ members_to_be_removed.each do |member|
87
+ Chef::Log.debug("#{@new_resource} removing member #{member} from group #{@new_resource.group_name}")
88
+ remove_member(member)
89
+ end
90
+ end
91
+ else
92
+ members_description = @new_resource.members.empty? ? "none" : @new_resource.members.join(", ")
93
+ Chef::Log.debug("#{@new_resource} setting group members to: #{members_description}")
94
+ set_members(@new_resource.members)
95
+ end
96
+ end
97
+
98
+ def add_member(member)
99
+ raise Chef::Exceptions::Group, "you must override add_member in #{self.to_s}"
100
+ end
101
+
102
+ def remove_member(member)
103
+ raise Chef::Exceptions::Group, "you must override remove_member in #{self.to_s}"
104
+ end
105
+
106
+ def set_members(members)
107
+ raise Chef::Exceptions::Group, "you must override set_members in #{self.to_s}"
69
108
  end
109
+
70
110
  # Little bit of magic as per Adam's useradd provider to pull the assign the command line flags
71
111
  #
72
112
  # ==== Returns
@@ -44,45 +44,40 @@ class Chef
44
44
  # Manage the group when it already exists
45
45
  def manage_group
46
46
  if @new_resource.append
47
- to_add = @new_resource.members.dup
48
- to_add.reject! { |user| @current_resource.members.include?(user) }
49
-
50
- to_delete = Array.new
51
-
52
- Chef::Log.debug("#{@new_resource} not changing group members, the group has no members to add") if to_add.empty?
47
+ members_to_be_added = [ ]
48
+ if @new_resource.excluded_members && !@new_resource.excluded_members.empty?
49
+ # First find out if any member needs to be removed
50
+ members_to_be_removed = [ ]
51
+ @new_resource.excluded_members.each do |member|
52
+ members_to_be_removed << member if @current_resource.members.include?(member)
53
+ end
54
+
55
+ unless members_to_be_removed.empty?
56
+ # We are using a magic trick to remove the groups.
57
+ reset_group_membership
58
+
59
+ # Capture the members we need to add in
60
+ # members_to_be_added to be added later on.
61
+ @current_resource.members.each do |member|
62
+ members_to_be_added << member unless members_to_be_removed.include?(member)
63
+ end
64
+ end
65
+ end
66
+
67
+ if @new_resource.members && !@new_resource.members.empty?
68
+ @new_resource.members.each do |member|
69
+ members_to_be_added << member if !@current_resource.members.include?(member)
70
+ end
71
+ end
72
+
73
+ Chef::Log.debug("#{@new_resource} not changing group members, the group has no members to add") if members_to_be_added.empty?
74
+
75
+ add_group_members(members_to_be_added)
53
76
  else
54
- to_add = @new_resource.members.dup
55
- to_add.reject! { |user| @current_resource.members.include?(user) }
56
-
57
- to_delete = @current_resource.members.dup
58
- to_delete.reject! { |user| @new_resource.members.include?(user) }
59
-
77
+ # We are resetting the members of a group so use the same trick
78
+ reset_group_membership
60
79
  Chef::Log.debug("#{@new_resource} setting group members to: none") if @new_resource.members.empty?
61
- end
62
-
63
- if to_delete.empty?
64
- # If we are only adding new members to this group, then
65
- # call add_group_members with only those users
66
- add_group_members(to_add)
67
- else
68
- Chef::Log.debug("#{@new_resource} removing members #{to_delete.join(', ')}")
69
-
70
- # This is tricky, but works: rename the existing group to
71
- # "<name>_bak", create a new group with the same GID and
72
- # "<name>", then set correct members on that group
73
- rename = "group mod -n #{@new_resource.group_name}_bak #{@new_resource.group_name}"
74
- shell_out!(rename)
75
-
76
- create = "group add"
77
- create << set_options(:overwrite_gid => true)
78
- shell_out!(create)
79
-
80
- # Ignore to_add here, since we're replacing the group we
81
- # have to add all members who should be in the group.
82
80
  add_group_members(@new_resource.members)
83
-
84
- remove = "group del #{@new_resource.group_name}_bak"
85
- shell_out!(remove)
86
81
  end
87
82
  end
88
83
 
@@ -99,6 +94,21 @@ class Chef
99
94
  end
100
95
  end
101
96
 
97
+ # This is tricky, but works: rename the existing group to
98
+ # "<name>_bak", create a new group with the same GID and
99
+ # "<name>", then set correct members on that group
100
+ def reset_group_membership
101
+ rename = "group mod -n #{@new_resource.group_name}_bak #{@new_resource.group_name}"
102
+ shell_out!(rename)
103
+
104
+ create = "group add"
105
+ create << set_options(:overwrite_gid => true)
106
+ shell_out!(create)
107
+
108
+ remove = "group del #{@new_resource.group_name}_bak"
109
+ shell_out!(remove)
110
+ end
111
+
102
112
  # Little bit of magic as per Adam's useradd provider to pull and assign the command line flags
103
113
  #
104
114
  # ==== Returns
@@ -39,16 +39,28 @@ class Chef
39
39
  def create_group
40
40
  command = "pw groupadd"
41
41
  command << set_options
42
- command << set_members_option
43
- run_command(:command => command)
42
+ member_options = set_members_options
43
+ if member_options.empty?
44
+ run_command(:command => command)
45
+ else
46
+ member_options.each do |option|
47
+ run_command(:command => command + option)
48
+ end
49
+ end
44
50
  end
45
51
 
46
52
  # Manage the group when it already exists
47
53
  def manage_group
48
54
  command = "pw groupmod"
49
55
  command << set_options
50
- command << set_members_option
51
- run_command(:command => command)
56
+ member_options = set_members_options
57
+ if member_options.empty?
58
+ run_command(:command => command)
59
+ else
60
+ member_options.each do |option|
61
+ run_command(:command => command + option)
62
+ end
63
+ end
52
64
  end
53
65
 
54
66
  # Remove the group
@@ -70,21 +82,52 @@ class Chef
70
82
  end
71
83
 
72
84
  # Set the membership option depending on the current resource states
73
- def set_members_option
74
- opt = ""
75
- unless @new_resource.members.empty?
76
- opt << " -M #{@new_resource.members.join(',')}"
77
- Chef::Log.debug("#{@new_resource} setting group members to #{@new_resource.members.join(', ')}")
85
+ def set_members_options
86
+ opts = [ ]
87
+ members_to_be_added = [ ]
88
+ members_to_be_removed = [ ]
89
+
90
+ if @new_resource.append
91
+ # Append is set so we will only add members given in the
92
+ # members list and remove members given in the
93
+ # excluded_members list.
94
+ if @new_resource.members && !@new_resource.members.empty?
95
+ @new_resource.members.each do |member|
96
+ members_to_be_added << member if !@current_resource.members.include?(member)
97
+ end
98
+ end
99
+
100
+ if @new_resource.excluded_members && !@new_resource.excluded_members.empty?
101
+ @new_resource.excluded_members.each do |member|
102
+ members_to_be_removed << member if @current_resource.members.include?(member)
103
+ end
104
+ end
78
105
  else
79
- # New member list is empty so we should delete any old group members
80
- unless @current_resource.members.empty?
81
- opt << " -d #{@current_resource.members.join(',')}"
82
- Chef::Log.debug("#{@new_resource} removing group members #{@current_resource.members.join(', ')}")
83
- else
84
- Chef::Log.debug("#{@new_resource} not changing group members, the group has no members")
106
+ # Append is not set so we're resetting the membership of
107
+ # the group to the given members.
108
+ members_to_be_added = @new_resource.members
109
+ @current_resource.members.each do |member|
110
+ # No need to re-add a member if it's present in the new
111
+ # list of members
112
+ if members_to_be_added.include? member
113
+ members_to_be_added.delete member
114
+ else
115
+ members_to_be_removed << member
116
+ end
85
117
  end
86
118
  end
87
- opt
119
+
120
+ unless members_to_be_added.empty?
121
+ Chef::Log.debug("#{@new_resource} adding group members: #{members_to_be_added.join(',')}")
122
+ opts << " -m #{members_to_be_added.join(',')}"
123
+ end
124
+
125
+ unless members_to_be_removed.empty?
126
+ Chef::Log.debug("#{@new_resource} removing group members: #{members_to_be_removed.join(',')}")
127
+ opts << " -d #{members_to_be_removed.join(',')}"
128
+ end
129
+
130
+ opts
88
131
  end
89
132
 
90
133
  end
@@ -39,21 +39,24 @@ class Chef
39
39
  end
40
40
  end
41
41
 
42
- def modify_group_members
43
- unless @new_resource.members.empty?
44
- if(@new_resource.append)
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!("groupmod -A #{member} #{@new_resource.group_name}")
48
- end
49
- else
50
- Chef::Log.debug("#{@new_resource} setting group members to #{@new_resource.members.join(', ')}")
51
- shell_out!("groupmod -A #{@new_resource.members.join(',')} #{@new_resource.group_name}")
52
- end
53
- else
54
- Chef::Log.debug("#{@new_resource} not changing group members, the group has no members")
42
+ def set_members(members)
43
+ unless @current_resource.members.empty?
44
+ shell_out!("groupmod -R #{@current_resource.members.join(',')} #{@new_resource.group_name}")
55
45
  end
46
+
47
+ unless members.empty?
48
+ shell_out!("groupmod -A #{members.join(',')} #{@new_resource.group_name}")
49
+ end
50
+ end
51
+
52
+ def add_member(member)
53
+ shell_out!("groupmod -A #{member} #{@new_resource.group_name}")
56
54
  end
55
+
56
+ def remove_member(member)
57
+ shell_out!("groupmod -R #{member} #{@new_resource.group_name}")
58
+ end
59
+
57
60
  end
58
61
  end
59
62
  end
@@ -17,12 +17,14 @@
17
17
  #
18
18
 
19
19
  require 'chef/provider/group/groupadd'
20
+ require 'chef/mixin/shell_out'
20
21
 
21
22
  class Chef
22
23
  class Provider
23
24
  class Group
24
25
  class Usermod < Chef::Provider::Group::Groupadd
25
-
26
+ include Chef::Mixin::ShellOut
27
+
26
28
  def load_current_resource
27
29
  super
28
30
  end
@@ -36,32 +38,52 @@ class Chef
36
38
  # No whyrun alternative: this component should be available in the base install of any given system that uses it
37
39
  end
38
40
 
39
- requirements.assert(:modify, :create) do |a|
40
- a.assertion { @new_resource.members.empty? || @new_resource.append }
41
+ requirements.assert(:modify, :manage) do |a|
42
+ a.assertion { @new_resource.members.empty? || @new_resource.append }
41
43
  a.failure_message Chef::Exceptions::Group, "setting group members directly is not supported by #{self.to_s}, must set append true in group"
42
44
  # No whyrun alternative - this action is simply not supported.
43
45
  end
44
- end
45
-
46
- def modify_group_members
47
- case node[:platform]
48
- when "openbsd", "netbsd", "aix", "solaris2"
49
- append_flags = "-G"
50
- when "solaris"
51
- append_flags = "-a -G"
46
+
47
+ requirements.assert(:all_actions) do |a|
48
+ a.assertion { @new_resource.excluded_members.empty? }
49
+ a.failure_message Chef::Exceptions::Group, "excluded_members is not supported by #{self.to_s}"
50
+ # No whyrun alternative - this action is simply not supported.
52
51
  end
52
+ end
53
53
 
54
- unless @new_resource.members.empty?
55
- if(@new_resource.append)
56
- @new_resource.members.each do |member|
57
- Chef::Log.debug("#{@new_resource} appending member #{member} to group #{@new_resource.group_name}")
58
- run_command(:command => "usermod #{append_flags} #{@new_resource.group_name} #{member}" )
59
- end
54
+ def set_members(members)
55
+ return if members.empty?
56
+ # This provider only supports adding members with
57
+ # append. Only if the action is create we will go
58
+ # ahead and add members.
59
+ if @new_resource.action == :create
60
+ members.each do |member|
61
+ add_member(member)
60
62
  end
61
63
  else
62
- Chef::Log.debug("#{@new_resource} not changing group members, the group has no members")
64
+ raise Chef::Exceptions::UnsupportedAction, "Setting members directly is not supported by #{self.to_s}"
63
65
  end
64
66
  end
67
+
68
+ def add_member(member)
69
+ shell_out!("usermod #{append_flags} #{@new_resource.group_name} #{member}")
70
+ end
71
+
72
+ def remove_member(member)
73
+ # This provider only supports adding members with
74
+ # append. This function should never be called.
75
+ raise Chef::Exceptions::UnsupportedAction, "Removing members members is not supported by #{self.to_s}"
76
+ end
77
+
78
+ def append_flags
79
+ case node[:platform]
80
+ when "openbsd", "netbsd", "aix", "solaris2", "smartos"
81
+ "-G"
82
+ when "solaris", "suse", "opensuse"
83
+ "-a -G"
84
+ end
85
+ end
86
+
65
87
  end
66
88
  end
67
89
  end
@@ -57,13 +57,20 @@ class Chef
57
57
 
58
58
  def manage_group
59
59
  if @new_resource.append
60
- begin
61
- #ERROR_MEMBER_IN_ALIAS if a member already exists in the group
62
- @net_group.local_add_members(@new_resource.members)
63
- rescue
64
- members = @new_resource.members + @current_resource.members
65
- @net_group.local_set_members(members.uniq)
60
+ members_to_be_added = [ ]
61
+ @new_resource.members.each do |member|
62
+ members_to_be_added << member if !@current_resource.members.include?(member)
66
63
  end
64
+
65
+ # local_add_members will raise ERROR_MEMBER_IN_ALIAS if a
66
+ # member already exists in the group.
67
+ @net_group.local_add_members(members_to_be_added) unless members_to_be_added.empty?
68
+
69
+ members_to_be_removed = [ ]
70
+ @new_resource.excluded_members.each do |member|
71
+ members_to_be_removed << member if @current_resource.members.include?(member)
72
+ end
73
+ @net_group.local_delete_members(members_to_be_removed) unless members_to_be_removed.empty?
67
74
  else
68
75
  @net_group.local_set_members(@new_resource.members)
69
76
  end
@@ -947,6 +947,7 @@ class Chef
947
947
  end # YumCache
948
948
 
949
949
  include Chef::Mixin::GetSourceFromPackage
950
+ include Chef::Mixin::ShellOut
950
951
 
951
952
  def initialize(new_resource, run_context)
952
953
  super
@@ -42,7 +42,7 @@ class Chef
42
42
  if matches_current_checksum?(raw_file)
43
43
  Chef::Log.debug "#{@new_resource} target and source checksums are the same - not updating"
44
44
  else
45
- description = []
45
+ description = []
46
46
  description << "copy file downloaded from #{@new_resource.source} into #{@new_resource.path}"
47
47
  description << diff_current(raw_file.path)
48
48
  converge_by(description) do
@@ -52,7 +52,7 @@ class Chef
52
52
  raw_file.close!
53
53
  end
54
54
  # whyrun mode cleanup - the temp file will never be used,
55
- # so close/unlink it here.
55
+ # so close/unlink it here.
56
56
  if whyrun_mode?
57
57
  raw_file.close!
58
58
  end
@@ -121,6 +121,12 @@ class Chef
121
121
  false
122
122
  end
123
123
 
124
+ def managing_content?
125
+ return true if @new_resource.checksum
126
+ return true if !@new_resource.source.nil? && @action != :create_if_missing
127
+ false
128
+ end
129
+
124
130
  end
125
131
  end
126
132
  end
@@ -29,7 +29,7 @@ class Chef
29
29
  end
30
30
 
31
31
  def action_create
32
- converge_by("execute the ruby block #{@new_resource.name}") do
32
+ converge_by("execute the ruby block #{@new_resource.name}") do
33
33
  @new_resource.block.call
34
34
  Chef::Log.info("#{@new_resource} called")
35
35
  end