chef 16.5.77 → 16.6.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/lib/chef/application/client.rb +6 -1
  4. data/lib/chef/client.rb +2 -31
  5. data/lib/chef/data_collector.rb +1 -1
  6. data/lib/chef/mixin/powershell_exec.rb +22 -10
  7. data/lib/chef/mixin/powershell_out.rb +12 -5
  8. data/lib/chef/node/mixin/immutablize_hash.rb +2 -0
  9. data/lib/chef/powershell.rb +3 -2
  10. data/lib/chef/provider/ifconfig.rb +1 -1
  11. data/lib/chef/provider/ifconfig/debian.rb +33 -15
  12. data/lib/chef/provider/ifconfig/redhat.rb +51 -17
  13. data/lib/chef/provider/powershell_script.rb +12 -1
  14. data/lib/chef/pwsh.rb +64 -0
  15. data/lib/chef/resource/apt_repository.rb +2 -3
  16. data/lib/chef/resource/chef_client_config.rb +313 -0
  17. data/lib/chef/resource/chef_client_cron.rb +5 -5
  18. data/lib/chef/resource/chef_client_scheduled_task.rb +4 -4
  19. data/lib/chef/resource/chef_client_systemd_timer.rb +5 -5
  20. data/lib/chef/resource/chef_sleep.rb +1 -1
  21. data/lib/chef/resource/cron/cron_d.rb +2 -2
  22. data/lib/chef/resource/kernel_module.rb +1 -1
  23. data/lib/chef/resource/launchd.rb +15 -15
  24. data/lib/chef/resource/mount.rb +1 -1
  25. data/lib/chef/resource/powershell_script.rb +7 -1
  26. data/lib/chef/resource/support/client.erb +65 -0
  27. data/lib/chef/resource/windows_audit_policy.rb +26 -24
  28. data/lib/chef/resources.rb +1 -0
  29. data/lib/chef/version.rb +1 -1
  30. data/spec/functional/mixin/powershell_out_spec.rb +9 -1
  31. data/spec/functional/resource/powershell_script_spec.rb +57 -14
  32. data/spec/spec_helper.rb +1 -0
  33. data/spec/support/platform_helpers.rb +6 -1
  34. data/spec/unit/mixin/powershell_exec_spec.rb +40 -3
  35. data/spec/unit/mixin/powershell_out_spec.rb +14 -0
  36. data/spec/unit/provider/powershell_script_spec.rb +11 -0
  37. data/spec/unit/resource/chef_client_config_spec.rb +137 -0
  38. data/spec/unit/resource/powershell_script_spec.rb +2 -2
  39. metadata +11 -7
@@ -131,35 +131,35 @@ class Chef
131
131
  description: "If a job dies, all remaining processes with the same process ID may be kept running. Set to true to kill all remaining processes."
132
132
 
133
133
  property :debug, [ TrueClass, FalseClass ],
134
- description: "Sets the log mask to LOG_DEBUG for this job."
134
+ description: "Sets the log mask to `LOG_DEBUG` for this job."
135
135
 
136
136
  property :disabled, [ TrueClass, FalseClass ], default: false,
137
- description: "Hints to launchctl to not submit this job to launchd."
137
+ description: "Hints to `launchctl` to not submit this job to launchd."
138
138
 
139
139
  property :enable_globbing, [ TrueClass, FalseClass ],
140
140
  description: "Update program arguments before invocation."
141
141
 
142
142
  property :enable_transactions, [ TrueClass, FalseClass ],
143
- description: "Track in-progress transactions; if none, then send the SIGKILL signal."
143
+ description: "Track in-progress transactions; if none, then send the `SIGKILL` signal."
144
144
 
145
145
  property :environment_variables, Hash,
146
146
  description: "Additional environment variables to set before running a job."
147
147
 
148
148
  property :exit_timeout, Integer,
149
- description: "The amount of time (in seconds) launchd waits before sending a SIGKILL signal."
149
+ description: "The amount of time (in seconds) launchd waits before sending a `SIGKILL` signal."
150
150
 
151
151
  property :hard_resource_limits, Hash,
152
152
  description: "A Hash of resource limits to be imposed on a job."
153
153
 
154
154
  property :inetd_compatibility, Hash,
155
- description: "Specifies if a daemon expects to be run as if it were launched from inetd. Set to wait => true to pass standard input, output, and error file descriptors. Set to wait => false to call the accept system call on behalf of the job, and then pass standard input, output, and error file descriptors."
155
+ description: "Specifies if a daemon expects to be run as if it were launched from inetd. Set to `wait => true` to pass standard input, output, and error file descriptors. Set to `wait => false` to call the accept system call on behalf of the job, and then pass standard input, output, and error file descriptors."
156
156
 
157
157
  property :init_groups, [ TrueClass, FalseClass ],
158
- description: "Specify if initgroups is called before running a job."
158
+ description: "Specify if `initgroups` is called before running a job."
159
159
 
160
160
  property :keep_alive, [ TrueClass, FalseClass, Hash ],
161
161
  introduced: "12.14",
162
- description: "Keep a job running continuously (true) or allow demand and conditions on the node to determine if the job keeps running (false)."
162
+ description: "Keep a job running continuously (true) or allow demand and conditions on the node to determine if the job keeps running (`false`)."
163
163
 
164
164
  property :launch_events, [ Hash ],
165
165
  introduced: "15.1",
@@ -191,10 +191,10 @@ class Chef
191
191
  callbacks: { "should be a Integer between -20 and 19" => proc { |v| v >= -20 && v <= 19 } }
192
192
 
193
193
  property :on_demand, [ TrueClass, FalseClass ],
194
- description: "Keep a job alive. Only applies to macOS version 10.4 (and earlier); use keep_alive instead for newer versions."
194
+ description: "Keep a job alive. Only applies to macOS version 10.4 (and earlier); use `keep_alive` instead for newer versions."
195
195
 
196
196
  property :process_type, String,
197
- description: "The intended purpose of the job: Adaptive, Background, Interactive, or Standard."
197
+ description: "The intended purpose of the job: `Adaptive`, `Background`, `Interactive`, or `Standard`."
198
198
 
199
199
  property :program, String,
200
200
  description: "The first argument of execvp, typically the file name associated with the file to be executed. This value must be specified if program_arguments is not specified, and vice-versa."
@@ -206,7 +206,7 @@ class Chef
206
206
  description: "An array of non-empty directories which, if any are modified, will cause a job to be started."
207
207
 
208
208
  property :root_directory, String,
209
- description: "chroot to this directory, and then run the job."
209
+ description: "`chroot` to this directory, and then run the job."
210
210
 
211
211
  property :run_at_load, [ TrueClass, FalseClass ],
212
212
  description: "Launch a job once (at the time it is loaded)."
@@ -218,13 +218,13 @@ class Chef
218
218
  description: "A Hash of resource limits to be imposed on a job."
219
219
 
220
220
  property :standard_error_path, String,
221
- description: "The file to which standard error (stderr) is sent."
221
+ description: "The file to which standard error (`stderr`) is sent."
222
222
 
223
223
  property :standard_in_path, String,
224
- description: "The file to which standard input (stdin) is sent."
224
+ description: "The file to which standard input (`stdin`) is sent."
225
225
 
226
226
  property :standard_out_path, String,
227
- description: "The file to which standard output (stdout) is sent."
227
+ description: "The file to which standard output (`stdout`) is sent."
228
228
 
229
229
  property :start_interval, Integer,
230
230
  description: "The frequency (in seconds) at which a job is started."
@@ -239,7 +239,7 @@ class Chef
239
239
  description: "The amount of time (in seconds) a job may be idle before it times out. If no value is specified, the default timeout value for launchd will be used."
240
240
 
241
241
  property :umask, Integer,
242
- description: "A decimal value to pass to umask before running a job."
242
+ description: "A decimal value to pass to `umask` before running a job."
243
243
 
244
244
  property :username, String,
245
245
  description: "When launchd is run as the root user, the user to run the job as."
@@ -251,7 +251,7 @@ class Chef
251
251
  description: "An array of paths which, if any are modified, will cause a job to be started."
252
252
 
253
253
  property :working_directory, String,
254
- description: "Chdir to this directory, and then run the job."
254
+ description: "`chdir` to this directory, and then run the job."
255
255
  end
256
256
  end
257
257
  end
@@ -84,7 +84,7 @@ class Chef
84
84
  description: "Windows only: Use to specify the user name."
85
85
 
86
86
  property :domain, String,
87
- description: "Windows only: Use to specify the domain in which the username and password are located."
87
+ description: "Windows only: Use to specify the domain in which the `username` and `password` are located."
88
88
 
89
89
  private
90
90
 
@@ -22,11 +22,18 @@ class Chef
22
22
  class PowershellScript < Chef::Resource::WindowsScript
23
23
  unified_mode true
24
24
 
25
+ set_guard_inherited_attributes(:interpreter)
26
+
25
27
  provides :powershell_script, os: "windows"
26
28
 
27
29
  property :flags, String,
28
30
  description: "A string that is passed to the Windows PowerShell command"
29
31
 
32
+ property :interpreter, String,
33
+ default: "powershell",
34
+ equal_to: %w{powershell pwsh},
35
+ description: "The interpreter type, `powershell` or `pwsh` (PowerShell Core)"
36
+
30
37
  property :convert_boolean_return, [true, false],
31
38
  default: false,
32
39
  description: <<~DESC
@@ -62,7 +69,6 @@ class Chef
62
69
 
63
70
  def initialize(*args)
64
71
  super
65
- @interpreter = "powershell.exe"
66
72
  @default_guard_interpreter = resource_name
67
73
  end
68
74
 
@@ -0,0 +1,65 @@
1
+ <% %w(@node_name
2
+ @chef_license
3
+ @chef_server_url
4
+ @event_loggers
5
+ @file_backup_path
6
+ @file_cache_path
7
+ @file_staging_uses_destdir
8
+ @formatters
9
+ @http_proxy
10
+ @https_proxy
11
+ @ftp_proxy
12
+ @log_level
13
+ @log_location
14
+ @minimal_ohai
15
+ @named_run_list
16
+ @no_proxy
17
+ @ohai_disabled_plugins
18
+ @ohai_optional_plugins
19
+ @pid_file
20
+ @policy_group
21
+ @policy_name
22
+ @ssl_verify_mode).each do |prop| -%>
23
+ <% next if instance_variable_get(prop).nil? || instance_variable_get(prop).empty? -%>
24
+ <%=prop.delete_prefix("@") %> = <%= instance_variable_get(prop).inspect %>
25
+ <% end -%>
26
+ <%# log_location is special due to STDOUT/STDERR from String -> IO Object -%>
27
+ <% unless @log_location.nil? %>
28
+ <% if @log_location.is_a? String && %w(STDOUT STDERR).include?(@log_location) -%>
29
+ log_location = <%= @log_location %>
30
+ <% else -%>
31
+ log_location = <%= @log_location.inspect %>
32
+ <% end -%>
33
+ <% end -%>
34
+ <%# The code below is not DRY on purpose to improve readability -%>
35
+ <% unless @start_handlers.empty? -%>
36
+ # Do not crash if a start handler is missing / not installed yet
37
+ begin
38
+ <% @start_handlers.each do |handler| -%>
39
+ start_handlers << <%= @handler %>
40
+ <% end -%>
41
+ rescue NameError => e
42
+ Chef::Log.error e
43
+ end
44
+ <% end -%>
45
+ <% unless @report_handlers.empty? -%>
46
+ # Do not crash if a report handler is missing / not installed yet
47
+ begin
48
+ <% @report_handlers.each do |handler| -%>
49
+ report_handlers << <%= @handler %>
50
+ <% end -%>
51
+ rescue NameError => e
52
+ Chef::Log.error e
53
+ end
54
+ <% end -%>
55
+ <% unless @exception_handlers.empty? -%>
56
+ # Do not crash if an exception handler is missing / not installed yet
57
+ begin
58
+ <% @exception_handlers.each do |handler| -%>
59
+ exception_handlers << <%= @handler %>
60
+ <% end -%>
61
+ rescue NameError => e
62
+ Chef::Log.error e
63
+ end
64
+ <% end -%>
65
+ <%= @additional_config -%>
@@ -152,30 +152,6 @@ class Chef
152
152
  property :audit_base_directories, [true, false],
153
153
  description: "Setting this audit policy option to true will force the system to assign a System Access Control List to named objects to enable auditing of container objects such as directories."
154
154
 
155
- def subcategory_configured?(sub_cat, success_value, failure_value)
156
- setting = if success_value && failure_value
157
- "Success and Failure$"
158
- elsif success_value && !failure_value
159
- "Success$"
160
- elsif !success_value && failure_value
161
- "(Failure$)&!(Success and Failure$)"
162
- else
163
- "No Auditing"
164
- end
165
- powershell_exec(<<-CODE).result
166
- $auditpol_config = auditpol /get /subcategory:"#{sub_cat}"
167
- if ($auditpol_config | Select-String "#{setting}") { return $true } else { return $false }
168
- CODE
169
- end
170
-
171
- def option_configured?(option_name, option_setting)
172
- setting = option_setting ? "Enabled$" : "Disabled$"
173
- powershell_exec(<<-CODE).result
174
- $auditpol_config = auditpol /get /option:#{option_name}
175
- if ($auditpol_config | Select-String "#{setting}") { return $true } else { return $false }
176
- CODE
177
- end
178
-
179
155
  action :set do
180
156
  unless new_resource.subcategory.nil?
181
157
  new_resource.subcategory.each do |subcategory|
@@ -225,6 +201,32 @@ class Chef
225
201
  end
226
202
  end
227
203
  end
204
+
205
+ action_class do
206
+ def subcategory_configured?(sub_cat, success_value, failure_value)
207
+ setting = if success_value && failure_value
208
+ "Success and Failure$"
209
+ elsif success_value && !failure_value
210
+ "Success$"
211
+ elsif !success_value && failure_value
212
+ "#{sub_cat}\\s+Failure$"
213
+ else
214
+ "No Auditing"
215
+ end
216
+ powershell_exec!(<<-CODE).result
217
+ $auditpol_config = auditpol /get /subcategory:"#{sub_cat}"
218
+ if ($auditpol_config | Select-String "#{setting}") { return $true } else { return $false }
219
+ CODE
220
+ end
221
+
222
+ def option_configured?(option_name, option_setting)
223
+ setting = option_setting ? "Enabled$" : "Disabled$"
224
+ powershell_exec!(<<-CODE).result
225
+ $auditpol_config = auditpol /get /option:#{option_name}
226
+ if ($auditpol_config | Select-String "#{setting}") { return $true } else { return $false }
227
+ CODE
228
+ end
229
+ end
228
230
  end
229
231
  end
230
232
  end
@@ -27,6 +27,7 @@ require_relative "resource/batch"
27
27
  require_relative "resource/breakpoint"
28
28
  require_relative "resource/build_essential"
29
29
  require_relative "resource/cookbook_file"
30
+ require_relative "resource/chef_client_config"
30
31
  require_relative "resource/chef_client_cron"
31
32
  require_relative "resource/chef_client_launchd"
32
33
  require_relative "resource/chef_client_scheduled_task"
@@ -23,7 +23,7 @@ require_relative "version_string"
23
23
 
24
24
  class Chef
25
25
  CHEF_ROOT = File.expand_path("..", __dir__)
26
- VERSION = Chef::VersionString.new("16.5.77")
26
+ VERSION = Chef::VersionString.new("16.6.14")
27
27
  end
28
28
 
29
29
  #
@@ -18,7 +18,7 @@
18
18
  require "spec_helper"
19
19
  require "chef/mixin/powershell_out"
20
20
 
21
- describe Chef::Mixin::PowershellOut, windows_only: true do
21
+ describe Chef::Mixin::PowershellOut, :windows_only do
22
22
  include Chef::Mixin::PowershellOut
23
23
 
24
24
  describe "#powershell_out" do
@@ -26,6 +26,14 @@ describe Chef::Mixin::PowershellOut, windows_only: true do
26
26
  expect(powershell_out("get-process").run_command.stdout).to match /Handles/
27
27
  end
28
28
 
29
+ it "uses :powershell by default" do
30
+ expect(powershell_out("$PSVersionTable").run_command.stdout).to match /CLRVersion/
31
+ end
32
+
33
+ it ":pwsh interpreter uses core edition", :pwsh_installed do
34
+ expect(powershell_out("$PSVersionTable", :pwsh).run_command.stdout).to match /Core/
35
+ end
36
+
29
37
  it "does not raise exceptions when the command is invalid" do
30
38
  powershell_out("this-is-not-a-valid-command").run_command
31
39
  end
@@ -47,7 +47,7 @@ describe Chef::Resource::WindowsScript::PowershellScript, :windows_only do
47
47
  r
48
48
  end
49
49
 
50
- describe "when the run action is invoked on Windows" do
50
+ shared_examples_for "a running powershell script" do
51
51
  it "successfully executes a non-cmdlet Windows binary as the last command of the script" do
52
52
  resource.code(successful_executable_script_content + " | out-file -encoding ASCII #{script_output_path}")
53
53
  resource.returns(0)
@@ -231,22 +231,54 @@ describe Chef::Resource::WindowsScript::PowershellScript, :windows_only do
231
231
  resource.only_if { true }
232
232
  expect { resource.should_skip?(:run) }.to raise_error(ArgumentError, /guard_interpreter does not support blocks/)
233
233
  end
234
+ end
235
+
236
+ context "when using the powershell interpreter" do
237
+ before do
238
+ resource.interpreter "powershell"
239
+ end
240
+
241
+ it_behaves_like "a running powershell script"
242
+
243
+ it "runs Windows Powershell" do
244
+ resource.code("$PSVersionTable.PSVersion.Major | out-file -encoding ASCII #{script_output_path}")
245
+ resource.returns(0)
246
+ resource.run_action(:run)
247
+
248
+ expect(get_script_output.to_i).to be < 6
249
+ end
250
+ end
251
+
252
+ context "when using the pwsh interpreter", :pwsh_installed do
253
+ before do
254
+ resource.interpreter "pwsh"
255
+ end
256
+
257
+ it_behaves_like "a running powershell script"
234
258
 
235
- context "when dsc is supported", :windows_powershell_dsc_only do
236
- it "can execute LCM configuration code" do
237
- resource.code <<~EOF
238
- configuration LCM
259
+ it "runs a version of powershell greater than 6" do
260
+ resource.code("$PSVersionTable.PSVersion.Major | out-file -encoding ASCII #{script_output_path}")
261
+ resource.returns(0)
262
+ resource.run_action(:run)
263
+
264
+ expect(get_script_output.to_i).to be > 6
265
+ end
266
+ end
267
+
268
+ context "when dsc is supported", :windows_powershell_dsc_only do
269
+ it "can execute LCM configuration code" do
270
+ resource.code <<~EOF
271
+ configuration LCM
272
+ {
273
+ param ($thumbprint)
274
+ localconfigurationmanager
239
275
  {
240
- param ($thumbprint)
241
- localconfigurationmanager
242
- {
243
- RebootNodeIfNeeded = $false
244
- ConfigurationMode = 'ApplyOnly'
245
- }
276
+ RebootNodeIfNeeded = $false
277
+ ConfigurationMode = 'ApplyOnly'
246
278
  }
247
- EOF
248
- expect { resource.run_action(:run) }.not_to raise_error
249
- end
279
+ }
280
+ EOF
281
+ expect { resource.run_action(:run) }.not_to raise_error
250
282
  end
251
283
  end
252
284
 
@@ -347,6 +379,17 @@ describe Chef::Resource::WindowsScript::PowershellScript, :windows_only do
347
379
 
348
380
  context "with powershell_script as the guard_interpreter" do
349
381
 
382
+ context "when pwsh is the interpreter", :pwsh_installed do
383
+ before do
384
+ resource.interpreter "pwsh"
385
+ end
386
+
387
+ it "uses powershell core to evaluate the guard" do
388
+ resource.not_if "$PSVersionTable.PSEdition -eq 'Core'"
389
+ expect(resource.should_skip?(:run)).to be_truthy
390
+ end
391
+ end
392
+
350
393
  it "has a guard_interpreter attribute set to :powershell_script" do
351
394
  expect(resource.guard_interpreter).to eq(:powershell_script)
352
395
  end
@@ -200,6 +200,7 @@ RSpec.configure do |config|
200
200
  # check for particular binaries we need
201
201
  config.filter_run_excluding choco_installed: true unless choco_installed?
202
202
  config.filter_run_excluding requires_ifconfig: true unless ifconfig?
203
+ config.filter_run_excluding pwsh_installed: true unless pwsh_installed?
203
204
 
204
205
  running_platform_arch = `uname -m`.strip unless windows?
205
206
 
@@ -243,5 +243,10 @@ end
243
243
 
244
244
  def choco_installed?
245
245
  result = ShellHelpers.powershell_out("choco --version")
246
- result.stderr.empty? ? true : false
246
+ result.stderr.empty?
247
+ end
248
+
249
+ def pwsh_installed?
250
+ result = ShellHelpers.powershell_out("pwsh.exe --version")
251
+ result.stderr.empty?
247
252
  end
@@ -19,13 +19,42 @@
19
19
  require "spec_helper"
20
20
  require "chef/mixin/powershell_exec"
21
21
 
22
- describe Chef::Mixin::PowershellExec, :windows_only, :windows_gte_10 do
22
+ describe Chef::Mixin::PowershellExec, :windows_only do
23
23
  let(:powershell_mixin) { Class.new { include Chef::Mixin::PowershellExec } }
24
24
  subject(:object) { powershell_mixin.new }
25
25
 
26
26
  describe "#powershell_exec" do
27
- it "runs a basic command and returns a Chef::PowerShell object" do
28
- expect(object.powershell_exec("$PSVersionTable")).to be_kind_of(Chef::PowerShell)
27
+ context "not specifying an interpreter" do
28
+ it "runs a basic command and returns a Chef::PowerShell object" do
29
+ expect(object.powershell_exec("$PSVersionTable")).to be_kind_of(Chef::PowerShell)
30
+ end
31
+
32
+ it "uses less than version 6" do
33
+ execution = object.powershell_exec("$PSVersionTable")
34
+ expect(execution.result["PSVersion"].to_s.to_i).to be < 6
35
+ end
36
+ end
37
+
38
+ context "using pwsh interpreter" do
39
+ it "runs a basic command and returns a Chef::PowerShell object" do
40
+ expect(object.powershell_exec("$PSVersionTable", :pwsh)).to be_kind_of(Chef::Pwsh)
41
+ end
42
+
43
+ it "uses greater than version 6" do
44
+ execution = object.powershell_exec("$PSVersionTable", :pwsh)
45
+ expect(execution.result["PSVersion"]["Major"]).to be > 6
46
+ end
47
+ end
48
+
49
+ context "using powershell interpreter" do
50
+ it "runs a basic command and returns a Chef::PowerShell object" do
51
+ expect(object.powershell_exec("$PSVersionTable", :powershell)).to be_kind_of(Chef::PowerShell)
52
+ end
53
+
54
+ it "uses less than version 6" do
55
+ execution = object.powershell_exec("$PSVersionTable", :powershell)
56
+ expect(execution.result["PSVersion"].to_s.to_i).to be < 6
57
+ end
29
58
  end
30
59
 
31
60
  it "runs a command that fails with a non-terminating error and can trap the error via .error?" do
@@ -39,6 +68,10 @@ describe Chef::Mixin::PowershellExec, :windows_only, :windows_gte_10 do
39
68
  expect(execution.errors[0]).to be_a_kind_of(String)
40
69
  expect(execution.errors[0]).to include("Runtime exception: this-should-error")
41
70
  end
71
+
72
+ it "raises an error if the interpreter is invalid" do
73
+ expect { object.powershell_exec("this-should-error", :powerfart) }.to raise_error(ArgumentError)
74
+ end
42
75
  end
43
76
 
44
77
  describe "#powershell_exec!" do
@@ -49,5 +82,9 @@ describe Chef::Mixin::PowershellExec, :windows_only, :windows_gte_10 do
49
82
  it "raises an error if the command fails" do
50
83
  expect { object.powershell_exec!("this-should-error") }.to raise_error(Chef::PowerShell::CommandFailed)
51
84
  end
85
+
86
+ it "raises an error if the interpreter is invalid" do
87
+ expect { object.powershell_exec!("this-should-error", :powerfart) }.to raise_error(ArgumentError)
88
+ end
52
89
  end
53
90
  end