chef 17.7.29 → 17.8.25
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/chef/application/base.rb +1 -1
- data/lib/chef/compliance/default_attributes.rb +12 -2
- data/lib/chef/compliance/runner.rb +51 -5
- data/lib/chef/mixin/powershell_exec.rb +6 -5
- data/lib/chef/mixin/why_run.rb +8 -2
- data/lib/chef/powershell.rb +8 -6
- data/lib/chef/provider/mount/linux.rb +16 -2
- data/lib/chef/provider/mount/mount.rb +1 -1
- data/lib/chef/provider/package/dnf.rb +1 -1
- data/lib/chef/provider/package/powershell.rb +13 -10
- data/lib/chef/provider/package/zypper.rb +2 -0
- data/lib/chef/provider/package.rb +58 -23
- data/lib/chef/provider.rb +1 -1
- data/lib/chef/pwsh.rb +3 -2
- data/lib/chef/resource/chef_client_config.rb +22 -1
- data/lib/chef/resource/chef_client_launchd.rb +1 -1
- data/lib/chef/resource/dnf_package.rb +4 -6
- data/lib/chef/resource/dpkg_package.rb +5 -0
- data/lib/chef/resource/execute.rb +1 -4
- data/lib/chef/resource/launchd.rb +0 -3
- data/lib/chef/resource/macos_userdefaults.rb +5 -7
- data/lib/chef/resource/rhsm_register.rb +31 -0
- data/lib/chef/resource/support/client.erb +7 -0
- data/lib/chef/resource/windows_feature_powershell.rb +7 -7
- data/lib/chef/resource.rb +1 -1
- data/lib/chef/version.rb +1 -1
- data/spec/functional/resource/dnf_package_spec.rb +34 -20
- data/spec/functional/resource/dpkg_package_spec.rb +16 -0
- data/spec/functional/resource/macos_userdefaults_spec.rb +20 -0
- data/spec/functional/resource/zypper_package_spec.rb +7 -0
- data/spec/integration/client/client_spec.rb +31 -0
- data/spec/unit/application/base_spec.rb +40 -0
- data/spec/unit/compliance/runner_spec.rb +62 -1
- data/spec/unit/file_access_control_spec.rb +1 -1
- data/spec/unit/mixin/why_run_spec.rb +53 -0
- data/spec/unit/provider/group/groupadd_spec.rb +1 -0
- data/spec/unit/provider/group/usermod_spec.rb +2 -2
- data/spec/unit/provider/ifconfig_spec.rb +2 -0
- data/spec/unit/provider/mount/linux_spec.rb +16 -3
- data/spec/unit/provider/package/bff_spec.rb +1 -0
- data/spec/unit/provider/package/powershell_spec.rb +114 -114
- data/spec/unit/provider/package/rubygems_spec.rb +3 -0
- data/spec/unit/provider/package/solaris_spec.rb +1 -0
- data/spec/unit/provider/service/arch_service_spec.rb +2 -2
- data/spec/unit/provider/service/debian_service_spec.rb +1 -0
- data/spec/unit/provider/service/gentoo_service_spec.rb +1 -0
- data/spec/unit/provider/service/macosx_spec.rb +1 -0
- data/spec/unit/provider/service/redhat_spec.rb +4 -1
- data/spec/unit/provider/service/simple_service_spec.rb +6 -4
- data/spec/unit/provider/user_spec.rb +2 -0
- data/spec/unit/resource/dpkg_package_spec.rb +12 -0
- data/spec/unit/resource/rhsm_register_spec.rb +42 -0
- 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
|
-
|
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 =
|
104
|
-
Chef::Log.info(cmd.
|
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 =
|
119
|
-
Chef::Log.info(cmd.
|
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 =
|
136
|
-
Chef::Log.info(cmd.
|
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 =
|
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
@@ -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(
|
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
|
@@ -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
|