chef 14.12.9 → 14.13.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -9
  3. data/lib/chef/chef_fs/command_line.rb +11 -12
  4. data/lib/chef/deprecated.rb +3 -3
  5. data/lib/chef/dsl/data_query.rb +22 -4
  6. data/lib/chef/dsl/recipe.rb +1 -7
  7. data/lib/chef/dsl/universal.rb +6 -0
  8. data/lib/chef/file_access_control/windows.rb +5 -3
  9. data/lib/chef/knife.rb +3 -3
  10. data/lib/chef/knife/bootstrap.rb +1 -1
  11. data/lib/chef/knife/bootstrap/templates/chef-full.erb +2 -1
  12. data/lib/chef/knife/config_list_profiles.rb +1 -1
  13. data/lib/chef/knife/core/status_presenter.rb +9 -2
  14. data/lib/chef/mixin/template.rb +14 -9
  15. data/lib/chef/node_map.rb +5 -24
  16. data/lib/chef/provider/cron.rb +14 -2
  17. data/lib/chef/provider/file.rb +1 -1
  18. data/lib/chef/provider/service/insserv.rb +3 -1
  19. data/lib/chef/resource.rb +3 -10
  20. data/lib/chef/resource/windows_feature_powershell.rb +1 -1
  21. data/lib/chef/resource_collection.rb +3 -2
  22. data/lib/chef/shell.rb +1 -0
  23. data/lib/chef/version.rb +1 -1
  24. data/lib/chef/win32/api/security.rb +2 -0
  25. data/lib/chef/win32/file.rb +8 -0
  26. data/lib/chef/win32/security.rb +1 -1
  27. data/spec/data/templates/failed.erb +5 -0
  28. data/spec/functional/assets/inittest +36 -0
  29. data/spec/functional/resource/insserv_spec.rb +205 -0
  30. data/spec/functional/resource/link_spec.rb +2 -2
  31. data/spec/spec_helper.rb +1 -0
  32. data/spec/support/platform_helpers.rb +4 -0
  33. data/spec/support/shared/functional/directory_resource.rb +12 -10
  34. data/spec/support/shared/functional/file_resource.rb +2 -2
  35. data/spec/support/shared/functional/securable_resource.rb +102 -71
  36. data/spec/support/shared/unit/provider/file.rb +1 -0
  37. data/spec/unit/knife/bootstrap_spec.rb +22 -0
  38. data/spec/unit/knife_spec.rb +8 -5
  39. data/spec/unit/mixin/template_spec.rb +45 -0
  40. data/spec/unit/node_map_spec.rb +10 -43
  41. data/spec/unit/provider/cron_spec.rb +123 -20
  42. data/spec/unit/provider/service/insserv_service_spec.rb +2 -2
  43. data/spec/unit/resource_collection_spec.rb +8 -0
  44. data/spec/unit/resource_spec.rb +1 -13
  45. data/spec/unit/win32/security_spec.rb +25 -0
  46. metadata +7 -4
@@ -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
- if Dir.glob("/etc/rc**/S*#{Chef::Util::PathHelper.escape_glob_dir(current_resource.service_name)}").empty?
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
@@ -1166,10 +1166,9 @@ class Chef
1166
1166
 
1167
1167
  # Set or return if this resource is in preview mode.
1168
1168
  #
1169
- # This is used in Chef core as part of the process of migrating resources
1170
- # from a cookbook into core. It should be set to `true` when a cookbook
1171
- # resource is added to core, and then removed (set to `false`) in the next
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=\"InstallState\"; Expression = {If ($_.Installed) { 1 } Else { 0 }}} | ConvertTo-Json -Compress', timeout: new_resource.timeout).stdout
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
@@ -60,8 +60,9 @@ class Chef
60
60
  end
61
61
 
62
62
  def delete(key)
63
- resource_list.delete(key)
64
- resource_set.delete(key)
63
+ res = resource_set.delete(key)
64
+ resource_list.delete(res.to_s)
65
+ res
65
66
  end
66
67
 
67
68
  # @deprecated
@@ -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
 
@@ -23,7 +23,7 @@ require "chef/version_string"
23
23
 
24
24
  class Chef
25
25
  CHEF_ROOT = File.expand_path("../..", __FILE__)
26
- VERSION = Chef::VersionString.new("14.12.9")
26
+ VERSION = Chef::VersionString.new("14.13.11")
27
27
  end
28
28
 
29
29
  #
@@ -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
@@ -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
@@ -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 != ERROR_INSUFFICIENT_BUFFER
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,5 @@
1
+ This is a template
2
+
3
+ Which includes some content
4
+
5
+ And will fail <%= nil[] %>
@@ -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
 
@@ -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?
@@ -175,6 +175,10 @@ def rhel6?
175
175
  rhel? && !!(ohai[:platform_version].to_i == 6)
176
176
  end
177
177
 
178
+ def sles11?
179
+ suse? && !!(ohai[:platform_version].to_i == 11)
180
+ end
181
+
178
182
  def rhel7?
179
183
  rhel? && !!(ohai[:platform_version].to_i == 7)
180
184
  end
@@ -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
- ACE.access_allowed(sid, expected_perms[:specific]),
71
- ACE.access_allowed(sid, expected_perms[:generic], (Chef::ReservedNames::Win32::API::Security::INHERIT_ONLY_ACE | Chef::ReservedNames::Win32::API::Security::CONTAINER_INHERIT_ACE | Chef::ReservedNames::Win32::API::Security::OBJECT_INHERIT_ACE)),
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
- ACE.access_denied(sid, expected_perms[:specific]),
78
- ACE.access_denied(sid, expected_perms[:generic], (Chef::ReservedNames::Win32::API::Security::INHERIT_ONLY_ACE | Chef::ReservedNames::Win32::API::Security::CONTAINER_INHERIT_ACE | Chef::ReservedNames::Win32::API::Security::OBJECT_INHERIT_ACE)),
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