chef 18.4.2 → 18.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +4 -1
- data/chef.gemspec +7 -7
- data/lib/chef/application/client.rb +12 -0
- data/lib/chef/client.rb +10 -16
- data/lib/chef/compliance/runner.rb +10 -0
- data/lib/chef/cookbook/chefignore.rb +4 -1
- data/lib/chef/cookbook/cookbook_version_loader.rb +1 -1
- data/lib/chef/cookbook/synchronizer.rb +7 -1
- data/lib/chef/cookbook_manifest.rb +2 -2
- data/lib/chef/file_access_control/unix.rb +9 -9
- data/lib/chef/file_cache.rb +17 -2
- data/lib/chef/file_content_management/deploy/target_io.rb +29 -0
- data/lib/chef/file_content_management/deploy.rb +4 -1
- data/lib/chef/formatters/doc.rb +1 -1
- data/lib/chef/mixin/file_class.rb +3 -1
- data/lib/chef/mixin/get_source_from_package.rb +1 -1
- data/lib/chef/mixin/openssl_helper.rb +1 -1
- data/lib/chef/node/attribute.rb +3 -11
- data/lib/chef/node/immutable_collections.rb +15 -8
- data/lib/chef/node/mixin/state_tracking.rb +6 -3
- data/lib/chef/node.rb +1 -1
- data/lib/chef/policy_builder/policyfile.rb +8 -0
- data/lib/chef/provider/.gitkeep +0 -0
- data/lib/chef/provider/cookbook_file.rb +1 -1
- data/lib/chef/provider/cron.rb +1 -1
- data/lib/chef/provider/directory.rb +15 -15
- data/lib/chef/provider/file.rb +42 -29
- data/lib/chef/provider/git.rb +8 -8
- data/lib/chef/provider/group/aix.rb +1 -1
- data/lib/chef/provider/group/dscl.rb +1 -1
- data/lib/chef/provider/group/gpasswd.rb +2 -2
- data/lib/chef/provider/group/groupadd.rb +1 -1
- data/lib/chef/provider/group/groupmod.rb +2 -2
- data/lib/chef/provider/group/pw.rb +2 -2
- data/lib/chef/provider/group/solaris.rb +2 -2
- data/lib/chef/provider/group/usermod.rb +2 -2
- data/lib/chef/provider/group.rb +1 -1
- data/lib/chef/provider/http_request.rb +2 -3
- data/lib/chef/provider/ifconfig/aix.rb +1 -1
- data/lib/chef/provider/ifconfig/debian.rb +3 -3
- data/lib/chef/provider/ifconfig/redhat.rb +1 -1
- data/lib/chef/provider/ifconfig.rb +1 -1
- data/lib/chef/provider/link.rb +10 -10
- data/lib/chef/provider/mount/aix.rb +4 -4
- data/lib/chef/provider/mount/linux.rb +4 -4
- data/lib/chef/provider/mount/mount.rb +11 -11
- data/lib/chef/provider/package/apt.rb +2 -11
- data/lib/chef/provider/package/bff.rb +3 -3
- data/lib/chef/provider/package/chocolatey.rb +54 -24
- data/lib/chef/provider/package/dpkg.rb +3 -3
- data/lib/chef/provider/package/freebsd/base.rb +1 -1
- data/lib/chef/provider/package/habitat.rb +5 -3
- data/lib/chef/provider/package/ips.rb +2 -2
- data/lib/chef/provider/package/openbsd.rb +3 -2
- data/lib/chef/provider/package/pacman.rb +4 -4
- data/lib/chef/provider/package/paludis.rb +2 -2
- data/lib/chef/provider/package/portage.rb +1 -1
- data/lib/chef/provider/package/powershell.rb +1 -0
- data/lib/chef/provider/package/rpm.rb +2 -2
- data/lib/chef/provider/package/smartos.rb +2 -2
- data/lib/chef/provider/package/snap.rb +2 -1
- data/lib/chef/provider/package/snap_tm.rb +79 -0
- data/lib/chef/provider/package/solaris.rb +4 -4
- data/lib/chef/provider/package/zypper.rb +4 -5
- data/lib/chef/provider/package.rb +1 -1
- data/lib/chef/provider/remote_directory.rb +5 -5
- data/lib/chef/provider/remote_file/http.rb +2 -3
- data/lib/chef/provider/remote_file.rb +1 -1
- data/lib/chef/provider/route.rb +9 -9
- data/lib/chef/provider/service/aix.rb +1 -1
- data/lib/chef/provider/service/aixinit.rb +4 -4
- data/lib/chef/provider/service/arch.rb +6 -6
- data/lib/chef/provider/service/debian.rb +5 -5
- data/lib/chef/provider/service/freebsd.rb +7 -7
- data/lib/chef/provider/service/gentoo.rb +5 -5
- data/lib/chef/provider/service/init.rb +2 -2
- data/lib/chef/provider/service/insserv.rb +2 -2
- data/lib/chef/provider/service/invokercd.rb +1 -1
- data/lib/chef/provider/service/openbsd.rb +7 -7
- data/lib/chef/provider/service/redhat.rb +3 -3
- data/lib/chef/provider/service/solaris.rb +2 -2
- data/lib/chef/provider/service/systemd.rb +2 -2
- data/lib/chef/provider/service/upstart.rb +2 -2
- data/lib/chef/provider/service/windows.rb +0 -1
- data/lib/chef/provider/subversion.rb +8 -8
- data/lib/chef/provider/systemd_unit.rb +3 -3
- data/lib/chef/provider/template.rb +1 -1
- data/lib/chef/provider/user/aix.rb +3 -3
- data/lib/chef/provider/user/linux.rb +7 -2
- data/lib/chef/provider/user/pw.rb +3 -3
- data/lib/chef/provider/user/solaris.rb +7 -7
- data/lib/chef/provider/user.rb +7 -8
- data/lib/chef/provider/yum_repository.rb +1 -3
- data/lib/chef/provider/zypper_repository.rb +1 -1
- data/lib/chef/providers.rb +1 -0
- data/lib/chef/resource/.gitkeep +0 -0
- data/lib/chef/resource/alternatives.rb +2 -2
- data/lib/chef/resource/apt_preference.rb +1 -1
- data/lib/chef/resource/apt_repository.rb +7 -9
- data/lib/chef/resource/apt_update.rb +3 -3
- data/lib/chef/resource/bff_package.rb +1 -1
- data/lib/chef/resource/chef_client_config.rb +3 -2
- data/lib/chef/resource/chef_client_systemd_timer.rb +5 -0
- data/lib/chef/resource/chef_gem.rb +1 -1
- data/lib/chef/resource/chef_sleep.rb +1 -1
- data/lib/chef/resource/cookbook_file.rb +1 -1
- data/lib/chef/resource/cron/cron.rb +1 -1
- data/lib/chef/resource/cron/cron_d.rb +1 -1
- data/lib/chef/resource/cron_access.rb +1 -1
- data/lib/chef/resource/directory.rb +1 -1
- data/lib/chef/resource/dpkg_package.rb +1 -1
- data/lib/chef/resource/execute.rb +8 -6
- data/lib/chef/resource/file/verification/json.rb +1 -1
- data/lib/chef/resource/file/verification/systemd_unit.rb +1 -1
- data/lib/chef/resource/file/verification/yaml.rb +1 -1
- data/lib/chef/resource/file.rb +1 -1
- data/lib/chef/resource/freebsd_package.rb +2 -2
- data/lib/chef/resource/group.rb +1 -1
- data/lib/chef/resource/habitat/habitat_package.rb +1 -1
- data/lib/chef/resource/habitat/habitat_sup.rb +9 -9
- data/lib/chef/resource/habitat/habitat_sup_systemd.rb +2 -2
- data/lib/chef/resource/habitat_install.rb +5 -4
- data/lib/chef/resource/hostname.rb +11 -10
- data/lib/chef/resource/http_request.rb +1 -1
- data/lib/chef/resource/ifconfig.rb +1 -1
- data/lib/chef/resource/inspec_input.rb +3 -1
- data/lib/chef/resource/inspec_waiver.rb +1 -1
- data/lib/chef/resource/inspec_waiver_file_entry.rb +1 -1
- data/lib/chef/resource/ips_package.rb +2 -2
- data/lib/chef/resource/kernel_module.rb +2 -2
- data/lib/chef/resource/link.rb +1 -1
- data/lib/chef/resource/locale.rb +2 -2
- data/lib/chef/resource/mount.rb +1 -1
- data/lib/chef/resource/notify_group.rb +1 -1
- data/lib/chef/resource/ohai.rb +1 -1
- data/lib/chef/resource/ohai_hint.rb +1 -1
- data/lib/chef/resource/openbsd_package.rb +2 -2
- data/lib/chef/resource/package.rb +1 -1
- data/lib/chef/resource/pacman_package.rb +1 -1
- data/lib/chef/resource/paludis_package.rb +1 -1
- data/lib/chef/resource/portage_package.rb +1 -1
- data/lib/chef/resource/powershell_package.rb +4 -0
- data/lib/chef/resource/reboot.rb +1 -1
- data/lib/chef/resource/remote_directory.rb +1 -1
- data/lib/chef/resource/remote_file.rb +1 -1
- data/lib/chef/resource/rhsm_errata.rb +1 -1
- data/lib/chef/resource/rhsm_errata_level.rb +1 -1
- data/lib/chef/resource/rhsm_register.rb +1 -1
- data/lib/chef/resource/rhsm_repo.rb +3 -4
- data/lib/chef/resource/rhsm_subscription.rb +8 -9
- data/lib/chef/resource/route.rb +1 -1
- data/lib/chef/resource/rpm_package.rb +1 -1
- data/lib/chef/resource/scm/git.rb +1 -1
- data/lib/chef/resource/scm/subversion.rb +1 -1
- data/lib/chef/resource/selinux/common_helpers.rb +1 -1
- data/lib/chef/resource/selinux_boolean.rb +1 -1
- data/lib/chef/resource/selinux_fcontext.rb +3 -3
- data/lib/chef/resource/selinux_install.rb +1 -1
- data/lib/chef/resource/selinux_login.rb +1 -1
- data/lib/chef/resource/selinux_module.rb +5 -5
- data/lib/chef/resource/selinux_permissive.rb +2 -2
- data/lib/chef/resource/selinux_port.rb +2 -2
- data/lib/chef/resource/selinux_state.rb +2 -2
- data/lib/chef/resource/selinux_user.rb +1 -1
- data/lib/chef/resource/smartos_package.rb +2 -2
- data/lib/chef/resource/snap_package.rb +24 -1
- data/lib/chef/resource/solaris_package.rb +1 -1
- data/lib/chef/resource/ssh_known_hosts_entry.rb +1 -1
- data/lib/chef/resource/sudo.rb +5 -5
- data/lib/chef/resource/support/client.erb +1 -1
- data/lib/chef/resource/swap_file.rb +6 -6
- data/lib/chef/resource/sysctl.rb +6 -5
- data/lib/chef/resource/systemd_unit.rb +1 -1
- data/lib/chef/resource/template.rb +1 -1
- data/lib/chef/resource/timezone.rb +5 -5
- data/lib/chef/resource/user/aix_user.rb +2 -2
- data/lib/chef/resource/user/linux_user.rb +2 -2
- data/lib/chef/resource/user/pw_user.rb +2 -2
- data/lib/chef/resource/user/solaris_user.rb +2 -2
- data/lib/chef/resource/user_ulimit.rb +1 -1
- data/lib/chef/resource/yum_repository.rb +1 -1
- data/lib/chef/resource/zypper_package.rb +2 -2
- data/lib/chef/resource/zypper_repository.rb +2 -2
- data/lib/chef/run_lock.rb +3 -0
- data/lib/chef/scan_access_control.rb +6 -6
- data/lib/chef/target_io/dir.rb +12 -0
- data/lib/chef/target_io/etc.rb +16 -0
- data/lib/chef/target_io/file.rb +12 -0
- data/lib/chef/target_io/fileutils.rb +12 -0
- data/lib/chef/target_io/http.rb +22 -0
- data/lib/chef/target_io/io.rb +12 -0
- data/lib/chef/target_io/shadow.rb +44 -0
- data/lib/chef/target_io/train/dir.rb +69 -0
- data/lib/chef/target_io/train/etc.rb +112 -0
- data/lib/chef/target_io/train/file.rb +219 -0
- data/lib/chef/target_io/train/fileutils.rb +220 -0
- data/lib/chef/target_io/train/http.rb +117 -0
- data/lib/chef/target_io/train/io.rb +13 -0
- data/lib/chef/target_io/train/shadow.rb +52 -0
- data/lib/chef/target_io/train_compat.rb +7 -0
- data/lib/chef/target_io.rb +9 -0
- data/lib/chef/util/backup.rb +1 -1
- data/lib/chef/util/diff.rb +14 -1
- data/lib/chef/util/file_edit.rb +4 -4
- data/lib/chef/version.rb +1 -1
- data/lib/chef.rb +2 -0
- data/spec/functional/resource/remote_file_spec.rb +1 -1
- data/spec/integration/client/fips_spec.rb +11 -2
- data/spec/integration/client/open_ssl_spec.rb +20 -0
- data/spec/spec_helper.rb +3 -1
- data/spec/support/platform_helpers.rb +20 -7
- data/spec/unit/client_spec.rb +0 -16
- data/spec/unit/file_cache_spec.rb +64 -0
- data/spec/unit/mixin/openssl_helper_spec.rb +6 -1
- data/spec/unit/provider/apt_repository_spec.rb +1 -1
- data/spec/unit/provider/package/chocolatey_spec.rb +17 -12
- data/spec/unit/provider/package/windows_spec.rb +5 -5
- data/spec/unit/provider/package/zypper_spec.rb +0 -10
- data/spec/unit/provider/route_spec.rb +6 -4
- data/spec/unit/resource/rhsm_repo_spec.rb +1 -0
- data/spec/unit/resource/rhsm_subscription_spec.rb +2 -0
- metadata +31 -10
@@ -0,0 +1,117 @@
|
|
1
|
+
# require_relative "../mixin/which"
|
2
|
+
|
3
|
+
module TargetIO
|
4
|
+
module TrainCompat
|
5
|
+
class HTTP
|
6
|
+
attr_reader :last_response
|
7
|
+
|
8
|
+
def initialize(url, options = {})
|
9
|
+
@url = url.is_a?(URI) ? url.to_s : url
|
10
|
+
@options = options
|
11
|
+
@last_response = ""
|
12
|
+
end
|
13
|
+
|
14
|
+
# Send an HTTP HEAD request to the path
|
15
|
+
#
|
16
|
+
# === Parameters
|
17
|
+
# path:: path part of the request URL
|
18
|
+
def head(path, headers = {})
|
19
|
+
request(:HEAD, path, headers)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Send an HTTP GET request to the path
|
23
|
+
#
|
24
|
+
# === Parameters
|
25
|
+
# path:: The path to GET
|
26
|
+
def get(path, headers = {})
|
27
|
+
request(:GET, path, headers)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Send an HTTP PUT request to the path
|
31
|
+
#
|
32
|
+
# === Parameters
|
33
|
+
# path:: path part of the request URL
|
34
|
+
def put(path, json, headers = {})
|
35
|
+
request(:PUT, path, headers, json)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Send an HTTP POST request to the path
|
39
|
+
#
|
40
|
+
# === Parameters
|
41
|
+
# path:: path part of the request URL
|
42
|
+
def post(path, json, headers = {})
|
43
|
+
request(:POST, path, headers, json)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Send an HTTP DELETE request to the path
|
47
|
+
#
|
48
|
+
# === Parameters
|
49
|
+
# path:: path part of the request URL
|
50
|
+
def delete(path, headers = {})
|
51
|
+
request(:DELETE, path, headers)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Used inside Chef::Provider::RemoteFile::HTTPS
|
55
|
+
def streaming_request(path, headers = {}, tempfile = nil)
|
56
|
+
content = get(path, headers)
|
57
|
+
@last_response = content
|
58
|
+
|
59
|
+
tempfile.write(content)
|
60
|
+
tempfile.close
|
61
|
+
|
62
|
+
tempfile
|
63
|
+
end
|
64
|
+
|
65
|
+
def request(method, path, headers = {}, data = false)
|
66
|
+
cmd = nil
|
67
|
+
path = path.is_a?(URI) ? path.to_s : path
|
68
|
+
headers.merge!(@options[:headers] || {})
|
69
|
+
|
70
|
+
SUPPORTED_COMMANDS.each do |command_name|
|
71
|
+
executable = which(command_name).chop
|
72
|
+
next if !executable || executable.empty?
|
73
|
+
|
74
|
+
# There are different ways to call (constructor, argument, combination of both)
|
75
|
+
full_url = if path.start_with?("http")
|
76
|
+
path
|
77
|
+
elsif path.empty? || @url.end_with?(path)
|
78
|
+
@url
|
79
|
+
else
|
80
|
+
File.join(@url, path)
|
81
|
+
end
|
82
|
+
|
83
|
+
cmd = send(command_name.to_sym, executable, method.to_s.upcase, full_url, headers, data)
|
84
|
+
break
|
85
|
+
end
|
86
|
+
|
87
|
+
raise "Target needs one of #{SUPPORTED_COMMANDS.join("/")} for HTTP requests to work" unless cmd
|
88
|
+
|
89
|
+
connection = Chef.run_context&.transport_connection
|
90
|
+
connection.run_command(cmd).stdout
|
91
|
+
end
|
92
|
+
|
93
|
+
SUPPORTED_COMMANDS = %w{curl wget}.freeze
|
94
|
+
|
95
|
+
# Sending data is not yet supported
|
96
|
+
def curl(cmd, method, url, headers, _data)
|
97
|
+
cmd += headers.map { |name, value| " --header '#{name}: #{value}'" }.join
|
98
|
+
cmd += " --request #{method} "
|
99
|
+
cmd += url
|
100
|
+
end
|
101
|
+
|
102
|
+
# Sending data is not yet supported
|
103
|
+
def wget(cmd, method, url, headers, _data)
|
104
|
+
cmd += headers.map { |name, value| " --header '#{name}: #{value}'" }.join
|
105
|
+
cmd += " --method #{method}"
|
106
|
+
cmd += " --output-document=- "
|
107
|
+
cmd += url
|
108
|
+
end
|
109
|
+
|
110
|
+
# extend Chef::Mixin::Which
|
111
|
+
def which(cmd)
|
112
|
+
connection = Chef.run_context&.transport_connection
|
113
|
+
connection.run_command("which #{cmd}").stdout
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module TargetIO
|
2
|
+
module TrainCompat
|
3
|
+
module Shadow
|
4
|
+
# @see https://www.rubydoc.info/gems/ruby-shadow/2.5.0
|
5
|
+
class Passwd
|
6
|
+
class << self
|
7
|
+
def getspnam(name)
|
8
|
+
content = ::TargetIO::File.read("/etc/shadow")
|
9
|
+
entries = __parse_shadow(content)
|
10
|
+
data = entries.detect { |entry| entry["name"] == name }
|
11
|
+
return ::TargetIO::Shadow::Entry.new unless data
|
12
|
+
|
13
|
+
::TargetIO::Shadow::Entry.new(
|
14
|
+
data["sp_namp"],
|
15
|
+
data["sp_pwdp"],
|
16
|
+
data["sp_lstchg"],
|
17
|
+
data["sp_min"],
|
18
|
+
data["sp_max"],
|
19
|
+
data["sp_warn"],
|
20
|
+
data["sp_inact"],
|
21
|
+
data["sp_expire"],
|
22
|
+
data["sp_loginclass"]
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
def __parse_shadow(content)
|
27
|
+
content.to_s.split("\n").map do |line|
|
28
|
+
next if line[0] == "#"
|
29
|
+
|
30
|
+
__parse_shadow_line(line)
|
31
|
+
end.compact
|
32
|
+
end
|
33
|
+
|
34
|
+
def __parse_shadow_line(line)
|
35
|
+
x = line.split(":")
|
36
|
+
{
|
37
|
+
# rubocop:disable Layout/AlignHash
|
38
|
+
"sp_namp" => x.at(0),
|
39
|
+
"sp_pwdp" => x.at(1),
|
40
|
+
"sp_lstchg" => x.at(2),
|
41
|
+
"sp_min" => x.at(3),
|
42
|
+
"sp_max" => x.at(4),
|
43
|
+
"sp_warn" => x.at(5),
|
44
|
+
"sp_inact" => x.at(6),
|
45
|
+
"sp_expire" => x.at(7),
|
46
|
+
}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require_relative "target_io/dir"
|
2
|
+
require_relative "target_io/etc"
|
3
|
+
require_relative "target_io/file"
|
4
|
+
require_relative "target_io/fileutils"
|
5
|
+
require_relative "target_io/http"
|
6
|
+
require_relative "target_io/io"
|
7
|
+
require_relative "target_io/shadow"
|
8
|
+
|
9
|
+
require_relative "target_io/train_compat"
|
data/lib/chef/util/backup.rb
CHANGED
@@ -30,7 +30,7 @@ class Chef
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def backup!
|
33
|
-
if @new_resource.backup != false && @new_resource.backup > 0 && ::File.exist?(path)
|
33
|
+
if @new_resource.backup != false && @new_resource.backup > 0 && ::TargetIO::File.exist?(path)
|
34
34
|
do_backup
|
35
35
|
# Clean up after the number of backups
|
36
36
|
slice_number = @new_resource.backup
|
data/lib/chef/util/diff.rb
CHANGED
@@ -60,7 +60,7 @@ class Chef
|
|
60
60
|
|
61
61
|
def use_tempfile_if_missing(file)
|
62
62
|
tempfile = nil
|
63
|
-
unless File.exist?(file)
|
63
|
+
unless TargetIO::File.exist?(file)
|
64
64
|
Chef::Log.trace("File #{file} does not exist to diff against, using empty tempfile")
|
65
65
|
tempfile = Tempfile.new("chef-diff")
|
66
66
|
file = tempfile.path
|
@@ -131,6 +131,19 @@ class Chef
|
|
131
131
|
diff_filesize_threshold = Chef::Config[:diff_filesize_threshold]
|
132
132
|
diff_output_threshold = Chef::Config[:diff_output_threshold]
|
133
133
|
|
134
|
+
# Download files for diffs in Target Mode, then work locally
|
135
|
+
if ChefConfig::Config.target_mode?
|
136
|
+
connection = Chef.run_context&.transport_connection
|
137
|
+
|
138
|
+
old_copy = Tempfile.new(old_file)
|
139
|
+
connection.download(old_file, old_copy.path) if connection.file(old_file).exist?
|
140
|
+
old_file = old_copy.path
|
141
|
+
|
142
|
+
new_copy = Tempfile.new(new_file)
|
143
|
+
connection.download(new_file, new_copy.path) if connection.file(new_file).exist?
|
144
|
+
new_file = new_copy.path
|
145
|
+
end
|
146
|
+
|
134
147
|
if ::File.size(old_file) > diff_filesize_threshold || ::File.size(new_file) > diff_filesize_threshold
|
135
148
|
return "(file sizes exceed #{diff_filesize_threshold} bytes, diff output suppressed)"
|
136
149
|
end
|
data/lib/chef/util/file_edit.rb
CHANGED
@@ -29,9 +29,9 @@ class Chef
|
|
29
29
|
public
|
30
30
|
|
31
31
|
def initialize(filepath)
|
32
|
-
raise ArgumentError, "File '#{filepath}' does not exist" unless File.exist?(filepath)
|
32
|
+
raise ArgumentError, "File '#{filepath}' does not exist" unless TargetIO::File.exist?(filepath)
|
33
33
|
|
34
|
-
@editor = Editor.new(File.open(filepath, &:readlines))
|
34
|
+
@editor = Editor.new(TargetIO::File.open(filepath, &:readlines))
|
35
35
|
@original_pathname = filepath
|
36
36
|
@file_edited = false
|
37
37
|
end
|
@@ -85,8 +85,8 @@ class Chef
|
|
85
85
|
def write_file
|
86
86
|
if @changes
|
87
87
|
backup_pathname = original_pathname + ".old"
|
88
|
-
FileUtils.cp(original_pathname, backup_pathname, preserve: true)
|
89
|
-
File.open(original_pathname, "w") do |newfile|
|
88
|
+
TargetIO::FileUtils.cp(original_pathname, backup_pathname, preserve: true)
|
89
|
+
TargetIO::File.open(original_pathname, "w") do |newfile|
|
90
90
|
editor.lines.each do |line|
|
91
91
|
newfile.puts(line)
|
92
92
|
end
|
data/lib/chef/version.rb
CHANGED
data/lib/chef.rb
CHANGED
@@ -245,7 +245,7 @@ describe Chef::Resource::RemoteFile do
|
|
245
245
|
end
|
246
246
|
end
|
247
247
|
|
248
|
-
context "when the
|
248
|
+
context "when the file is only accessible as a specific alternate identity" do
|
249
249
|
let(:windows_nonadmin_user) { "chefremfile2" }
|
250
250
|
let(:windows_nonadmin_user_password) { "j82ajfxK3;2Xe2" }
|
251
251
|
include_context "a non-admin Windows user"
|
@@ -9,12 +9,21 @@ describe "chef-client fips" do
|
|
9
9
|
after { OpenSSL.fips_mode = false }
|
10
10
|
|
11
11
|
# For non-FIPS OSes/builds of Ruby, enabling FIPS should error
|
12
|
-
example "Error enabling fips_mode if FIPS not linked",
|
12
|
+
example "Error enabling fips_mode if FIPS not linked", :fips_mode_negative_test do
|
13
13
|
expect { enable_fips }.to raise_error(OpenSSL::OpenSSLError)
|
14
14
|
end
|
15
15
|
|
16
|
+
example "Do not error on MD5 if not fips_mode", :fips_mode_negative_test do
|
17
|
+
expect { OpenSSL::Digest.new("MD5", "test string for digesting") }.not_to raise_error
|
18
|
+
end
|
19
|
+
|
16
20
|
# For FIPS OSes/builds of Ruby, enabling FIPS should not error
|
17
|
-
example "Do not error enabling fips_mode if FIPS linked",
|
21
|
+
example "Do not error enabling fips_mode if FIPS linked", :fips_mode_test do
|
18
22
|
expect { enable_fips }.not_to raise_error
|
19
23
|
end
|
24
|
+
|
25
|
+
example "Error on MD5 if fips_mode", :fips_mode_test do
|
26
|
+
enable_fips
|
27
|
+
expect { OpenSSL::Digest.new("MD5", "test string for digesting") }.to raise_error(OpenSSL::Digest::DigestError)
|
28
|
+
end
|
20
29
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "openssl checks" do
|
4
|
+
let(:openssl_version_default) do
|
5
|
+
if windows?
|
6
|
+
"1.0.2zi"
|
7
|
+
elsif macos?
|
8
|
+
"1.1.1m"
|
9
|
+
else
|
10
|
+
"3.0.9"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
%w{version library_version}.each do |method|
|
15
|
+
# macOS just picks up its own for some reason, maybe it circumvents a build step
|
16
|
+
example "check #{method}", not_supported_on_macos: true do
|
17
|
+
expect(OpenSSL.const_get("OPENSSL_#{method.upcase}")).to match(openssl_version_default), "OpenSSL doesn't match omnibus_overrides.rb"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -138,7 +138,8 @@ RSpec.configure do |config|
|
|
138
138
|
|
139
139
|
config.filter_run_excluding skip_buildkite: true if ENV["BUILDKITE"]
|
140
140
|
|
141
|
-
config.filter_run_excluding
|
141
|
+
config.filter_run_excluding fips_mode_test: true unless fips_mode_build?
|
142
|
+
config.filter_run_excluding fips_mode_negative_test: true # disable all fips_mode negative tests
|
142
143
|
# Skip fips on windows
|
143
144
|
# config.filter_run_excluding :fips_mode if windows?
|
144
145
|
|
@@ -180,6 +181,7 @@ RSpec.configure do |config|
|
|
180
181
|
config.filter_run_excluding aes_256_gcm_only: true unless aes_256_gcm?
|
181
182
|
config.filter_run_excluding broken: true
|
182
183
|
config.filter_run_excluding not_wpar: true unless wpar?
|
184
|
+
config.filter_run_excluding not_supported_on_s390x: true unless s390x?
|
183
185
|
config.filter_run_excluding not_supported_under_fips: true if fips?
|
184
186
|
config.filter_run_excluding rhel: true unless rhel?
|
185
187
|
config.filter_run_excluding rhel6: true unless rhel6?
|
@@ -67,10 +67,10 @@ end
|
|
67
67
|
|
68
68
|
def win32_os_version
|
69
69
|
@win32_os_version ||= begin
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
70
|
+
wmi = WmiLite::Wmi.new
|
71
|
+
host = wmi.first_of("Win32_OperatingSystem")
|
72
|
+
host["version"]
|
73
|
+
end
|
74
74
|
end
|
75
75
|
|
76
76
|
def windows_powershell_dsc?
|
@@ -80,7 +80,7 @@ def windows_powershell_dsc?
|
|
80
80
|
begin
|
81
81
|
wmi = WmiLite::Wmi.new("root/microsoft/windows/desiredstateconfiguration")
|
82
82
|
lcm = wmi.query("SELECT * FROM meta_class WHERE __this ISA 'MSFT_DSCLocalConfigurationManager'")
|
83
|
-
supports_dsc = !!
|
83
|
+
supports_dsc = !!lcm
|
84
84
|
rescue WmiLite::WmiException
|
85
85
|
end
|
86
86
|
supports_dsc
|
@@ -95,7 +95,7 @@ end
|
|
95
95
|
|
96
96
|
# detects if the hardware is 64-bit (evaluates to true in "WOW64" mode in a 32-bit app on a 64-bit system)
|
97
97
|
def windows64?
|
98
|
-
windows? && (
|
98
|
+
windows? && (ENV["PROCESSOR_ARCHITECTURE"] == "AMD64" || ENV["PROCESSOR_ARCHITEW6432"] == "AMD64")
|
99
99
|
end
|
100
100
|
|
101
101
|
# detects if the hardware is 32-bit
|
@@ -175,6 +175,10 @@ def wpar?
|
|
175
175
|
!((ohai[:virtualization] || {})[:wpar_no].nil?)
|
176
176
|
end
|
177
177
|
|
178
|
+
def s390x?
|
179
|
+
RUBY_PLATFORM.include?("s390x")
|
180
|
+
end
|
181
|
+
|
178
182
|
def supports_cloexec?
|
179
183
|
Fcntl.const_defined?(:F_SETFD) && Fcntl.const_defined?(:FD_CLOEXEC)
|
180
184
|
end
|
@@ -224,7 +228,15 @@ def aes_256_gcm?
|
|
224
228
|
end
|
225
229
|
|
226
230
|
def fips_mode_build?
|
227
|
-
|
231
|
+
if ENV.include?("BUILDKITE_LABEL") # try keying directly off Buildkite environments
|
232
|
+
# regex version of chef/chef-foundation:.expeditor/release.omnibus.yml:fips-platforms
|
233
|
+
[/el-.*-x86_64/, /el-.*-ppc64/, /el-.*aarch/, /ubuntu-/, /windows-/, /amazon-2/].any? do |os_arch|
|
234
|
+
ENV["BUILDKITE_LABEL"].match?(os_arch)
|
235
|
+
end
|
236
|
+
else
|
237
|
+
# if you're testing your local build
|
238
|
+
OpenSSL::OPENSSL_FIPS
|
239
|
+
end
|
228
240
|
end
|
229
241
|
|
230
242
|
def fips?
|
@@ -233,6 +245,7 @@ end
|
|
233
245
|
|
234
246
|
class HttpHelper
|
235
247
|
extend Ohai::Mixin::HttpHelper
|
248
|
+
|
236
249
|
def self.logger
|
237
250
|
Chef::Log
|
238
251
|
end
|
data/spec/unit/client_spec.rb
CHANGED
@@ -384,22 +384,6 @@ describe Chef::Client do
|
|
384
384
|
end
|
385
385
|
end
|
386
386
|
|
387
|
-
describe "eol release warning" do
|
388
|
-
it "warns when running an EOL release" do
|
389
|
-
stub_const("Chef::VERSION", 15)
|
390
|
-
allow(Time).to receive(:now).and_return(Time.new(2021, 5, 1, 5))
|
391
|
-
expect(logger).to receive(:warn).with(/This release of.*became end of life \(EOL\) on May 1st 2021/)
|
392
|
-
client.warn_if_eol
|
393
|
-
end
|
394
|
-
|
395
|
-
it "does not warn when running an non-EOL release" do
|
396
|
-
stub_const("Chef::VERSION", 15)
|
397
|
-
allow(Time).to receive(:now).and_return(Time.new(2021, 4, 31))
|
398
|
-
expect(logger).to_not receive(:warn).with(/became end of life/)
|
399
|
-
client.warn_if_eol
|
400
|
-
end
|
401
|
-
end
|
402
|
-
|
403
387
|
describe "authentication protocol selection" do
|
404
388
|
context "when FIPS is disabled" do
|
405
389
|
before do
|
@@ -94,7 +94,71 @@ describe Chef::FileCache do
|
|
94
94
|
it "searches for cached files by globbing" do
|
95
95
|
expect(Chef::FileCache.find("snappy/**/*")).to eq(%w{snappy/patter})
|
96
96
|
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "#find handles regex-unsafe unix paths" do
|
100
|
+
before(:each) do
|
101
|
+
# Dir.mktmpdir doesn't allow regex unsafe characters (the nerve!), so we'll have to fake file lookups
|
102
|
+
@file_cache_path = "/tmp/[foo* ^bar]"
|
103
|
+
escaped_file_cache_path = '/tmp/\[foo\* ^bar\]'
|
104
|
+
Chef::Config[:file_cache_path] = @file_cache_path
|
105
|
+
allow(Chef::Util::PathHelper).to receive(:escape_glob_dir).and_return(escaped_file_cache_path)
|
106
|
+
allow(Dir).to receive(:[]).with(File.join(escaped_file_cache_path, "snappy/**/*")).and_return([
|
107
|
+
File.join(@file_cache_path, "snappy"),
|
108
|
+
File.join(@file_cache_path, "snappy", "patter"),
|
109
|
+
])
|
110
|
+
allow(Dir).to receive(:[]).with(escaped_file_cache_path).and_return([
|
111
|
+
@file_cache_path,
|
112
|
+
])
|
113
|
+
[
|
114
|
+
File.join(@file_cache_path, "snappy", "patter"),
|
115
|
+
File.join(@file_cache_path, "whiz", "bang"),
|
116
|
+
].each do |f|
|
117
|
+
allow(File).to receive(:file?).with(f).and_return(true)
|
118
|
+
end
|
119
|
+
[
|
120
|
+
File.join(@file_cache_path, "snappy"),
|
121
|
+
File.join(@file_cache_path, "whiz"),
|
122
|
+
].each do |f|
|
123
|
+
allow(File).to receive(:file?).with(f).and_return(false)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
it "searches for cached files by globbing" do
|
128
|
+
expect(Chef::FileCache.find("snappy/**/*")).to eq(%w{snappy/patter})
|
129
|
+
end
|
130
|
+
end
|
97
131
|
|
132
|
+
describe "#find handles Windows paths" do
|
133
|
+
before(:each) do
|
134
|
+
allow(ChefUtils).to receive(:windows?).and_return(true)
|
135
|
+
@file_cache_path = 'C:\tmp\fakecache'
|
136
|
+
escaped_file_cache_path = "C:\\tmp\\fakecache"
|
137
|
+
Chef::Config[:file_cache_path] = @file_cache_path
|
138
|
+
allow(Chef::Util::PathHelper).to receive(:escape_glob_dir).and_return(escaped_file_cache_path)
|
139
|
+
allow(Dir).to receive(:[]).with(File.join(escaped_file_cache_path, "snappy/**/*")).and_return([
|
140
|
+
File.join(@file_cache_path, "snappy"),
|
141
|
+
File.join(@file_cache_path, "snappy", "patter"),
|
142
|
+
])
|
143
|
+
allow(Dir).to receive(:[]).with(escaped_file_cache_path).and_return([
|
144
|
+
@file_cache_path,
|
145
|
+
])
|
146
|
+
[
|
147
|
+
File.join(@file_cache_path, "snappy", "patter"),
|
148
|
+
File.join(@file_cache_path, "whiz", "bang"),
|
149
|
+
].each do |f|
|
150
|
+
allow(File).to receive(:file?).with(f).and_return(true)
|
151
|
+
end
|
152
|
+
[
|
153
|
+
File.join(@file_cache_path, "snappy"),
|
154
|
+
File.join(@file_cache_path, "whiz"),
|
155
|
+
].each do |f|
|
156
|
+
allow(File).to receive(:file?).with(f).and_return(false)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
it "searches for cached files by globbing" do
|
160
|
+
expect(Chef::FileCache.find("snappy/**/*")).to eq(%w{snappy/patter})
|
161
|
+
end
|
98
162
|
end
|
99
163
|
|
100
164
|
describe "when checking for the existence of a file" do
|
@@ -92,7 +92,12 @@ describe Chef::Mixin::OpenSSLHelper do
|
|
92
92
|
|
93
93
|
context "When the dhparam.pem file does exist, and does contain a vaild dhparam key" do
|
94
94
|
it "returns true" do
|
95
|
-
|
95
|
+
# bumped this from 256 to 1024 because OpenSSL 3.x will enforce
|
96
|
+
# size
|
97
|
+
# OpenSSL::PKey::PKeyError:
|
98
|
+
# EVP_PKEY_paramgen: modulus too small
|
99
|
+
# need to double check that the mixin itself doesn't allow smaller
|
100
|
+
@dhparam_file.puts(::OpenSSL::PKey::DH.new(1024).to_pem)
|
96
101
|
@dhparam_file.close
|
97
102
|
expect(instance.dhparam_pem_valid?(@dhparam_file.path)).to be_truthy
|
98
103
|
end
|
@@ -230,7 +230,7 @@ C5986B4F1257FFA86632CBA746181433FBB75451
|
|
230
230
|
it "gets a key" do
|
231
231
|
simples = double("HTTP")
|
232
232
|
allow(simples).to receive(:get).and_return("\"#{key}\"")
|
233
|
-
expect(Chef::HTTP::Simple).to receive(:new).with(url).and_return(simples)
|
233
|
+
expect(Chef::HTTP::Simple).to receive(:new).with(url, {}).and_return(simples)
|
234
234
|
expect(provider).to receive(:install_key_from_keyserver).with(key, "keyserver.ubuntu.com")
|
235
235
|
provider.install_ppa_key("chef", "main")
|
236
236
|
end
|
@@ -36,9 +36,9 @@ describe Chef::Provider::Package::Chocolatey, :windows_only do
|
|
36
36
|
# installed packages (ConEmu is upgradable)
|
37
37
|
let(:local_list_stdout) do
|
38
38
|
<<~EOF
|
39
|
-
Chocolatey v0.9.9.
|
40
|
-
chocolatey|0.9.9.
|
41
|
-
ConEmu|15.10.25.
|
39
|
+
Chocolatey v0.9.9.10
|
40
|
+
chocolatey|0.9.9.12
|
41
|
+
ConEmu|15.10.25.2
|
42
42
|
EOF
|
43
43
|
end
|
44
44
|
|
@@ -47,10 +47,10 @@ describe Chef::Provider::Package::Chocolatey, :windows_only do
|
|
47
47
|
allow(provider).to receive(:choco_exe).and_return(choco_exe)
|
48
48
|
local_list_obj = double(stdout: local_list_stdout)
|
49
49
|
allow(provider).to receive(:shell_out_compacted!).with(choco_exe, "list", "-l", "-r", { returns: [0, 2], timeout: timeout }).and_return(local_list_obj)
|
50
|
-
allow(provider).to receive(:powershell_exec!).with("#{choco_exe}
|
50
|
+
allow(provider).to receive(:powershell_exec!).with("Get-ItemProperty #{choco_exe} | select-object -expandproperty versioninfo | select-object -expandproperty productversion").and_return(double(result: "2.1.0"))
|
51
51
|
# Mock the local file system choco queries
|
52
52
|
allow(provider).to receive(:get_local_pkg_dirs).and_return(%w{chocolatey ConEmu})
|
53
|
-
allow(provider).to receive(:
|
53
|
+
allow(provider).to receive(:fetch_package_versions).and_return({ "chocolatey" => "0.9.9.11", "conemu" => "15.10.25.0" })
|
54
54
|
end
|
55
55
|
|
56
56
|
after(:each) do
|
@@ -70,10 +70,13 @@ describe Chef::Provider::Package::Chocolatey, :windows_only do
|
|
70
70
|
munin-node|1.6.1.20130823
|
71
71
|
EOF
|
72
72
|
remote_list_obj = double(stdout: remote_list_stdout)
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
73
|
+
|
74
|
+
package_names.each do |pkg|
|
75
|
+
if args
|
76
|
+
allow(provider).to receive(:shell_out_compacted!).with(choco_exe, provider.query_command, "-r", *([pkg] + args), { returns: [0, 2], timeout: timeout }).and_return(remote_list_obj)
|
77
|
+
else
|
78
|
+
allow(provider).to receive(:shell_out_compacted!).with(choco_exe, provider.query_command, "-r", pkg, { returns: [0, 2], timeout: timeout }).and_return(remote_list_obj)
|
79
|
+
end
|
77
80
|
end
|
78
81
|
end
|
79
82
|
|
@@ -89,12 +92,12 @@ describe Chef::Provider::Package::Chocolatey, :windows_only do
|
|
89
92
|
|
90
93
|
describe "choco searches change with the version" do
|
91
94
|
it "Choco V1 uses List" do
|
92
|
-
allow(provider).to receive(:powershell_exec!).with("#{choco_exe}
|
95
|
+
allow(provider).to receive(:powershell_exec!).with("Get-ItemProperty #{choco_exe} | select-object -expandproperty versioninfo | select-object -expandproperty productversion").and_return(double(result: "1.4.0"))
|
93
96
|
expect(provider.query_command).to eql("list")
|
94
97
|
end
|
95
98
|
|
96
99
|
it "Choco V2 uses Search" do
|
97
|
-
allow(provider).to receive(:powershell_exec!).with("#{choco_exe}
|
100
|
+
allow(provider).to receive(:powershell_exec!).with("Get-ItemProperty #{choco_exe} | select-object -expandproperty versioninfo | select-object -expandproperty productversion").and_return(double(result: "2.1.0"))
|
98
101
|
expect(provider.query_command).to eql("search")
|
99
102
|
end
|
100
103
|
end
|
@@ -168,6 +171,7 @@ describe Chef::Provider::Package::Chocolatey, :windows_only do
|
|
168
171
|
|
169
172
|
it "should load and downcase names in the installed_packages hash (with disk provider)" do
|
170
173
|
new_resource.use_choco_list(false)
|
174
|
+
provider.invalidate_cache
|
171
175
|
provider.load_current_resource
|
172
176
|
expect(provider.send(:installed_packages)).to eql(
|
173
177
|
{ "chocolatey" => "0.9.9.11", "conemu" => "15.10.25.0" }
|
@@ -176,9 +180,10 @@ describe Chef::Provider::Package::Chocolatey, :windows_only do
|
|
176
180
|
|
177
181
|
it "should load and downcase names in the installed_packages hash (with choco list provider)" do
|
178
182
|
new_resource.use_choco_list(true)
|
183
|
+
provider.invalidate_cache
|
179
184
|
provider.load_current_resource
|
180
185
|
expect(provider.send(:installed_packages)).to eql(
|
181
|
-
{ "chocolatey" => "0.9.9.
|
186
|
+
{ "chocolatey" => "0.9.9.12", "conemu" => "15.10.25.2" }
|
182
187
|
)
|
183
188
|
end
|
184
189
|
|
@@ -106,27 +106,27 @@ describe Chef::Provider::Package::Windows, :windows_only do
|
|
106
106
|
provider.package_provider
|
107
107
|
end
|
108
108
|
|
109
|
-
it "sets the package provider to MSI if the
|
109
|
+
it "sets the package provider to MSI if the installer type is :msi" do
|
110
110
|
allow(provider).to receive(:installer_type).and_return(:msi)
|
111
111
|
expect(provider.package_provider).to be_a(Chef::Provider::Package::Windows::MSI)
|
112
112
|
end
|
113
113
|
|
114
|
-
it "sets the package provider to Exe if the
|
114
|
+
it "sets the package provider to Exe if the installer type is :inno" do
|
115
115
|
allow(provider).to receive(:installer_type).and_return(:inno)
|
116
116
|
expect(provider.package_provider).to be_a(Chef::Provider::Package::Windows::Exe)
|
117
117
|
end
|
118
118
|
|
119
|
-
it "sets the package provider to Exe if the
|
119
|
+
it "sets the package provider to Exe if the installer type is :nsis" do
|
120
120
|
allow(provider).to receive(:installer_type).and_return(:nsis)
|
121
121
|
expect(provider.package_provider).to be_a(Chef::Provider::Package::Windows::Exe)
|
122
122
|
end
|
123
123
|
|
124
|
-
it "sets the package provider to Exe if the
|
124
|
+
it "sets the package provider to Exe if the installer type is :wise" do
|
125
125
|
allow(provider).to receive(:installer_type).and_return(:wise)
|
126
126
|
expect(provider.package_provider).to be_a(Chef::Provider::Package::Windows::Exe)
|
127
127
|
end
|
128
128
|
|
129
|
-
it "sets the package provider to Exe if the
|
129
|
+
it "sets the package provider to Exe if the installer type is :installshield" do
|
130
130
|
allow(provider).to receive(:installer_type).and_return(:installshield)
|
131
131
|
expect(provider.package_provider).to be_a(Chef::Provider::Package::Windows::Exe)
|
132
132
|
end
|