chef 11.8.4.ohai7.0 → 11.10.0.alpha.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. checksums.yaml +7 -0
  2. data/distro/common/html/chef-client.8.html +3 -3
  3. data/distro/common/html/chef-expander.8.html +3 -3
  4. data/distro/common/html/chef-expanderctl.8.html +3 -3
  5. data/distro/common/html/chef-server-webui.8.html +3 -3
  6. data/distro/common/html/chef-server.8.html +3 -3
  7. data/distro/common/html/chef-shell.1.html +3 -3
  8. data/distro/common/html/chef-solo.8.html +3 -3
  9. data/distro/common/html/chef-solr.8.html +4 -4
  10. data/distro/common/html/knife-bootstrap.1.html +3 -3
  11. data/distro/common/html/knife-client.1.html +3 -3
  12. data/distro/common/html/knife-configure.1.html +3 -3
  13. data/distro/common/html/knife-cookbook-site.1.html +3 -3
  14. data/distro/common/html/knife-cookbook.1.html +3 -3
  15. data/distro/common/html/knife-data-bag.1.html +3 -3
  16. data/distro/common/html/knife-environment.1.html +3 -3
  17. data/distro/common/html/knife-exec.1.html +3 -3
  18. data/distro/common/html/knife-index.1.html +3 -3
  19. data/distro/common/html/knife-node.1.html +3 -3
  20. data/distro/common/html/knife-role.1.html +3 -3
  21. data/distro/common/html/knife-search.1.html +3 -3
  22. data/distro/common/html/knife-ssh.1.html +3 -3
  23. data/distro/common/html/knife-status.1.html +3 -3
  24. data/distro/common/html/knife-tag.1.html +3 -3
  25. data/distro/common/html/knife.1.html +3 -3
  26. data/distro/common/man/man8/chef-client.8 +3 -3
  27. data/distro/common/man/man8/chef-solo.8 +5 -2
  28. data/lib/chef.rb +2 -0
  29. data/lib/chef/application.rb +7 -2
  30. data/lib/chef/application/apply.rb +6 -0
  31. data/lib/chef/application/client.rb +3 -1
  32. data/lib/chef/application/knife.rb +2 -0
  33. data/lib/chef/application/solo.rb +1 -1
  34. data/lib/chef/client.rb +14 -11
  35. data/lib/chef/config.rb +4 -1
  36. data/lib/chef/cookbook_uploader.rb +14 -7
  37. data/lib/chef/encrypted_data_bag_item.rb +6 -303
  38. data/lib/chef/encrypted_data_bag_item/decryption_failure.rb +22 -0
  39. data/lib/chef/encrypted_data_bag_item/decryptor.rb +201 -0
  40. data/lib/chef/encrypted_data_bag_item/encryptor.rb +142 -0
  41. data/lib/chef/encrypted_data_bag_item/unacceptable_encrypted_data_bag_item_format.rb +22 -0
  42. data/lib/chef/encrypted_data_bag_item/unsupported_cipher.rb +22 -0
  43. data/lib/chef/encrypted_data_bag_item/unsupported_encrypted_data_bag_item_format.rb +22 -0
  44. data/lib/chef/exceptions.rb +1 -0
  45. data/lib/chef/formatters/doc.rb +19 -3
  46. data/lib/chef/http/basic_client.rb +1 -1
  47. data/lib/chef/http/http_request.rb +7 -0
  48. data/lib/chef/knife.rb +8 -1
  49. data/lib/chef/knife/bootstrap.rb +1 -1
  50. data/lib/chef/knife/cookbook_site_share.rb +2 -2
  51. data/lib/chef/knife/cookbook_upload.rb +7 -1
  52. data/lib/chef/knife/core/subcommand_loader.rb +2 -2
  53. data/lib/chef/knife/data_bag_create.rb +7 -0
  54. data/lib/chef/knife/environment_compare.rb +127 -0
  55. data/lib/chef/mixin/command.rb +11 -12
  56. data/lib/chef/mixin/deep_merge.rb +4 -4
  57. data/lib/chef/monkey_patches/net_http.rb +34 -0
  58. data/lib/chef/monkey_patches/uri.rb +70 -0
  59. data/lib/chef/platform/provider_mapping.rb +1 -0
  60. data/lib/chef/provider/cookbook_file.rb +8 -0
  61. data/lib/chef/provider/cron.rb +1 -1
  62. data/lib/chef/provider/directory.rb +7 -0
  63. data/lib/chef/provider/file.rb +17 -4
  64. data/lib/chef/provider/git.rb +23 -5
  65. data/lib/chef/provider/group.rb +30 -11
  66. data/lib/chef/provider/group/dscl.rb +26 -4
  67. data/lib/chef/provider/group/gpasswd.rb +14 -19
  68. data/lib/chef/provider/group/groupadd.rb +41 -1
  69. data/lib/chef/provider/group/groupmod.rb +46 -36
  70. data/lib/chef/provider/group/pw.rb +59 -16
  71. data/lib/chef/provider/group/suse.rb +16 -13
  72. data/lib/chef/provider/group/usermod.rb +38 -15
  73. data/lib/chef/provider/group/windows.rb +13 -6
  74. data/lib/chef/provider/ohai.rb +5 -6
  75. data/lib/chef/provider/remote_file.rb +8 -0
  76. data/lib/chef/provider/template.rb +8 -0
  77. data/lib/chef/provider/user.rb +5 -1
  78. data/lib/chef/provider/user/useradd.rb +7 -0
  79. data/lib/chef/provider/whyrun_safe_ruby_block.rb +30 -0
  80. data/lib/chef/providers.rb +1 -0
  81. data/lib/chef/resource/deploy.rb +18 -0
  82. data/lib/chef/resource/group.rb +11 -0
  83. data/lib/chef/resource/scm.rb +18 -0
  84. data/lib/chef/resource/whyrun_safe_ruby_block.rb +31 -0
  85. data/lib/chef/resources.rb +1 -0
  86. data/lib/chef/run_context.rb +11 -0
  87. data/lib/chef/shell/ext.rb +1 -1
  88. data/lib/chef/util/windows/net_group.rb +5 -1
  89. data/lib/chef/version.rb +1 -1
  90. data/spec/functional/resource/base.rb +3 -1
  91. data/spec/functional/resource/deploy_revision_spec.rb +1 -1
  92. data/spec/functional/resource/git_spec.rb +1 -1
  93. data/spec/functional/resource/group_spec.rb +257 -118
  94. data/spec/integration/client/client_spec.rb +82 -8
  95. data/spec/integration/client/ipv6_spec.rb +133 -0
  96. data/spec/integration/knife/cookbook_api_ipv6_spec.rb +111 -0
  97. data/spec/scripts/ssl-serve.rb +52 -0
  98. data/spec/spec_helper.rb +7 -6
  99. data/spec/support/platform_helpers.rb +21 -0
  100. data/spec/support/shared/functional/windows_script.rb +2 -1
  101. data/spec/support/shared/unit/provider/file.rb +181 -43
  102. data/spec/support/shared/unit/provider/useradd_based_user_provider.rb +18 -0
  103. data/spec/unit/application/client_spec.rb +1 -0
  104. data/spec/unit/client_spec.rb +14 -1
  105. data/spec/unit/config_spec.rb +20 -0
  106. data/spec/unit/encrypted_data_bag_item_spec.rb +32 -18
  107. data/spec/unit/knife/cookbook_upload_spec.rb +14 -0
  108. data/spec/unit/knife/core/subcommand_loader_spec.rb +2 -2
  109. data/spec/unit/knife/data_bag_create_spec.rb +7 -0
  110. data/spec/unit/knife/environment_compare_spec.rb +112 -0
  111. data/spec/unit/knife_spec.rb +6 -1
  112. data/spec/unit/monkey_patches/uri_spec.rb +34 -0
  113. data/spec/unit/provider/cookbook_file_spec.rb +2 -1
  114. data/spec/unit/provider/cron_spec.rb +6 -0
  115. data/spec/unit/provider/file_spec.rb +3 -1
  116. data/spec/unit/provider/git_spec.rb +28 -4
  117. data/spec/unit/provider/group/dscl_spec.rb +1 -0
  118. data/spec/unit/provider/group/gpasswd_spec.rb +16 -9
  119. data/spec/unit/provider/group/groupadd_spec.rb +3 -4
  120. data/spec/unit/provider/group/groupmod_spec.rb +0 -1
  121. data/spec/unit/provider/group/pw_spec.rb +11 -14
  122. data/spec/unit/provider/group/usermod_spec.rb +19 -4
  123. data/spec/unit/provider/group/windows_spec.rb +0 -8
  124. data/spec/unit/provider/group_spec.rb +26 -4
  125. data/spec/unit/provider/ohai_spec.rb +1 -0
  126. data/spec/unit/provider/remote_file_spec.rb +4 -3
  127. data/spec/unit/provider/template_spec.rb +5 -3
  128. data/spec/unit/provider/user_spec.rb +6 -0
  129. data/spec/unit/provider/whyrun_safe_ruby_block_spec.rb +47 -0
  130. data/spec/unit/resource/scm_spec.rb +10 -0
  131. data/spec/unit/rest/auth_credentials_spec.rb +4 -1
  132. data/spec/unit/rest_spec.rb +12 -3
  133. metadata +69 -97
  134. data/spec/functional/resource/ohai_spec.rb +0 -65
@@ -85,7 +85,7 @@ class Chef
85
85
 
86
86
  def cron_different?
87
87
  CRON_ATTRIBUTES.any? do |cron_var|
88
- !@new_resource.send(cron_var).nil? && @new_resource.send(cron_var) != @current_resource.send(cron_var)
88
+ @new_resource.send(cron_var) != @current_resource.send(cron_var)
89
89
  end
90
90
  end
91
91
 
@@ -123,6 +123,13 @@ class Chef
123
123
  end
124
124
  end
125
125
  end
126
+
127
+ private
128
+
129
+ def managing_content?
130
+ false
131
+ end
132
+
126
133
  end
127
134
  end
128
135
  end
@@ -75,7 +75,8 @@ class Chef
75
75
  @current_resource ||= Chef::Resource::File.new(@new_resource.name)
76
76
  @current_resource.path(@new_resource.path)
77
77
  if ::File.exists?(@current_resource.path) && ::File.file?(::File.realpath(@current_resource.path))
78
- if @action != :create_if_missing && @current_resource.respond_to?(:checksum)
78
+ if managing_content?
79
+ Chef::Log.debug("#{@new_resource} checksumming file at #{@new_resource.path}.")
79
80
  @current_resource.checksum(checksum(@current_resource.path))
80
81
  end
81
82
  load_resource_attributes_from_file(@current_resource)
@@ -159,6 +160,15 @@ class Chef
159
160
 
160
161
  private
161
162
 
163
+ # What to check in this resource to see if we're going to be actively managing
164
+ # content (for things like doing checksums in load_current_resource). Expected to
165
+ # be overridden in subclasses.
166
+ def managing_content?
167
+ return true if @new_resource.checksum
168
+ return true if !@new_resource.content.nil? && @action != :create_if_missing
169
+ false
170
+ end
171
+
162
172
  # Handles resource requirements for action :create when some fs entry
163
173
  # already exists at the destination path. For actions other than create,
164
174
  # we don't care what kind of thing is at the destination path because:
@@ -240,8 +250,8 @@ class Chef
240
250
 
241
251
  def content
242
252
  @content ||= begin
243
- load_current_resource if @current_resource.nil?
244
- @content_class.new(@new_resource, @current_resource, @run_context)
253
+ load_current_resource if @current_resource.nil?
254
+ @content_class.new(@new_resource, @current_resource, @run_context)
245
255
  end
246
256
  end
247
257
 
@@ -330,7 +340,9 @@ class Chef
330
340
  do_backup unless file_created?
331
341
  deployment_strategy.deploy(tempfile.path, ::File.realpath(@new_resource.path))
332
342
  Chef::Log.info("#{@new_resource} updated file contents #{@new_resource.path}")
333
- @new_resource.checksum(checksum(@new_resource.path)) # for reporting
343
+ if managing_content?
344
+ @new_resource.checksum(checksum(@new_resource.path)) # for reporting
345
+ end
334
346
  end
335
347
 
336
348
  def do_contents_changes
@@ -379,6 +391,7 @@ class Chef
379
391
  end
380
392
 
381
393
  def contents_changed?
394
+ Chef::Log.debug "calculating checksum of #{tempfile.path} to compare with #{@current_resource.checksum}"
382
395
  checksum(tempfile.path) != @current_resource.checksum
383
396
  end
384
397
 
@@ -17,6 +17,7 @@
17
17
  #
18
18
 
19
19
 
20
+ require 'chef/exceptions'
20
21
  require 'chef/log'
21
22
  require 'chef/provider'
22
23
  require 'chef/mixin/shell_out'
@@ -75,7 +76,9 @@ class Chef
75
76
  def action_checkout
76
77
  if target_dir_non_existent_or_empty?
77
78
  clone
78
- checkout
79
+ if @new_resource.enable_checkout
80
+ checkout
81
+ end
79
82
  enable_submodules
80
83
  add_remotes
81
84
  else
@@ -151,10 +154,11 @@ class Chef
151
154
 
152
155
  def checkout
153
156
  sha_ref = target_revision
157
+
154
158
  converge_by("checkout ref #{sha_ref} branch #{@new_resource.revision}") do
155
159
  # checkout into a local branch rather than a detached HEAD
156
- shell_out!("git checkout -b deploy #{sha_ref}", run_options(:cwd => @new_resource.destination))
157
- Chef::Log.info "#{@new_resource} checked out branch: #{@new_resource.revision} reference: #{sha_ref}"
160
+ shell_out!("git checkout -b #{@new_resource.checkout_branch} #{sha_ref}", run_options(:cwd => @new_resource.destination))
161
+ Chef::Log.info "#{@new_resource} checked out branch: #{@new_resource.revision} onto: #{@new_resource.checkout_branch} reference: #{sha_ref}"
158
162
  end
159
163
  end
160
164
 
@@ -269,12 +273,26 @@ class Chef
269
273
  private
270
274
 
271
275
  def run_options(run_opts={})
272
- run_opts[:user] = @new_resource.user if @new_resource.user
276
+ env = {}
277
+ if @new_resource.user
278
+ run_opts[:user] = @new_resource.user
279
+ # Certain versions of `git` misbehave if git configuration is
280
+ # inaccessible in $HOME. We need to ensure $HOME matches the
281
+ # user who is executing `git` not the user running Chef.
282
+ env['HOME'] = begin
283
+ require 'etc'
284
+ Etc.getpwnam(@new_resource.user).dir
285
+ rescue ArgumentError # user not found
286
+ raise Chef::Exceptions::User, "Could not determine HOME for specified user '#{@new_resource.user}' for resource '#{@new_resource.name}'"
287
+ end
288
+ end
273
289
  run_opts[:group] = @new_resource.group if @new_resource.group
274
- run_opts[:environment] = {"GIT_SSH" => @new_resource.ssh_wrapper} if @new_resource.ssh_wrapper
290
+ env['GIT_SSH'] = @new_resource.ssh_wrapper if @new_resource.ssh_wrapper
275
291
  run_opts[:log_tag] = @new_resource.to_s
276
292
  run_opts[:timeout] = @new_resource.timeout if @new_resource.timeout
293
+ run_opts[:environment] = env unless env.empty?
277
294
  run_opts
295
+
278
296
  end
279
297
 
280
298
  def cwd
@@ -63,6 +63,17 @@ class Chef
63
63
  a.failure_message(Chef::Exceptions::Group, "Cannot modify #{@new_resource} - group does not exist!")
64
64
  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.")
65
65
  end
66
+
67
+ requirements.assert(:all_actions) do |a|
68
+ # Make sure that the resource doesn't contain any common
69
+ # user names in the members and exclude_members properties.
70
+ if !@new_resource.members.nil? && !@new_resource.excluded_members.nil?
71
+ common_members = @new_resource.members & @new_resource.excluded_members
72
+ a.assertion { common_members.empty? }
73
+ a.failure_message(Chef::Exceptions::ConflictingMembersInGroup, "Attempting to both add and remove users from a group: '#{common_members.join(', ')}'")
74
+ # No why-run alternative
75
+ end
76
+ end
66
77
  end
67
78
 
68
79
  # Check to see if a group needs any changes. Populate
@@ -72,10 +83,9 @@ class Chef
72
83
  # <true>:: If a change is required
73
84
  # <false>:: If a change is not required
74
85
  def compare_group
75
- @change_desc = nil
86
+ @change_desc = [ ]
76
87
  if @new_resource.gid != @current_resource.gid
77
- @change_desc = "change gid #{@current_resource.gid} to #{@new_resource.gid}"
78
- return true
88
+ @change_desc << "change gid #{@current_resource.gid} to #{@new_resource.gid}"
79
89
  end
80
90
 
81
91
  if(@new_resource.append)
@@ -85,16 +95,25 @@ class Chef
85
95
  missing_members << member
86
96
  end
87
97
  if missing_members.length > 0
88
- @change_desc = "add missing member(s): #{missing_members.join(", ")}"
89
- return true
98
+ @change_desc << "add missing member(s): #{missing_members.join(", ")}"
99
+ end
100
+
101
+ members_to_be_removed = []
102
+ @new_resource.excluded_members.each do |member|
103
+ if @current_resource.members.include?(member)
104
+ members_to_be_removed << member
105
+ end
106
+ end
107
+ if members_to_be_removed.length > 0
108
+ @change_desc << "remove existing member(s): #{members_to_be_removed.join(", ")}"
90
109
  end
91
110
  else
92
111
  if @new_resource.members != @current_resource.members
93
- @change_desc = "replace group members with new list of members"
94
- return true
112
+ @change_desc << "replace group members with new list of members"
95
113
  end
96
114
  end
97
- return false
115
+
116
+ !@change_desc.empty?
98
117
  end
99
118
 
100
119
  def action_create
@@ -106,7 +125,7 @@ class Chef
106
125
  end
107
126
  else
108
127
  if compare_group
109
- converge_by(["alter group #{@new_resource}", @change_desc ]) do
128
+ converge_by(["alter group #{@new_resource}"] + change_desc) do
110
129
  manage_group
111
130
  Chef::Log.info("#{@new_resource} altered")
112
131
  end
@@ -125,7 +144,7 @@ class Chef
125
144
 
126
145
  def action_manage
127
146
  if @group_exists && compare_group
128
- converge_by(["manage group #{@new_resource}", @change_desc]) do
147
+ converge_by(["manage group #{@new_resource}"] + change_desc) do
129
148
  manage_group
130
149
  Chef::Log.info("#{@new_resource} managed")
131
150
  end
@@ -134,7 +153,7 @@ class Chef
134
153
 
135
154
  def action_modify
136
155
  if compare_group
137
- converge_by(["modify group #{@new_resource}", @change_desc]) do
156
+ converge_by(["modify group #{@new_resource}"] + change_desc) do
138
157
  manage_group
139
158
  Chef::Log.info("#{@new_resource} modified")
140
159
  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
@@ -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