chef 14.12.9 → 14.13.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -9
- data/lib/chef/chef_fs/command_line.rb +11 -12
- data/lib/chef/deprecated.rb +3 -3
- data/lib/chef/dsl/data_query.rb +22 -4
- data/lib/chef/dsl/recipe.rb +1 -7
- data/lib/chef/dsl/universal.rb +6 -0
- data/lib/chef/file_access_control/windows.rb +5 -3
- data/lib/chef/knife.rb +3 -3
- data/lib/chef/knife/bootstrap.rb +1 -1
- data/lib/chef/knife/bootstrap/templates/chef-full.erb +2 -1
- data/lib/chef/knife/config_list_profiles.rb +1 -1
- data/lib/chef/knife/core/status_presenter.rb +9 -2
- data/lib/chef/mixin/template.rb +14 -9
- data/lib/chef/node_map.rb +5 -24
- data/lib/chef/provider/cron.rb +14 -2
- data/lib/chef/provider/file.rb +1 -1
- data/lib/chef/provider/service/insserv.rb +3 -1
- data/lib/chef/resource.rb +3 -10
- data/lib/chef/resource/windows_feature_powershell.rb +1 -1
- data/lib/chef/resource_collection.rb +3 -2
- data/lib/chef/shell.rb +1 -0
- data/lib/chef/version.rb +1 -1
- data/lib/chef/win32/api/security.rb +2 -0
- data/lib/chef/win32/file.rb +8 -0
- data/lib/chef/win32/security.rb +1 -1
- data/spec/data/templates/failed.erb +5 -0
- data/spec/functional/assets/inittest +36 -0
- data/spec/functional/resource/insserv_spec.rb +205 -0
- data/spec/functional/resource/link_spec.rb +2 -2
- data/spec/spec_helper.rb +1 -0
- data/spec/support/platform_helpers.rb +4 -0
- data/spec/support/shared/functional/directory_resource.rb +12 -10
- data/spec/support/shared/functional/file_resource.rb +2 -2
- data/spec/support/shared/functional/securable_resource.rb +102 -71
- data/spec/support/shared/unit/provider/file.rb +1 -0
- data/spec/unit/knife/bootstrap_spec.rb +22 -0
- data/spec/unit/knife_spec.rb +8 -5
- data/spec/unit/mixin/template_spec.rb +45 -0
- data/spec/unit/node_map_spec.rb +10 -43
- data/spec/unit/provider/cron_spec.rb +123 -20
- data/spec/unit/provider/service/insserv_service_spec.rb +2 -2
- data/spec/unit/resource_collection_spec.rb +8 -0
- data/spec/unit/resource_spec.rb +1 -13
- data/spec/unit/win32/security_spec.rb +25 -0
- metadata +7 -4
data/lib/chef/provider/file.rb
CHANGED
@@ -227,7 +227,7 @@ class Chef
|
|
227
227
|
elsif file_class.symlink?(path) && new_resource.manage_symlink_source
|
228
228
|
verify_symlink_sanity(path)
|
229
229
|
elsif file_class.symlink?(new_resource.path) && new_resource.manage_symlink_source.nil?
|
230
|
-
logger.warn("File #{path} managed by #{new_resource} is really a symlink. Managing the source file instead.")
|
230
|
+
logger.warn("File #{path} managed by #{new_resource} is really a symlink (to #{file_class.realpath(new_resource.path)}). Managing the source file instead.")
|
231
231
|
logger.warn("Disable this warning by setting `manage_symlink_source true` on the resource")
|
232
232
|
logger.warn("In a future Chef release, 'manage_symlink_source' will not be enabled by default")
|
233
233
|
verify_symlink_sanity(path)
|
@@ -36,7 +36,9 @@ class Chef
|
|
36
36
|
super
|
37
37
|
|
38
38
|
# Look for a /etc/rc.*/SnnSERVICE link to signify that the service would be started in a runlevel
|
39
|
-
|
39
|
+
service_name = Chef::Util::PathHelper.escape_glob_dir(current_resource.service_name)
|
40
|
+
|
41
|
+
if Dir.glob("/etc/rc*/**/S*#{service_name}").empty?
|
40
42
|
current_resource.enabled false
|
41
43
|
else
|
42
44
|
current_resource.enabled true
|
data/lib/chef/resource.rb
CHANGED
@@ -1166,10 +1166,9 @@ class Chef
|
|
1166
1166
|
|
1167
1167
|
# Set or return if this resource is in preview mode.
|
1168
1168
|
#
|
1169
|
-
# This
|
1170
|
-
#
|
1171
|
-
#
|
1172
|
-
# major release.
|
1169
|
+
# This only has value in the resource_inspector to mark a resource as being new-to-chef-core.
|
1170
|
+
# Its meaning is probably more equivalent to "experimental" in that the API might change even
|
1171
|
+
# in minor versions due to bugfixing and is NOT considered "stable" yet.
|
1173
1172
|
#
|
1174
1173
|
# @param value [nil, Boolean] If nil, get the current value. If not nil, set
|
1175
1174
|
# the value of the flag.
|
@@ -1346,12 +1345,6 @@ class Chef
|
|
1346
1345
|
remove_canonical_dsl
|
1347
1346
|
end
|
1348
1347
|
|
1349
|
-
# If a resource is in preview mode, set allow_cookbook_override on all its
|
1350
|
-
# mappings by default.
|
1351
|
-
if preview_resource && !options.include?(:allow_cookbook_override)
|
1352
|
-
options[:allow_cookbook_override] = true
|
1353
|
-
end
|
1354
|
-
|
1355
1348
|
if @chef_version_for_provides && !options.include?(:chef_version)
|
1356
1349
|
options[:chef_version] = @chef_version_for_provides
|
1357
1350
|
end
|
@@ -226,7 +226,7 @@ class Chef
|
|
226
226
|
# Grab raw feature information from dism command line
|
227
227
|
# Windows < 2012 doesn't present a state value so we have to check if the feature is installed or not
|
228
228
|
raw_list_of_features = if older_than_win_2012_or_8? # make the older format look like the new format, warts and all
|
229
|
-
powershell_out!('Get-WindowsFeature | Select-Object -Property Name, @{Name
|
229
|
+
powershell_out!('Get-WindowsFeature | Select-Object -Property Name, @{Name="InstallState"; Expression = {If ($_.Installed) { 1 } Else { 0 }}} | ConvertTo-Json -Compress', timeout: new_resource.timeout).stdout
|
230
230
|
else
|
231
231
|
powershell_out!("Get-WindowsFeature | Select-Object -Property Name,InstallState | ConvertTo-Json -Compress", timeout: new_resource.timeout).stdout
|
232
232
|
end
|
data/lib/chef/shell.rb
CHANGED
@@ -214,6 +214,7 @@ module Shell
|
|
214
214
|
* If no chef_shell.rb can be found, chef-shell falls back to load:
|
215
215
|
/etc/chef/client.rb if -z option is given.
|
216
216
|
/etc/chef/solo.rb if --solo-legacy-mode option is given.
|
217
|
+
.chef/config.rb if -s option is given.
|
217
218
|
.chef/knife.rb if -s option is given.
|
218
219
|
FOOTER
|
219
220
|
|
data/lib/chef/version.rb
CHANGED
@@ -140,6 +140,8 @@ class Chef
|
|
140
140
|
FILE_READ_EA | SYNCHRONIZE
|
141
141
|
FILE_GENERIC_WRITE = STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE
|
142
142
|
FILE_GENERIC_EXECUTE = STANDARD_RIGHTS_EXECUTE | FILE_READ_ATTRIBUTES | FILE_EXECUTE | SYNCHRONIZE
|
143
|
+
WRITE = FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA
|
144
|
+
SUBFOLDERS_AND_FILES_ONLY = INHERIT_ONLY_ACE | CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE
|
143
145
|
# Access Token Rights (for OpenProcessToken)
|
144
146
|
# Access Rights for Access-Token Objects (used in OpenProcessToken)
|
145
147
|
TOKEN_ASSIGN_PRIMARY = 0x0001
|
data/lib/chef/win32/file.rb
CHANGED
@@ -89,6 +89,14 @@ class Chef
|
|
89
89
|
is_symlink
|
90
90
|
end
|
91
91
|
|
92
|
+
def self.realpath(file_name)
|
93
|
+
if symlink?(file_name)
|
94
|
+
readlink(file_name)
|
95
|
+
else
|
96
|
+
file_name
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
92
100
|
# Returns the path of the of the symbolic link referred to by +file+.
|
93
101
|
#
|
94
102
|
# Requires Windows Vista or later. On older versions of Windows it
|
data/lib/chef/win32/security.rb
CHANGED
@@ -404,7 +404,7 @@ class Chef
|
|
404
404
|
system_name = system_name.to_wstring if system_name
|
405
405
|
if LookupAccountNameW(system_name, name.to_wstring, nil, sid_size, nil, referenced_domain_name_size, nil)
|
406
406
|
raise "Expected ERROR_INSUFFICIENT_BUFFER from LookupAccountName, and got no error!"
|
407
|
-
elsif FFI::LastError.error
|
407
|
+
elsif !([NO_ERROR, ERROR_INSUFFICIENT_BUFFER].include?(FFI::LastError.error))
|
408
408
|
Chef::ReservedNames::Win32::Error.raise!
|
409
409
|
end
|
410
410
|
|
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
TMPDIR="${TMPDIR:-/tmp}"
|
4
|
+
|
5
|
+
function create_chef_txt {
|
6
|
+
touch $TMPDIR/inittest.txt
|
7
|
+
}
|
8
|
+
|
9
|
+
function delete_chef_txt {
|
10
|
+
rm $TMPDIR/inittest.txt
|
11
|
+
}
|
12
|
+
|
13
|
+
function rename_chef_txt {
|
14
|
+
mv $TMPDIR/inittest.txt $TMPDIR/$1
|
15
|
+
}
|
16
|
+
|
17
|
+
case "$1" in
|
18
|
+
start )
|
19
|
+
create_chef_txt
|
20
|
+
;;
|
21
|
+
stop )
|
22
|
+
delete_chef_txt
|
23
|
+
;;
|
24
|
+
status )
|
25
|
+
[ -f $TMPDIR/inittest.txt ] || [ -f $TMPDIR/inittest_reload.txt ] || [ -f $TMPDIR/inittest_restart.txt ]
|
26
|
+
;;
|
27
|
+
reload )
|
28
|
+
rename_chef_txt "inittest_reload.txt"
|
29
|
+
;;
|
30
|
+
restart )
|
31
|
+
rename_chef_txt "inittest_restart.txt"
|
32
|
+
;;
|
33
|
+
* )
|
34
|
+
echo "Usage: $0 (start | stop | restart | reload)"
|
35
|
+
exit 1
|
36
|
+
esac
|
@@ -0,0 +1,205 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#
|
3
|
+
# Author:: Dheeraj Dubey (<dheeraj.dubey@msystechnologies.com>)
|
4
|
+
# Copyright:: Copyright 2009-2019, Chef Software, Inc.
|
5
|
+
# License:: Apache License, Version 2.0
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
|
20
|
+
require "spec_helper"
|
21
|
+
require "functional/resource/base"
|
22
|
+
require "chef/mixin/shell_out"
|
23
|
+
require "fileutils"
|
24
|
+
|
25
|
+
describe Chef::Resource::Service, :requires_root, :sles11 do
|
26
|
+
|
27
|
+
include Chef::Mixin::ShellOut
|
28
|
+
|
29
|
+
def service_should_be_enabled
|
30
|
+
expect(shell_out!("/sbin/insserv -r -f #{new_resource.service_name}").exitstatus).to eq(0)
|
31
|
+
expect(shell_out!("/sbin/insserv -d -f #{new_resource.service_name}").exitstatus).to eq(0)
|
32
|
+
!Dir.glob("/etc/rc*/**/S*#{service_name}").empty?
|
33
|
+
end
|
34
|
+
|
35
|
+
def service_should_be_disabled
|
36
|
+
expect(shell_out!("/sbin/insserv -r -f #{new_resource.service_name}").exitstatus).to eq(0)
|
37
|
+
Dir.glob("/etc/rc*/**/S*#{service_name}").empty?
|
38
|
+
end
|
39
|
+
|
40
|
+
# Platform specific validation routines.
|
41
|
+
def service_should_be_started(file_name)
|
42
|
+
# The existence of this file indicates that the service was started.
|
43
|
+
expect(File.exists?("#{Dir.tmpdir}/#{file_name}")).to be_truthy
|
44
|
+
end
|
45
|
+
|
46
|
+
def service_should_be_stopped(file_name)
|
47
|
+
expect(File.exists?("#{Dir.tmpdir}/#{file_name}")).to be_falsey
|
48
|
+
end
|
49
|
+
|
50
|
+
def delete_test_files
|
51
|
+
files = Dir.glob("#{Dir.tmpdir}/init[a-z_]*.txt")
|
52
|
+
File.delete(*files)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Actual tests
|
56
|
+
let(:new_resource) do
|
57
|
+
new_resource = Chef::Resource::Service.new("inittest", run_context)
|
58
|
+
new_resource.provider Chef::Provider::Service::Insserv
|
59
|
+
new_resource.supports({ status: true, restart: true, reload: true })
|
60
|
+
new_resource
|
61
|
+
end
|
62
|
+
|
63
|
+
let(:provider) do
|
64
|
+
provider = new_resource.provider_for_action(new_resource.action)
|
65
|
+
provider
|
66
|
+
end
|
67
|
+
|
68
|
+
let (:service_name) { "Chef::Util::PathHelper.escape_glob_dir(current_resource.service_name)" }
|
69
|
+
|
70
|
+
let(:current_resource) do
|
71
|
+
provider.load_current_resource
|
72
|
+
provider.current_resource
|
73
|
+
end
|
74
|
+
|
75
|
+
before(:all) do
|
76
|
+
File.delete("/etc/init.d/inittest") if File.exists?("/etc/init.d/inittest")
|
77
|
+
FileUtils.cp((File.join(File.dirname(__FILE__), "/../assets/inittest")).to_s, "/etc/init.d/inittest")
|
78
|
+
end
|
79
|
+
|
80
|
+
after(:all) do
|
81
|
+
File.delete("/etc/init.d/inittest") if File.exists?("/etc/init.d/inittest")
|
82
|
+
end
|
83
|
+
|
84
|
+
before(:each) do
|
85
|
+
delete_test_files
|
86
|
+
end
|
87
|
+
|
88
|
+
after(:each) do
|
89
|
+
delete_test_files
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "start service" do
|
93
|
+
it "should start the service" do
|
94
|
+
new_resource.run_action(:start)
|
95
|
+
service_should_be_started("inittest.txt")
|
96
|
+
expect(new_resource).to be_updated_by_last_action
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should be idempotent" do
|
100
|
+
new_resource.run_action(:start)
|
101
|
+
service_should_be_started("inittest.txt")
|
102
|
+
expect(new_resource).to be_updated_by_last_action
|
103
|
+
new_resource.run_action(:start)
|
104
|
+
service_should_be_started("inittest.txt")
|
105
|
+
expect(new_resource).not_to be_updated_by_last_action
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe "stop service" do
|
110
|
+
before do
|
111
|
+
new_resource.run_action(:start)
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should stop the service" do
|
115
|
+
new_resource.run_action(:stop)
|
116
|
+
service_should_be_stopped("inittest.txt")
|
117
|
+
expect(new_resource).to be_updated_by_last_action
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should be idempotent" do
|
121
|
+
new_resource.run_action(:stop)
|
122
|
+
service_should_be_stopped("inittest.txt")
|
123
|
+
expect(new_resource).to be_updated_by_last_action
|
124
|
+
new_resource.run_action(:stop)
|
125
|
+
service_should_be_stopped("inittest.txt")
|
126
|
+
expect(new_resource).not_to be_updated_by_last_action
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe "restart service" do
|
131
|
+
before do
|
132
|
+
new_resource.run_action(:start)
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should restart the service" do
|
136
|
+
new_resource.run_action(:restart)
|
137
|
+
service_should_be_started("inittest_restart.txt")
|
138
|
+
expect(new_resource).to be_updated_by_last_action
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should be idempotent" do
|
142
|
+
skip "FIXME: restart is not idempotent"
|
143
|
+
new_resource.run_action(:restart)
|
144
|
+
service_should_be_disabled
|
145
|
+
expect(new_resource).to be_updated_by_last_action
|
146
|
+
new_resource.run_action(:restart)
|
147
|
+
service_should_be_disabled
|
148
|
+
expect(new_resource).not_to be_updated_by_last_action
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
describe "reload service" do
|
153
|
+
before do
|
154
|
+
new_resource.run_action(:start)
|
155
|
+
end
|
156
|
+
|
157
|
+
it "should reload the service" do
|
158
|
+
new_resource.run_action(:reload)
|
159
|
+
service_should_be_started("inittest_reload.txt")
|
160
|
+
expect(new_resource).to be_updated_by_last_action
|
161
|
+
end
|
162
|
+
|
163
|
+
it "should be idempotent" do
|
164
|
+
skip "FIXME: reload is not idempotent"
|
165
|
+
new_resource.run_action(:reload)
|
166
|
+
service_should_be_disabled
|
167
|
+
expect(new_resource).to be_updated_by_last_action
|
168
|
+
new_resource.run_action(:reload)
|
169
|
+
service_should_be_disabled
|
170
|
+
expect(new_resource).not_to be_updated_by_last_action
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
describe "enable service" do
|
175
|
+
it "should enable the service" do
|
176
|
+
new_resource.run_action(:enable)
|
177
|
+
service_should_be_enabled
|
178
|
+
expect(new_resource).to be_updated_by_last_action
|
179
|
+
end
|
180
|
+
|
181
|
+
it "should be idempotent" do
|
182
|
+
new_resource.run_action(:enable)
|
183
|
+
service_should_be_enabled
|
184
|
+
new_resource.run_action(:enable)
|
185
|
+
service_should_be_enabled
|
186
|
+
expect(new_resource).not_to be_updated_by_last_action
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
describe "disable_service" do
|
191
|
+
it "should disable the service" do
|
192
|
+
new_resource.run_action(:disable)
|
193
|
+
service_should_be_disabled
|
194
|
+
expect(new_resource).to be_updated_by_last_action
|
195
|
+
end
|
196
|
+
|
197
|
+
it "should be idempotent" do
|
198
|
+
new_resource.run_action(:disable)
|
199
|
+
service_should_be_disabled
|
200
|
+
new_resource.run_action(:disable)
|
201
|
+
service_should_be_disabled
|
202
|
+
expect(new_resource).not_to be_updated_by_last_action
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
@@ -417,11 +417,11 @@ describe Chef::Resource::Link do
|
|
417
417
|
|
418
418
|
it_behaves_like "a securable resource without existing target" do
|
419
419
|
let(:path) { target_file }
|
420
|
-
def allowed_acl(sid, expected_perms)
|
420
|
+
def allowed_acl(sid, expected_perms, _flags = 0)
|
421
421
|
[ ACE.access_allowed(sid, expected_perms[:specific]) ]
|
422
422
|
end
|
423
423
|
|
424
|
-
def denied_acl(sid, expected_perms)
|
424
|
+
def denied_acl(sid, expected_perms, _flags = 0)
|
425
425
|
[ ACE.access_denied(sid, expected_perms[:specific]) ]
|
426
426
|
end
|
427
427
|
|
data/spec/spec_helper.rb
CHANGED
@@ -172,6 +172,7 @@ RSpec.configure do |config|
|
|
172
172
|
config.filter_run_excluding linux_only: true unless linux?
|
173
173
|
config.filter_run_excluding aix_only: true unless aix?
|
174
174
|
config.filter_run_excluding suse_only: true unless suse?
|
175
|
+
config.filter_run_excluding sles11: true unless sles11?
|
175
176
|
config.filter_run_excluding debian_family_only: true unless debian_family?
|
176
177
|
config.filter_run_excluding supports_cloexec: true unless supports_cloexec?
|
177
178
|
config.filter_run_excluding selinux_only: true unless selinux_enabled?
|
@@ -65,18 +65,20 @@ shared_examples_for "a directory resource" do
|
|
65
65
|
end
|
66
66
|
|
67
67
|
# Set up the context for security tests
|
68
|
-
def allowed_acl(sid, expected_perms)
|
69
|
-
[
|
70
|
-
|
71
|
-
|
72
|
-
|
68
|
+
def allowed_acl(sid, expected_perms, flags = 0)
|
69
|
+
acl = [ ACE.access_allowed(sid, expected_perms[:specific], flags) ]
|
70
|
+
if expected_perms[:generic]
|
71
|
+
acl << ACE.access_allowed(sid, expected_perms[:generic], (Chef::ReservedNames::Win32::API::Security::SUBFOLDERS_AND_FILES_ONLY))
|
72
|
+
end
|
73
|
+
acl
|
73
74
|
end
|
74
75
|
|
75
|
-
def denied_acl(sid, expected_perms)
|
76
|
-
[
|
77
|
-
|
78
|
-
|
79
|
-
|
76
|
+
def denied_acl(sid, expected_perms, flags = 0)
|
77
|
+
acl = [ ACE.access_denied(sid, expected_perms[:specific], flags) ]
|
78
|
+
if expected_perms[:generic]
|
79
|
+
acl << ACE.access_denied(sid, expected_perms[:generic], (Chef::ReservedNames::Win32::API::Security::SUBFOLDERS_AND_FILES_ONLY))
|
80
|
+
end
|
81
|
+
acl
|
80
82
|
end
|
81
83
|
|
82
84
|
def parent_inheritable_acls
|
@@ -899,11 +899,11 @@ shared_examples_for "a configured file resource" do
|
|
899
899
|
end
|
900
900
|
|
901
901
|
# Set up the context for security tests
|
902
|
-
def allowed_acl(sid, expected_perms)
|
902
|
+
def allowed_acl(sid, expected_perms, _flags = 0)
|
903
903
|
[ ACE.access_allowed(sid, expected_perms[:specific]) ]
|
904
904
|
end
|
905
905
|
|
906
|
-
def denied_acl(sid, expected_perms)
|
906
|
+
def denied_acl(sid, expected_perms, _flags = 0)
|
907
907
|
[ ACE.access_denied(sid, expected_perms[:specific]) ]
|
908
908
|
end
|
909
909
|
|