chef 17.6.15 → 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/Gemfile +5 -0
- data/chef.gemspec +1 -0
- data/lib/chef/application/base.rb +1 -1
- data/lib/chef/chef_fs/file_pattern.rb +1 -1
- data/lib/chef/chef_fs/path_utils.rb +1 -1
- data/lib/chef/compliance/default_attributes.rb +12 -2
- data/lib/chef/compliance/runner.rb +51 -5
- data/lib/chef/data_collector/run_end_message.rb +1 -1
- data/lib/chef/dsl/reboot_pending.rb +1 -1
- data/lib/chef/exceptions.rb +10 -0
- 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/cron.rb +4 -1
- data/lib/chef/provider/git.rb +1 -1
- data/lib/chef/provider/ifconfig/debian.rb +1 -1
- 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/habitat.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/subversion.rb +5 -5
- 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/chef_client_trusted_certificate.rb +1 -0
- data/lib/chef/resource/chocolatey_config.rb +1 -1
- data/lib/chef/resource/chocolatey_feature.rb +1 -1
- data/lib/chef/resource/chocolatey_source.rb +24 -2
- data/lib/chef/resource/directory.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/habitat_install.rb +5 -5
- data/lib/chef/resource/inspec_waiver.rb +1 -1
- data/lib/chef/resource/inspec_waiver_file_entry.rb +1 -1
- data/lib/chef/resource/kernel_module.rb +27 -2
- data/lib/chef/resource/launchd.rb +0 -3
- data/lib/chef/resource/macos_userdefaults.rb +41 -131
- data/lib/chef/resource/rhsm_register.rb +31 -0
- data/lib/chef/resource/support/client.erb +7 -0
- data/lib/chef/resource/windows_auto_run.rb +1 -1
- data/lib/chef/resource/windows_dfs_namespace.rb +2 -2
- data/lib/chef/resource/windows_feature_powershell.rb +7 -7
- data/lib/chef/resource/windows_update_settings.rb +3 -3
- data/lib/chef/resource.rb +2 -2
- data/lib/chef/resource_reporter.rb +1 -1
- data/lib/chef/secret_fetcher/azure_key_vault.rb +62 -8
- data/lib/chef/secret_fetcher.rb +0 -1
- data/lib/chef/version.rb +1 -1
- data/spec/functional/dsl/reboot_pending_spec.rb +3 -3
- data/spec/functional/dsl/registry_helper_spec.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/dsc_script_spec.rb +2 -2
- data/spec/functional/resource/macos_userdefaults_spec.rb +139 -0
- data/spec/functional/resource/registry_spec.rb +81 -81
- data/spec/functional/resource/zypper_package_spec.rb +7 -0
- data/spec/functional/win32/registry_spec.rb +8 -8
- 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/data_collector_spec.rb +24 -1
- data/spec/unit/dsl/reboot_pending_spec.rb +1 -1
- data/spec/unit/file_access_control_spec.rb +1 -1
- data/spec/unit/mixin/default_paths_spec.rb +1 -1
- data/spec/unit/mixin/securable_spec.rb +3 -3
- data/spec/unit/mixin/why_run_spec.rb +53 -0
- data/spec/unit/provider/cron_spec.rb +45 -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 +8 -5
- data/spec/unit/provider/package/solaris_spec.rb +1 -0
- data/spec/unit/provider/package/windows_spec.rb +1 -1
- data/spec/unit/provider/registry_key_spec.rb +4 -4
- 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/service/windows_spec.rb +5 -5
- data/spec/unit/provider/subversion_spec.rb +4 -4
- data/spec/unit/provider/user_spec.rb +2 -0
- data/spec/unit/provider/windows_env_spec.rb +1 -1
- data/spec/unit/provider/zypper_repository_spec.rb +1 -1
- data/spec/unit/resource/chef_client_trusted_certificate_spec.rb +14 -0
- data/spec/unit/resource/chocolatey_config_spec.rb +1 -1
- data/spec/unit/resource/chocolatey_feature_spec.rb +1 -1
- data/spec/unit/resource/chocolatey_source_spec.rb +1 -1
- data/spec/unit/resource/dpkg_package_spec.rb +12 -0
- data/spec/unit/resource/kernel_module_spec.rb +2 -1
- data/spec/unit/resource/macos_user_defaults_spec.rb +36 -96
- data/spec/unit/resource/registry_key_spec.rb +10 -10
- data/spec/unit/resource/rhsm_register_spec.rb +42 -0
- data/spec/unit/resource/windows_auto_run_spec.rb +1 -1
- data/spec/unit/resource/windows_feature_powershell_spec.rb +1 -1
- data/spec/unit/resource/windows_firewall_rule_spec.rb +2 -2
- data/spec/unit/resource/windows_task_spec.rb +3 -3
- data/spec/unit/resource_reporter_spec.rb +2 -2
- data/spec/unit/resource_spec.rb +5 -0
- data/spec/unit/secret_fetcher/azure_key_vault_spec.rb +99 -20
- data/spec/unit/util/backup_spec.rb +1 -1
- data/spec/unit/win32/registry_spec.rb +3 -3
- metadata +24 -7
@@ -17,6 +17,7 @@
|
|
17
17
|
|
18
18
|
require_relative "../resource"
|
19
19
|
require "chef-utils/dist" unless defined?(ChefUtils::Dist)
|
20
|
+
require "corefoundation" if RUBY_PLATFORM.match?(/darwin/)
|
20
21
|
autoload :Plist, "plist"
|
21
22
|
|
22
23
|
class Chef
|
@@ -78,173 +79,82 @@ class Chef
|
|
78
79
|
required: true
|
79
80
|
|
80
81
|
property :host, [String, Symbol],
|
81
|
-
description: "Set either :current or a hostname to set the user default at the host level.",
|
82
|
+
description: "Set either :current, :all or a hostname to set the user default at the host level.",
|
82
83
|
desired_state: false,
|
83
84
|
introduced: "16.3"
|
84
85
|
|
85
86
|
property :value, [Integer, Float, String, TrueClass, FalseClass, Hash, Array],
|
86
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'.",
|
87
|
-
required: [:write]
|
88
|
-
coerce: proc { |v| v.is_a?(Hash) ? v.transform_keys(&:to_s) : v } # make sure keys are all strings for comparison
|
88
|
+
required: [:write]
|
89
89
|
|
90
90
|
property :type, String,
|
91
91
|
description: "The value type of the preference key.",
|
92
92
|
equal_to: %w{bool string int float array dict},
|
93
|
-
desired_state: false
|
93
|
+
desired_state: false,
|
94
|
+
deprecated: true
|
94
95
|
|
95
|
-
property :user, String,
|
96
|
-
description: "The system user that the default will be applied to.",
|
96
|
+
property :user, [String, Symbol],
|
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",
|
97
98
|
desired_state: false
|
98
99
|
|
99
100
|
property :sudo, [TrueClass, FalseClass],
|
100
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}.",
|
101
102
|
default: false,
|
102
|
-
desired_state: false
|
103
|
+
desired_state: false,
|
104
|
+
deprecated: true
|
103
105
|
|
104
106
|
load_current_value do |new_resource|
|
105
|
-
Chef::Log.debug "#load_current_value:
|
106
|
-
state = shell_out(defaults_export_cmd(new_resource), user: new_resource.user)
|
107
|
-
|
108
|
-
if state.error? || state.stdout.empty?
|
109
|
-
Chef::Log.debug "#load_current_value: #{defaults_export_cmd(new_resource).join(" ")} returned stdout: #{state.stdout} and stderr: #{state.stderr}"
|
110
|
-
current_value_does_not_exist!
|
111
|
-
end
|
107
|
+
Chef::Log.debug "#load_current_value: attempting to read \"#{new_resource.domain}\" value from preferences to determine state"
|
112
108
|
|
113
|
-
|
109
|
+
pref = get_preference(new_resource)
|
110
|
+
current_value_does_not_exist! if pref.nil?
|
114
111
|
|
115
|
-
|
116
|
-
|
117
|
-
key new_resource.key
|
118
|
-
else
|
119
|
-
current_value_does_not_exist!
|
120
|
-
end
|
121
|
-
|
122
|
-
value plist_data[new_resource.key]
|
123
|
-
end
|
124
|
-
|
125
|
-
#
|
126
|
-
# The defaults command to export a domain
|
127
|
-
#
|
128
|
-
# @return [Array] defaults command
|
129
|
-
#
|
130
|
-
def defaults_export_cmd(resource)
|
131
|
-
state_cmd = ["/usr/bin/defaults"]
|
132
|
-
|
133
|
-
if resource.host == "current"
|
134
|
-
state_cmd.concat(["-currentHost"])
|
135
|
-
elsif resource.host # they specified a non-nil value, which is a hostname
|
136
|
-
state_cmd.concat(["-host", resource.host])
|
137
|
-
end
|
138
|
-
|
139
|
-
state_cmd.concat(["export", resource.domain, "-"])
|
140
|
-
state_cmd
|
112
|
+
key new_resource.key
|
113
|
+
value pref
|
141
114
|
end
|
142
115
|
|
143
116
|
action :write, description: "Write the value to the specified domain/key." do
|
144
117
|
converge_if_changed do
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
shell_out!(cmd, user: new_resource.user)
|
118
|
+
Chef::Log.debug("Updating defaults value for #{new_resource.key} in #{new_resource.domain}")
|
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))
|
149
120
|
end
|
150
121
|
end
|
151
122
|
|
152
123
|
action :delete, description: "Delete a key from a domain." do
|
153
124
|
# if it's not there there's nothing to remove
|
154
|
-
return
|
125
|
+
return if current_resource.nil?
|
155
126
|
|
156
127
|
converge_by("delete domain:#{new_resource.domain} key:#{new_resource.key}") do
|
157
|
-
|
158
|
-
|
159
|
-
Chef::Log.debug("Removing defaults key by shelling out: #{cmd.join(" ")}")
|
160
|
-
|
161
|
-
shell_out!(cmd, user: new_resource.user)
|
128
|
+
Chef::Log.debug("Removing defaults key: #{new_resource.key}")
|
129
|
+
CF::Preferences.set!(new_resource.key, nil, new_resource.domain, to_cf_user(new_resource.user), to_cf_host(new_resource.host))
|
162
130
|
end
|
163
131
|
end
|
164
132
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
#
|
169
|
-
# @return [Array] Array representation of defaults command to run
|
170
|
-
#
|
171
|
-
def defaults_modify_cmd
|
172
|
-
cmd = ["/usr/bin/defaults"]
|
173
|
-
|
174
|
-
if new_resource.host == :current
|
175
|
-
cmd.concat(["-currentHost"])
|
176
|
-
elsif new_resource.host # they specified a non-nil value, which is a hostname
|
177
|
-
cmd.concat(["-host", new_resource.host])
|
178
|
-
end
|
179
|
-
|
180
|
-
cmd.concat([action.to_s, new_resource.domain, new_resource.key])
|
181
|
-
cmd.concat(processed_value) if action == :write
|
182
|
-
cmd.prepend("sudo") if new_resource.sudo
|
183
|
-
cmd
|
184
|
-
end
|
185
|
-
|
186
|
-
#
|
187
|
-
# convert the provided value into the format defaults expects
|
188
|
-
#
|
189
|
-
# @return [array] array of values starting with the type if applicable
|
190
|
-
#
|
191
|
-
def processed_value
|
192
|
-
type = new_resource.type || value_type(new_resource.value)
|
193
|
-
|
194
|
-
# when dict this creates an array of values ["Key1", "Value1", "Key2", "Value2" ...]
|
195
|
-
cmd_values = ["-#{type}"]
|
196
|
-
|
197
|
-
case type
|
198
|
-
when "dict"
|
199
|
-
cmd_values.concat(new_resource.value.flatten)
|
200
|
-
when "array"
|
201
|
-
cmd_values.concat(new_resource.value)
|
202
|
-
when "bool"
|
203
|
-
cmd_values.concat(bool_to_defaults_bool(new_resource.value))
|
204
|
-
else
|
205
|
-
cmd_values.concat([new_resource.value])
|
206
|
-
end
|
207
|
-
|
208
|
-
cmd_values
|
209
|
-
end
|
133
|
+
def get_preference(new_resource)
|
134
|
+
CF::Preferences.get(new_resource.key, new_resource.domain, to_cf_user(new_resource.user), to_cf_host(new_resource.host))
|
135
|
+
end
|
210
136
|
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
return ["FALSE"] if [false, "FALSE", "0", "false", "NO", "no"].include?(input)
|
221
|
-
|
222
|
-
# make sure it's very clear bad input was given
|
223
|
-
raise ArgumentError, "#{input} cannot be converted to a boolean value for use with Apple's defaults command. Acceptable values are: 'TRUE', 'YES', 'true, 'yes', '0', true, 'FALSE', 'false', 'NO', 'no', '1', or false."
|
137
|
+
# Return valid hostname based on the input from host property
|
138
|
+
def to_cf_host(value)
|
139
|
+
case value
|
140
|
+
when :all
|
141
|
+
CF::Preferences::ALL_HOSTS
|
142
|
+
when :current
|
143
|
+
CF::Preferences::CURRENT_HOST
|
144
|
+
else
|
145
|
+
value
|
224
146
|
end
|
147
|
+
end
|
225
148
|
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
when true, false
|
236
|
-
"bool"
|
237
|
-
when Integer
|
238
|
-
"int"
|
239
|
-
when Float
|
240
|
-
"float"
|
241
|
-
when Hash
|
242
|
-
"dict"
|
243
|
-
when Array
|
244
|
-
"array"
|
245
|
-
when String
|
246
|
-
"string"
|
247
|
-
end
|
149
|
+
# Return valid username based on the input from user property
|
150
|
+
def to_cf_user(value)
|
151
|
+
case value
|
152
|
+
when :all
|
153
|
+
CF::Preferences::ALL_USERS
|
154
|
+
when :current
|
155
|
+
CF::Preferences::CURRENT_USER
|
156
|
+
else
|
157
|
+
value
|
248
158
|
end
|
249
159
|
end
|
250
160
|
end
|
@@ -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
|
@@ -38,7 +38,7 @@ class Chef
|
|
38
38
|
|
39
39
|
property :full_users, Array,
|
40
40
|
description: "Determines which users should have full access to the share.",
|
41
|
-
default: [
|
41
|
+
default: ["BUILTIN\\administrators"]
|
42
42
|
|
43
43
|
property :change_users, Array,
|
44
44
|
description: "Determines which users should have change access to the share.",
|
@@ -50,7 +50,7 @@ class Chef
|
|
50
50
|
|
51
51
|
property :root, String,
|
52
52
|
description: "The root from which to create the DFS tree. Defaults to C:\\DFSRoots.",
|
53
|
-
default:
|
53
|
+
default: "C:\\DFSRoots"
|
54
54
|
|
55
55
|
action :create, description: "Creates the dfs namespace on the server." do
|
56
56
|
directory file_path do
|
@@ -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
|
@@ -145,7 +145,7 @@ class Chef
|
|
145
145
|
action :set, description: "Set Windows Update settings." do
|
146
146
|
actual_day = convert_day(new_resource.scheduled_install_day)
|
147
147
|
|
148
|
-
registry_key
|
148
|
+
registry_key "HKEY_LOCAL_MACHINE\\Software\\Policies\\Microsoft\\Windows\\WindowsUpdate" do
|
149
149
|
recursive true
|
150
150
|
values [{
|
151
151
|
name: "DisableOSUpgrade",
|
@@ -180,7 +180,7 @@ class Chef
|
|
180
180
|
action :create
|
181
181
|
end
|
182
182
|
|
183
|
-
registry_key
|
183
|
+
registry_key "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer" do
|
184
184
|
recursive true
|
185
185
|
values [{
|
186
186
|
name: "NoWindowsUpdate",
|
@@ -190,7 +190,7 @@ class Chef
|
|
190
190
|
action :create
|
191
191
|
end
|
192
192
|
|
193
|
-
registry_key
|
193
|
+
registry_key "HKEY_LOCAL_MACHINE\\Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU" do
|
194
194
|
recursive true
|
195
195
|
values [{
|
196
196
|
name: "AUOptions",
|
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."
|
@@ -1508,7 +1508,7 @@ class Chef
|
|
1508
1508
|
# @return Chef::CookbookVersion The cookbook in which this Resource was defined.
|
1509
1509
|
#
|
1510
1510
|
def cookbook_version
|
1511
|
-
if cookbook_name
|
1511
|
+
if cookbook_name && cookbook_name != "@recipe_files"
|
1512
1512
|
run_context.cookbook_collection[cookbook_name]
|
1513
1513
|
end
|
1514
1514
|
end
|
@@ -41,7 +41,7 @@ class Chef
|
|
41
41
|
as_hash["result"] = action_record.action.to_s
|
42
42
|
if new_resource.cookbook_name
|
43
43
|
as_hash["cookbook_name"] = new_resource.cookbook_name
|
44
|
-
as_hash["cookbook_version"] = new_resource.cookbook_version
|
44
|
+
as_hash["cookbook_version"] = new_resource.cookbook_version&.version
|
45
45
|
end
|
46
46
|
|
47
47
|
as_hash
|
@@ -1,4 +1,6 @@
|
|
1
1
|
require_relative "base"
|
2
|
+
require_relative "../exceptions"
|
3
|
+
require "uri" unless defined?(URI)
|
2
4
|
|
3
5
|
class Chef
|
4
6
|
class SecretFetcher
|
@@ -14,13 +16,19 @@ class Chef
|
|
14
16
|
#
|
15
17
|
# @example
|
16
18
|
#
|
17
|
-
# fetcher = SecretFetcher.for_service(:azure_key_vault, { vault: "my_vault" }, run_context
|
19
|
+
# fetcher = SecretFetcher.for_service(:azure_key_vault, { vault: "my_vault" }, run_context)
|
18
20
|
# fetcher.fetch("secretkey1", "v1")
|
19
21
|
#
|
20
22
|
# @example
|
21
23
|
#
|
22
|
-
# fetcher = SecretFetcher.for_service(:azure_key_vault, {}, run_context
|
24
|
+
# fetcher = SecretFetcher.for_service(:azure_key_vault, {}, run_context)
|
23
25
|
# fetcher.fetch("my_vault/secretkey1", "v1")
|
26
|
+
#
|
27
|
+
# @example
|
28
|
+
#
|
29
|
+
# fetcher = SecretFetcher.for_service(:azure_key_vault, { client_id: "540d76b6-7f76-456c-b68b-ccae4dc9d99d" }, run_context)
|
30
|
+
# fetcher.fetch("my_vault/secretkey1", "v1")
|
31
|
+
#
|
24
32
|
class AzureKeyVault < Base
|
25
33
|
|
26
34
|
def do_fetch(name, version)
|
@@ -48,6 +56,12 @@ class Chef
|
|
48
56
|
end
|
49
57
|
end
|
50
58
|
|
59
|
+
def validate!
|
60
|
+
raise Chef::Exceptions::Secret::ConfigurationInvalid, "You may only specify one (these are mutually exclusive): :object_id, :client_id, or :mi_res_id" if [object_id, client_id, mi_res_id].select { |x| !x.nil? }.length > 1
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
51
65
|
# Determine the vault name and secret name from the provided name.
|
52
66
|
# If it is not in the provided name in the form "vault_name/secret_name"
|
53
67
|
# it will determine the vault name from `config[:vault]`.
|
@@ -63,16 +77,56 @@ class Chef
|
|
63
77
|
end
|
64
78
|
end
|
65
79
|
|
80
|
+
def api_version
|
81
|
+
"2018-02-01"
|
82
|
+
end
|
83
|
+
|
84
|
+
def resource
|
85
|
+
"https://vault.azure.net"
|
86
|
+
end
|
87
|
+
|
88
|
+
def object_id
|
89
|
+
config[:object_id]
|
90
|
+
end
|
91
|
+
|
92
|
+
def client_id
|
93
|
+
config[:client_id]
|
94
|
+
end
|
95
|
+
|
96
|
+
def mi_res_id
|
97
|
+
config[:mi_res_id]
|
98
|
+
end
|
99
|
+
|
100
|
+
def token_query
|
101
|
+
@token_query ||= begin
|
102
|
+
p = {}
|
103
|
+
p["api-version"] = api_version
|
104
|
+
p["resource"] = resource
|
105
|
+
p["object_id"] = object_id if object_id
|
106
|
+
p["client_id"] = client_id if client_id
|
107
|
+
p["mi_res_id"] = mi_res_id if mi_res_id
|
108
|
+
URI.encode_www_form(p)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
66
112
|
def fetch_token
|
67
|
-
token_uri = URI.parse("http://169.254.169.254/metadata/identity/oauth2/token
|
113
|
+
token_uri = URI.parse("http://169.254.169.254/metadata/identity/oauth2/token")
|
114
|
+
token_uri.query = token_query
|
68
115
|
http = Net::HTTP.new(token_uri.host, token_uri.port)
|
69
116
|
response = http.get(token_uri, { "Metadata" => "true" })
|
70
|
-
|
71
|
-
|
117
|
+
|
118
|
+
case response
|
119
|
+
when Net::HTTPSuccess
|
120
|
+
body = JSON.parse(response.body)
|
121
|
+
body["access_token"]
|
122
|
+
when Net::HTTPBadRequest
|
123
|
+
body = JSON.parse(response.body)
|
124
|
+
raise Chef::Exceptions::Secret::Azure::IdentityNotFound if body["error_description"] =~ /identity not found/i
|
125
|
+
else
|
126
|
+
body = JSON.parse(response.body)
|
127
|
+
body["access_token"]
|
128
|
+
end
|
72
129
|
end
|
73
130
|
end
|
74
131
|
end
|
75
132
|
end
|
76
|
-
|
77
|
-
|
78
|
-
|
data/lib/chef/secret_fetcher.rb
CHANGED
data/lib/chef/version.rb
CHANGED
@@ -39,8 +39,8 @@ describe Chef::DSL::RebootPending, :windows_only do
|
|
39
39
|
let(:reg_key) { nil }
|
40
40
|
let(:original_set) { false }
|
41
41
|
|
42
|
-
describe
|
43
|
-
let(:reg_key) {
|
42
|
+
describe "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\PendingFileRenameOperations" do
|
43
|
+
let(:reg_key) { "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Session Manager" }
|
44
44
|
let(:original_set) { registry.value_exists?(reg_key, { name: "PendingFileRenameOperations" }) }
|
45
45
|
|
46
46
|
it "returns true if the registry value exists" do
|
@@ -78,7 +78,7 @@ describe Chef::DSL::RebootPending, :windows_only do
|
|
78
78
|
|
79
79
|
describe "when there is nothing to indicate a reboot is pending" do
|
80
80
|
it "should return false" do
|
81
|
-
skip "reboot pending" if registry_value_exists?(
|
81
|
+
skip "reboot pending" if registry_value_exists?("HKLM\\SYSTEM\\CurrentControlSet\\Control\\Session Manager", { name: "PendingFileRenameOperations" }) ||
|
82
82
|
registry_key_exists?('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired') ||
|
83
83
|
registry_key_exists?('HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending')
|
84
84
|
expect(recipe.reboot_pending?).to be_falsey
|
@@ -24,7 +24,7 @@ describe Chef::Resource::RegistryKey, :windows_only do
|
|
24
24
|
before(:all) do
|
25
25
|
::Win32::Registry::HKEY_CURRENT_USER.create "Software\\Root"
|
26
26
|
::Win32::Registry::HKEY_CURRENT_USER.create "Software\\Root\\Branch"
|
27
|
-
::Win32::Registry::HKEY_CURRENT_USER.open(
|
27
|
+
::Win32::Registry::HKEY_CURRENT_USER.open("Software\\Root", Win32::Registry::KEY_ALL_ACCESS) do |reg|
|
28
28
|
reg["RootType1", Win32::Registry::REG_SZ] = "fibrous"
|
29
29
|
reg.write("Roots", Win32::Registry::REG_MULTI_SZ, ["strong roots", "healthy tree"])
|
30
30
|
end
|
@@ -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
|