chef 17.7.29 → 17.8.25

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/lib/chef/application/base.rb +1 -1
  3. data/lib/chef/compliance/default_attributes.rb +12 -2
  4. data/lib/chef/compliance/runner.rb +51 -5
  5. data/lib/chef/mixin/powershell_exec.rb +6 -5
  6. data/lib/chef/mixin/why_run.rb +8 -2
  7. data/lib/chef/powershell.rb +8 -6
  8. data/lib/chef/provider/mount/linux.rb +16 -2
  9. data/lib/chef/provider/mount/mount.rb +1 -1
  10. data/lib/chef/provider/package/dnf.rb +1 -1
  11. data/lib/chef/provider/package/powershell.rb +13 -10
  12. data/lib/chef/provider/package/zypper.rb +2 -0
  13. data/lib/chef/provider/package.rb +58 -23
  14. data/lib/chef/provider.rb +1 -1
  15. data/lib/chef/pwsh.rb +3 -2
  16. data/lib/chef/resource/chef_client_config.rb +22 -1
  17. data/lib/chef/resource/chef_client_launchd.rb +1 -1
  18. data/lib/chef/resource/dnf_package.rb +4 -6
  19. data/lib/chef/resource/dpkg_package.rb +5 -0
  20. data/lib/chef/resource/execute.rb +1 -4
  21. data/lib/chef/resource/launchd.rb +0 -3
  22. data/lib/chef/resource/macos_userdefaults.rb +5 -7
  23. data/lib/chef/resource/rhsm_register.rb +31 -0
  24. data/lib/chef/resource/support/client.erb +7 -0
  25. data/lib/chef/resource/windows_feature_powershell.rb +7 -7
  26. data/lib/chef/resource.rb +1 -1
  27. data/lib/chef/version.rb +1 -1
  28. data/spec/functional/resource/dnf_package_spec.rb +34 -20
  29. data/spec/functional/resource/dpkg_package_spec.rb +16 -0
  30. data/spec/functional/resource/macos_userdefaults_spec.rb +20 -0
  31. data/spec/functional/resource/zypper_package_spec.rb +7 -0
  32. data/spec/integration/client/client_spec.rb +31 -0
  33. data/spec/unit/application/base_spec.rb +40 -0
  34. data/spec/unit/compliance/runner_spec.rb +62 -1
  35. data/spec/unit/file_access_control_spec.rb +1 -1
  36. data/spec/unit/mixin/why_run_spec.rb +53 -0
  37. data/spec/unit/provider/group/groupadd_spec.rb +1 -0
  38. data/spec/unit/provider/group/usermod_spec.rb +2 -2
  39. data/spec/unit/provider/ifconfig_spec.rb +2 -0
  40. data/spec/unit/provider/mount/linux_spec.rb +16 -3
  41. data/spec/unit/provider/package/bff_spec.rb +1 -0
  42. data/spec/unit/provider/package/powershell_spec.rb +114 -114
  43. data/spec/unit/provider/package/rubygems_spec.rb +3 -0
  44. data/spec/unit/provider/package/solaris_spec.rb +1 -0
  45. data/spec/unit/provider/service/arch_service_spec.rb +2 -2
  46. data/spec/unit/provider/service/debian_service_spec.rb +1 -0
  47. data/spec/unit/provider/service/gentoo_service_spec.rb +1 -0
  48. data/spec/unit/provider/service/macosx_spec.rb +1 -0
  49. data/spec/unit/provider/service/redhat_spec.rb +4 -1
  50. data/spec/unit/provider/service/simple_service_spec.rb +6 -4
  51. data/spec/unit/provider/user_spec.rb +2 -0
  52. data/spec/unit/resource/dpkg_package_spec.rb +12 -0
  53. data/spec/unit/resource/rhsm_register_spec.rb +42 -0
  54. metadata +9 -7
@@ -346,7 +346,7 @@ class Chef
346
346
 
347
347
  By default, notifications are `:delayed`, that is they are queued up as they are
348
348
  triggered, and then executed at the very end of a Chef Infra Client run. To run
349
- kan action immediately, use `:immediately`:
349
+ an action immediately, use `:immediately`:
350
350
 
351
351
  ```ruby
352
352
  template '/etc/nagios3/configures-nagios.conf' do
@@ -517,9 +517,6 @@ class Chef
517
517
  name_property: true,
518
518
  description: "An optional property to set the command to be executed if it differs from the resource block's name. Note: Use the **execute** resource to run a single command. Use multiple **execute** resource blocks to run multiple commands."
519
519
 
520
- property :umask, [ String, Integer ],
521
- description: "The file mode creation mask, or umask."
522
-
523
520
  property :creates, String,
524
521
  description: "Prevent a command from creating a file when that file already exists."
525
522
 
@@ -238,9 +238,6 @@ class Chef
238
238
  property :time_out, Integer,
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
- property :umask, Integer,
242
- description: "A decimal value to pass to `umask` before running a job."
243
-
244
241
  property :username, String,
245
242
  description: "When launchd is run as the root user, the user to run the job as."
246
243
 
@@ -81,8 +81,7 @@ class Chef
81
81
  property :host, [String, Symbol],
82
82
  description: "Set either :current, :all or a hostname to set the user default at the host level.",
83
83
  desired_state: false,
84
- introduced: "16.3",
85
- coerce: proc { |value| to_cf_host(value) }
84
+ introduced: "16.3"
86
85
 
87
86
  property :value, [Integer, Float, String, TrueClass, FalseClass, Hash, Array],
88
87
  description: "The value of the key. Note: With the `type` property set to `bool`, `String` forms of Boolean true/false values that Apple accepts in the defaults command will be coerced: 0/1, 'TRUE'/'FALSE,' 'true'/false', 'YES'/'NO', or 'yes'/'no'.",
@@ -96,8 +95,7 @@ class Chef
96
95
 
97
96
  property :user, [String, Symbol],
98
97
  description: "The system user that the default will be applied to. Set :current for current user, :all for all users or pass a valid username",
99
- desired_state: false,
100
- coerce: proc { |value| to_cf_user(value) }
98
+ desired_state: false
101
99
 
102
100
  property :sudo, [TrueClass, FalseClass],
103
101
  description: "Set to true if the setting you wish to modify requires privileged access. This requires passwordless sudo for the `/usr/bin/defaults` command to be setup for the user running #{ChefUtils::Dist::Infra::PRODUCT}.",
@@ -118,7 +116,7 @@ class Chef
118
116
  action :write, description: "Write the value to the specified domain/key." do
119
117
  converge_if_changed do
120
118
  Chef::Log.debug("Updating defaults value for #{new_resource.key} in #{new_resource.domain}")
121
- CF::Preferences.set!(new_resource.key, new_resource.value, new_resource.domain, new_resource.user, new_resource.host)
119
+ CF::Preferences.set!(new_resource.key, new_resource.value, new_resource.domain, to_cf_user(new_resource.user), to_cf_host(new_resource.host))
122
120
  end
123
121
  end
124
122
 
@@ -128,12 +126,12 @@ class Chef
128
126
 
129
127
  converge_by("delete domain:#{new_resource.domain} key:#{new_resource.key}") do
130
128
  Chef::Log.debug("Removing defaults key: #{new_resource.key}")
131
- CF::Preferences.set!(new_resource.key, nil, new_resource.domain, new_resource.user, new_resource.host)
129
+ CF::Preferences.set!(new_resource.key, nil, new_resource.domain, to_cf_user(new_resource.user), to_cf_host(new_resource.host))
132
130
  end
133
131
  end
134
132
 
135
133
  def get_preference(new_resource)
136
- CF::Preferences.get(new_resource.key, new_resource.domain, new_resource.user, new_resource.host)
134
+ CF::Preferences.get(new_resource.key, new_resource.domain, to_cf_user(new_resource.user), to_cf_host(new_resource.host))
137
135
  end
138
136
 
139
137
  # Return valid hostname based on the input from host property
@@ -79,6 +79,23 @@ class Chef
79
79
  default: false, desired_state: false,
80
80
  introduced: "15.9"
81
81
 
82
+ property :server_url, String,
83
+ description: "The hostname of the subscription service to use. The default is for Customer Portal Subscription Management, subscription.rhn.redhat.com. If this option is not used, the system is registered with Customer Portal Subscription Management.",
84
+ introduced: "17.8"
85
+
86
+ property :base_url, String,
87
+ description: "The hostname of the content delivery server to use to receive updates. Both Customer Portal Subscription Management and Subscription Asset Manager use Red Hat's hosted content delivery services, with the URL https://cdn.redhat.com. Since Satellite 6 hosts its own content, the URL must be used for systems registered with Satellite 6.",
88
+ introduced: "17.8"
89
+
90
+ property :service_level, String,
91
+ description: "Sets the service level to use for subscriptions on the registering machine. This is only used with the auto_attach option.",
92
+ introduced: "17.8"
93
+
94
+ property :release,
95
+ [Float, String],
96
+ description: "Sets the operating system minor release to use for subscriptions for the system. Products and updates are limited to the specified minor release version. This is used only used with the auto_attach option. For example, `release '6.4'` will append `--release=6.4` to the register command.",
97
+ introduced: "17.8"
98
+
82
99
  action :register, description: "Register the node with RHSM." do
83
100
  package "subscription-manager"
84
101
 
@@ -170,6 +187,8 @@ class Chef
170
187
  command << new_resource.activation_key.map { |key| "--activationkey=#{Shellwords.shellescape(key)}" }
171
188
  command << "--org=#{Shellwords.shellescape(new_resource.organization)}"
172
189
  command << "--name=#{Shellwords.shellescape(new_resource.system_name)}" if new_resource.system_name
190
+ command << "--serverurl=#{Shellwords.shellescape(new_resource.server_url)}" if new_resource.server_url
191
+ command << "--baseurl=#{Shellwords.shellescape(new_resource.base_url)}" if new_resource.base_url
173
192
  command << "--force" if new_resource.force
174
193
 
175
194
  return command.join(" ")
@@ -179,11 +198,23 @@ class Chef
179
198
  if new_resource.username && new_resource.password
180
199
  raise "Unable to register - you must specify environment when using username/password" if new_resource.environment.nil? && using_satellite_host?
181
200
 
201
+ if new_resource.service_level
202
+ raise "Unable to register - 'auto_attach' must be enabled when using property `service_level`." unless new_resource.auto_attach
203
+ end
204
+
205
+ if new_resource.release
206
+ raise "Unable to register - `auto_attach` must be enabled when using property `release`." unless new_resource.auto_attach
207
+ end
208
+
182
209
  command << "--username=#{Shellwords.shellescape(new_resource.username)}"
183
210
  command << "--password=#{Shellwords.shellescape(new_resource.password)}"
184
211
  command << "--environment=#{Shellwords.shellescape(new_resource.environment)}" if using_satellite_host?
185
212
  command << "--name=#{Shellwords.shellescape(new_resource.system_name)}" if new_resource.system_name
213
+ command << "--serverurl=#{Shellwords.shellescape(new_resource.server_url)}" if new_resource.server_url
214
+ command << "--baseurl=#{Shellwords.shellescape(new_resource.base_url)}" if new_resource.base_url
186
215
  command << "--auto-attach" if new_resource.auto_attach
216
+ command << "--servicelevel=#{Shellwords.shellescape(new_resource.service_level)}" if new_resource.service_level
217
+ command << "--release=#{Shellwords.shellescape(new_resource.release)}" if new_resource.release
187
218
  command << "--force" if new_resource.force
188
219
 
189
220
  return command.join(" ")
@@ -37,6 +37,13 @@ log_location <%= @log_location %>
37
37
  log_location <%= @log_location.inspect %>
38
38
  <% end -%>
39
39
  <% end -%>
40
+ <%# These data_collector options are special as they have a '.' -%>
41
+ <% unless @data_collector_server_url.nil? || @data_collector_server_url.empty? %>
42
+ data_collector.server_url <%= @data_collector_server_url %>
43
+ <% end %>
44
+ <% unless @data_collector_token.nil? || @data_collector_token.empty? %>
45
+ data_collector.token <%= @data_collector_token %>
46
+ <% end %>
40
47
  <%# The code below is not DRY on purpose to improve readability -%>
41
48
  <% unless @start_handlers.empty? -%>
42
49
  # Do not crash if a start handler is missing / not installed yet
@@ -100,8 +100,8 @@ class Chef
100
100
  install_command << " -Source \"#{new_resource.source}\"" if new_resource.source
101
101
  install_command << " -IncludeManagementTools" if new_resource.management_tools
102
102
 
103
- cmd = powershell_out!(install_command, timeout: new_resource.timeout)
104
- Chef::Log.info(cmd.stdout)
103
+ cmd = powershell_exec!(install_command, timeout: new_resource.timeout)
104
+ Chef::Log.info(cmd.result)
105
105
 
106
106
  reload_cached_powershell_data # Reload cached powershell feature state
107
107
  end
@@ -115,8 +115,8 @@ class Chef
115
115
 
116
116
  unless features_to_remove.empty?
117
117
  converge_by("remove Windows feature#{"s" if features_to_remove.count > 1} #{features_to_remove.join(",")}") do
118
- cmd = powershell_out!("Uninstall-WindowsFeature #{features_to_remove.join(",")}", timeout: new_resource.timeout)
119
- Chef::Log.info(cmd.stdout)
118
+ cmd = powershell_exec!("Uninstall-WindowsFeature #{features_to_remove.join(",")}", timeout: new_resource.timeout)
119
+ Chef::Log.info(cmd.result)
120
120
 
121
121
  reload_cached_powershell_data # Reload cached powershell feature state
122
122
  end
@@ -132,8 +132,8 @@ class Chef
132
132
 
133
133
  unless features_to_delete.empty?
134
134
  converge_by("delete Windows feature#{"s" if features_to_delete.count > 1} #{features_to_delete.join(",")} from the image") do
135
- cmd = powershell_out!("Uninstall-WindowsFeature #{features_to_delete.join(",")} -Remove", timeout: new_resource.timeout)
136
- Chef::Log.info(cmd.stdout)
135
+ cmd = powershell_exec!("Uninstall-WindowsFeature #{features_to_delete.join(",")} -Remove", timeout: new_resource.timeout)
136
+ Chef::Log.info(cmd.result)
137
137
 
138
138
  reload_cached_powershell_data # Reload cached powershell feature state
139
139
  end
@@ -215,7 +215,7 @@ class Chef
215
215
  # fetch the list of available feature names and state in JSON and parse the JSON
216
216
  def parsed_feature_list
217
217
  # Grab raw feature information from WindowsFeature
218
- raw_list_of_features = powershell_out!("Get-WindowsFeature | Select-Object -Property Name,InstallState | ConvertTo-Json -Compress", timeout: new_resource.timeout).stdout
218
+ raw_list_of_features = powershell_exec!("Get-WindowsFeature | Select-Object -Property Name,InstallState", timeout: new_resource.timeout).result
219
219
 
220
220
  Chef::JSONCompat.from_json(raw_list_of_features)
221
221
  end
data/lib/chef/resource.rb CHANGED
@@ -454,7 +454,7 @@ class Chef
454
454
  # @param arg [String] The umask to apply while converging the resource.
455
455
  # @return [Boolean] The umask to apply while converging the resource.
456
456
  #
457
- property :umask, String,
457
+ property :umask, [String, Integer],
458
458
  desired_state: false,
459
459
  introduced: "16.2",
460
460
  description: "Set a umask to be used for the duration of converging the resource. Defaults to `nil`, which means to use the system umask. Unsupported on Windows because Windows lacks a direct equivalent to UNIX's umask."
data/lib/chef/version.rb CHANGED
@@ -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("17.7.29")
26
+ VERSION = Chef::VersionString.new("17.8.25")
27
27
  end
28
28
 
29
29
  #
@@ -455,7 +455,7 @@ describe Chef::Resource::DnfPackage, :requires_root, external: exclude_test do
455
455
  end
456
456
 
457
457
  context "downgrades" do
458
- it "downgrades the package when allow_downgrade" do
458
+ it "downgrades the package when allow_downgrade is true" do
459
459
  flush_cache
460
460
  preinstall("chef_rpm-1.10-1.#{pkg_arch}.rpm")
461
461
  dnf_package "chef_rpm" do
@@ -470,6 +470,18 @@ describe Chef::Resource::DnfPackage, :requires_root, external: exclude_test do
470
470
  action :install
471
471
  end.should_not_be_updated
472
472
  end
473
+
474
+ it "does not downgrade the package when allow_downgrade is false" do
475
+ flush_cache
476
+ preinstall("chef_rpm-1.10-1.#{pkg_arch}.rpm")
477
+ dnf_package "chef_rpm" do
478
+ options default_options
479
+ allow_downgrade false
480
+ version "1.2-1"
481
+ action :install
482
+ end.should_not_be_updated
483
+ expect(shell_out("rpm -q --queryformat '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' chef_rpm").stdout.chomp).to match("^chef_rpm-1.10-1.#{pkg_arch}$")
484
+ end
473
485
  end
474
486
 
475
487
  context "with arches", :intel_64bit do
@@ -763,6 +775,17 @@ describe Chef::Resource::DnfPackage, :requires_root, external: exclude_test do
763
775
  end.should_not_be_updated
764
776
  end
765
777
 
778
+ it "downgrade on a local file with allow_downgrade false does not downgrade" do
779
+ preinstall("chef_rpm-1.10-1.#{pkg_arch}.rpm")
780
+ dnf_package "#{CHEF_SPEC_ASSETS}/yumrepo/chef_rpm-1.2-1.#{pkg_arch}.rpm" do
781
+ options default_options
782
+ allow_downgrade false
783
+ version "1.2-1"
784
+ action :install
785
+ end.should_not_be_updated
786
+ expect(shell_out("rpm -q --queryformat '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' chef_rpm").stdout.chomp).to match("^chef_rpm-1.10-1.#{pkg_arch}$")
787
+ end
788
+
766
789
  it "does not downgrade the package with :install" do
767
790
  preinstall("chef_rpm-1.10-1.#{pkg_arch}.rpm")
768
791
  dnf_package "#{CHEF_SPEC_ASSETS}/yumrepo/chef_rpm-1.2-1.#{pkg_arch}.rpm" do
@@ -1027,25 +1050,6 @@ describe Chef::Resource::DnfPackage, :requires_root, external: exclude_test do
1027
1050
  action :install
1028
1051
  end.should_not_be_updated
1029
1052
  end
1030
-
1031
- it "throws a deprecation warning with allow_downgrade" do
1032
- Chef::Config[:treat_deprecation_warnings_as_errors] = false
1033
- expect(Chef).to receive(:deprecated).at_least(:once).with(:dnf_package_allow_downgrade, /^the allow_downgrade property on the dnf_package provider is not used/)
1034
- preinstall("chef_rpm-1.10-1.#{pkg_arch}.rpm")
1035
- dnf_package "chef_rpm" do
1036
- options default_options
1037
- version "1.2"
1038
- allow_downgrade true
1039
- action :install
1040
- end.should_be_updated
1041
- expect(shell_out("rpm -q chef_rpm").stdout.chomp).to match("^chef_rpm-1.2-1.#{pkg_arch}")
1042
- dnf_package "chef_rpm" do
1043
- options default_options
1044
- version "1.2"
1045
- allow_downgrade true
1046
- action :install
1047
- end.should_not_be_updated
1048
- end
1049
1053
  end
1050
1054
 
1051
1055
  context "with source arguments" do
@@ -1092,6 +1096,16 @@ describe Chef::Resource::DnfPackage, :requires_root, external: exclude_test do
1092
1096
  end.should_not_be_updated
1093
1097
  end
1094
1098
 
1099
+ it "does not downgrade the package when allow_downgrade is false" do
1100
+ preinstall("chef_rpm-1.10-1.#{pkg_arch}.rpm")
1101
+ dnf_package "#{CHEF_SPEC_ASSETS}/yumrepo/chef_rpm-1.2-1.#{pkg_arch}.rpm" do
1102
+ options default_options
1103
+ allow_downgrade false
1104
+ action :upgrade
1105
+ end.should_not_be_updated
1106
+ expect(shell_out("rpm -q --queryformat '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' chef_rpm").stdout.chomp).to match("^chef_rpm-1.10-1.#{pkg_arch}$")
1107
+ end
1108
+
1095
1109
  it "upgrades the package" do
1096
1110
  preinstall("chef_rpm-1.2-1.#{pkg_arch}.rpm")
1097
1111
  dnf_package "#{CHEF_SPEC_ASSETS}/yumrepo/chef_rpm-1.10-1.#{pkg_arch}.rpm" do
@@ -184,6 +184,22 @@ describe Chef::Resource::DpkgPackage, :requires_root, :debian_family_only, arch:
184
184
  dpkg_package.run_action(action)
185
185
  expect(dpkg_package).to be_updated_by_last_action
186
186
  end
187
+
188
+ it "should not allow downgrade a package" do
189
+ dpkg_package.allow_downgrade false
190
+ shell_out!("dpkg -i #{test1_1}")
191
+ set_dpkg_package_name test1_0
192
+ dpkg_package.run_action(action)
193
+ expect(dpkg_package).not_to be_updated_by_last_action
194
+ end
195
+
196
+ it "should allow downgrade a package" do
197
+ dpkg_package.allow_downgrade true
198
+ shell_out!("dpkg -i #{test1_1}")
199
+ set_dpkg_package_name test1_0
200
+ dpkg_package.run_action(action)
201
+ expect(dpkg_package).to be_updated_by_last_action
202
+ end
187
203
  end
188
204
 
189
205
  shared_examples_for "common behavior for remove or purge" do
@@ -116,4 +116,24 @@ describe Chef::Resource::MacosUserDefaults, :macos_only do
116
116
  resource.key "titlesize"
117
117
  expect { resource.run_action(:delete) }. to_not raise_error
118
118
  end
119
+
120
+ context "resource can process FFI::Pointer type" do
121
+ it "for host property" do
122
+ resource.domain "/Library/Preferences/ManagedInstalls"
123
+ resource.key "TestDictionaryValues"
124
+ resource.value "User": "/Library/Managed Installs/way_fake.log"
125
+ resource.host :current
126
+ resource.run_action(:write)
127
+ expect { resource.run_action(:write) }. to_not raise_error
128
+ end
129
+
130
+ it "for user property" do
131
+ resource.domain "/Library/Preferences/ManagedInstalls"
132
+ resource.key "TestDictionaryValues"
133
+ resource.value "User": "/Library/Managed Installs/way_fake.log"
134
+ resource.user :current
135
+ resource.run_action(:write)
136
+ expect { resource.run_action(:write) }. to_not raise_error
137
+ end
138
+ end
119
139
  end
@@ -187,6 +187,13 @@ describe Chef::Resource::ZypperPackage, :requires_root, :suse_only do
187
187
  expect(zypper_package.updated_by_last_action?).to be true
188
188
  expect(shell_out("rpm -q --queryformat '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' chef_rpm").stdout.chomp).to match("^package chef_rpm is not installed$")
189
189
  end
190
+
191
+ it "is idempotent when a package isn't installed" do
192
+ FileUtils.rm_f "/etc/zypp/repos.d/chef-zypp-localtesting.repo"
193
+ zypper_package.run_action(:remove)
194
+ expect(zypper_package.updated_by_last_action?).to be false
195
+ expect(shell_out("rpm -q --queryformat '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' chef_rpm").stdout.chomp).to match("^package chef_rpm is not installed$")
196
+ end
190
197
  end
191
198
  end
192
199
 
@@ -48,6 +48,37 @@ describe "chef-client" do
48
48
  let(:chef_client) { "bundle exec #{ChefUtils::Dist::Infra::CLIENT} --minimal-ohai" }
49
49
  let(:chef_solo) { "bundle exec #{ChefUtils::Dist::Solo::EXEC} --legacy-mode --minimal-ohai" }
50
50
 
51
+ context "when validation.pem in current Directory" do
52
+ let(:validation_path) { "" }
53
+
54
+ before do
55
+ tempfile = Tempfile.new(validation_path)
56
+ tempfile.write "string"
57
+ tempfile.close
58
+ @path = tempfile.path
59
+ Chef::Config.validation_key = @path
60
+
61
+ file "config/client.rb", <<~EOM
62
+ local_mode true
63
+ cookbook_path "#{path_to("cookbooks")}"
64
+ EOM
65
+ end
66
+
67
+ it "should find validation.pem successfully in current dir" do
68
+ validation_path = "validation.pem"
69
+ shell_out!("#{chef_client} -c \"#{path_to("config/client.rb")}\" -K #{@path} ", cwd: chef_dir)
70
+ end
71
+
72
+ it "should find validation.pem successfully in current dir" do
73
+ validation_path = "/tmp/validation.pem"
74
+ shell_out!("#{chef_client} -c \"#{path_to("config/client.rb")}\" -K #{@path} ", cwd: chef_dir)
75
+ end
76
+
77
+ it "should find validation.pem successfully in default directory" do
78
+ shell_out!("#{chef_client} -c \"#{path_to("config/client.rb")}\" ", cwd: chef_dir)
79
+ end
80
+ end
81
+
51
82
  when_the_repository "has a cookbook with a no-op recipe" do
52
83
  before { file "cookbooks/x/recipes/default.rb", "" }
53
84
 
@@ -0,0 +1,40 @@
1
+ require "spec_helper"
2
+
3
+ describe Chef::Application::Base, "setup_application" do
4
+ let(:validation_path) { "" }
5
+
6
+ context "when validation key is supplied" do
7
+ before do
8
+ @app = Chef::Application::Base.new
9
+ tempfile = Tempfile.new(validation_path)
10
+ tempfile.write "string"
11
+ tempfile.close
12
+ @path = tempfile.path
13
+ Chef::Config.validation_key = @path
14
+ end
15
+
16
+ context "when key is in current directory" do
17
+ it "should find with full path of validation_key" do
18
+ validation_path = "validation.pem"
19
+ expect(Chef::Config.validation_key).to eql(@path)
20
+ end
21
+ end
22
+
23
+ context "when path is given" do
24
+ validation_path = "/tmp/validation.pem"
25
+ it "should find validation_key" do
26
+ expect(Chef::Config.validation_key).to eql(@path)
27
+ end
28
+ end
29
+ end
30
+
31
+ context "when validation key is not supplied" do
32
+ it "should return default path for validation_key" do
33
+ if windows?
34
+ expect(Chef::Config.validation_key).to eql("C:\\chef\\validation.pem")
35
+ else
36
+ expect(Chef::Config.validation_key).to eql("/etc/chef/validation.pem")
37
+ end
38
+ end
39
+ end
40
+ end
@@ -1,4 +1,5 @@
1
1
  require "spec_helper"
2
+ require "tmpdir"
2
3
 
3
4
  describe Chef::Compliance::Runner do
4
5
  let(:logger) { double(:logger).as_null_object }
@@ -216,6 +217,7 @@ describe Chef::Compliance::Runner do
216
217
  node.normal["audit"]["reporter"] = [ "chef-automate" ]
217
218
  reporter_double = double("reporter", validate_config!: nil)
218
219
  expect(runner).to receive(:reporter).with("chef-automate").and_return(reporter_double)
220
+ expect(runner).to receive(:reporter).with("cli").and_return(reporter_double)
219
221
  runner.load_and_validate!
220
222
  end
221
223
 
@@ -278,8 +280,67 @@ describe Chef::Compliance::Runner do
278
280
  inputs = runner.inspec_opts[:inputs]
279
281
 
280
282
  expect(inputs["tacos"]).to eq("lunch")
281
- expect(inputs["chef_node"]["audit"]["reporter"]).to eq("cli")
283
+ expect(inputs["chef_node"]["audit"]["reporter"]).to eq(nil)
282
284
  expect(inputs["chef_node"]["chef_environment"]).to eq("_default")
283
285
  end
284
286
  end
287
+
288
+ describe "interval running" do
289
+ let(:tempdir) { Dir.mktmpdir("chef-compliance-tests") }
290
+
291
+ before do
292
+ allow(runner).to receive(:report_timing_file).and_return("#{tempdir}/report_timing.json")
293
+ end
294
+
295
+ it "is disabled by default" do
296
+ expect(runner.node["audit"]["interval"]["enabled"]).to be false
297
+ end
298
+
299
+ it "defaults to 24 hours / 1440 minutes" do
300
+ expect(runner.node["audit"]["interval"]["time"]).to be 1440
301
+ end
302
+
303
+ it "runs when the timing file does not exist" do
304
+ expect(runner).to receive(:report)
305
+ runner.report_with_interval
306
+ end
307
+
308
+ it "runs when the timing file does not exist and intervals are enabled" do
309
+ node.normal["audit"]["interval"]["enabled"] = true
310
+ expect(runner).to receive(:report)
311
+ runner.report_with_interval
312
+ end
313
+
314
+ it "runs when the timing file exists and has a recent timestamp" do
315
+ FileUtils.touch runner.report_timing_file
316
+ expect(runner).to receive(:report)
317
+ runner.report_with_interval
318
+ end
319
+
320
+ it "does not runs when the timing file exists and has a recent timestamp and intervals are enabled" do
321
+ node.normal["audit"]["interval"]["enabled"] = true
322
+ FileUtils.touch runner.report_timing_file
323
+ expect(runner).not_to receive(:report)
324
+ runner.report_with_interval
325
+ end
326
+
327
+ it "does not runs when the timing file exists and has a recent timestamp and intervals are enabled" do
328
+ node.normal["audit"]["interval"]["enabled"] = true
329
+ FileUtils.touch runner.report_timing_file
330
+ ten_minutes_ago = Time.now - 600
331
+ File.utime ten_minutes_ago, ten_minutes_ago, runner.report_timing_file
332
+ expect(runner).not_to receive(:report)
333
+ runner.report_with_interval
334
+ end
335
+
336
+ it "runs when the timing file exists and has a recent timestamp and intervals are enabled and the time is short" do
337
+ node.normal["audit"]["interval"]["enabled"] = true
338
+ node.normal["audit"]["interval"]["time"] = 9
339
+ FileUtils.touch runner.report_timing_file
340
+ ten_minutes_ago = Time.now - 600
341
+ File.utime ten_minutes_ago, ten_minutes_ago, runner.report_timing_file
342
+ expect(runner).to receive(:report)
343
+ runner.report_with_interval
344
+ end
345
+ end
285
346
  end
@@ -35,7 +35,7 @@ describe Chef::FileAccessControl do
35
35
  @events = Chef::EventDispatch::Dispatcher.new
36
36
  @run_context = Chef::RunContext.new(@node, {}, @events)
37
37
  @current_resource = Chef::Resource::File.new("/tmp/different_file.txt")
38
- @provider_requirements = Chef::Provider::ResourceRequirements.new(@resource, @run_context)
38
+ @provider_requirements = Chef::Provider::ResourceRequirements.new(@resource, @run_context, :create)
39
39
  @provider = double("File provider", requirements: @provider_requirements, manage_symlink_access?: false)
40
40
 
41
41
  @fac = Chef::FileAccessControl.new(@current_resource, @resource, @provider)
@@ -0,0 +1,53 @@
1
+ #
2
+ # Copyright:: Copyright (c) Chef Software Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require "spec_helper"
19
+
20
+ describe Chef::Mixin::WhyRun::ResourceRequirements do
21
+ class TestResource < Chef::Resource
22
+ action_class do
23
+ def define_resource_requirements
24
+ requirements.assert(:boom) do |a|
25
+ a.assertion { raise "boom1" }
26
+ a.failure_message("#{raise "boom2"}")
27
+ a.whyrun("#{raise "boom3"}")
28
+ end
29
+ end
30
+ end
31
+
32
+ action :boom do
33
+ # nothing
34
+ end
35
+
36
+ action :noboom do
37
+ # nothing
38
+ end
39
+ end
40
+
41
+ let(:node) { Chef::Node.new }
42
+ let(:events) { Chef::EventDispatch::Dispatcher.new }
43
+ let(:run_context) { Chef::RunContext.new(node, {}, events) }
44
+ let(:resource) { TestResource.new("name", run_context) }
45
+
46
+ it "raises an exception for an action where the assertions raise exceptions" do
47
+ expect { resource.run_action(:boom) }.to raise_error(StandardError, /boom2/)
48
+ end
49
+
50
+ it "does not raise an exception for an action which has no assertions" do
51
+ resource.run_action(:noboom)
52
+ end
53
+ end
@@ -169,6 +169,7 @@ describe Chef::Provider::Group::Groupadd do
169
169
 
170
170
  before do
171
171
  allow(File).to receive(:exist?).and_return(false)
172
+ provider.action = :modify
172
173
  provider.define_resource_requirements
173
174
  end
174
175
 
@@ -58,18 +58,18 @@ describe Chef::Provider::Group::Usermod do
58
58
  end
59
59
 
60
60
  it "should raise an error when setting the entire group directly" do
61
+ @provider.action = :modify
61
62
  @provider.define_resource_requirements
62
63
  @provider.load_current_resource
63
64
  @provider.instance_variable_set("@group_exists", true)
64
- @provider.action = :modify
65
65
  expect { @provider.run_action(@provider.process_resource_requirements) }.to raise_error(Chef::Exceptions::Group, "setting group members directly is not supported by #{@provider}, must set append true in group")
66
66
  end
67
67
 
68
68
  it "should raise an error when excluded_members are set" do
69
+ @provider.action = :modify
69
70
  @provider.define_resource_requirements
70
71
  @provider.load_current_resource
71
72
  @provider.instance_variable_set("@group_exists", true)
72
- @provider.action = :modify
73
73
  @new_resource.append(true)
74
74
  @new_resource.excluded_members(["someone"])
75
75
  expect { @provider.run_action(@provider.process_resource_requirements) }.to raise_error(Chef::Exceptions::Group, "excluded_members is not supported by #{@provider}")
@@ -61,6 +61,7 @@ describe Chef::Provider::Ifconfig do
61
61
  expect(@provider.instance_variable_get("@status").exitstatus).not_to eq(0)
62
62
  end
63
63
  it "should thrown an exception when ifconfig fails" do
64
+ @provider.action = :add
64
65
  @provider.define_resource_requirements
65
66
  expect { @provider.process_resource_requirements }.to raise_error Chef::Exceptions::Ifconfig
66
67
  end
@@ -81,6 +82,7 @@ describe Chef::Provider::Ifconfig do
81
82
  expect(@provider.instance_variable_get("@status").exitstatus).not_to eq(0)
82
83
  end
83
84
  it "should thrown an exception when ifconfig fails" do
85
+ @provider.action = :add
84
86
  @provider.define_resource_requirements
85
87
  expect { @provider.process_resource_requirements }.to raise_error Chef::Exceptions::Ifconfig
86
88
  end