chef 11.14.6-x86-mingw32 → 11.16.0-x86-mingw32

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.
@@ -0,0 +1,46 @@
1
+ #
2
+ # Author:: Adam Edwards (<adamed@getchef.com>)
3
+ #
4
+ # Copyright:: Copyright (c) 2014 Chef Software, Inc.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'json'
20
+
21
+ class Chef::Util::Powershell
22
+ class CmdletResult
23
+ attr_reader :output_format
24
+
25
+ def initialize(status, output_format)
26
+ @status = status
27
+ @output_format = output_format
28
+ end
29
+
30
+ def stderr
31
+ @status.stderr
32
+ end
33
+
34
+ def return_value
35
+ if output_format == :object
36
+ JSON.parse(@status.stdout)
37
+ else
38
+ @status.stdout
39
+ end
40
+ end
41
+
42
+ def succeeded?
43
+ @succeeded = @status.status.exitstatus == 0
44
+ end
45
+ end
46
+ end
@@ -17,7 +17,7 @@
17
17
 
18
18
  class Chef
19
19
  CHEF_ROOT = File.dirname(File.expand_path(File.dirname(__FILE__)))
20
- VERSION = '11.14.6'
20
+ VERSION = '11.16.0'
21
21
  end
22
22
 
23
23
  # NOTE: the Chef::Version class is defined in version_class.rb
@@ -0,0 +1,337 @@
1
+ #
2
+ # Author:: Adam Edwards (<adamed@getchef.com>)
3
+ # Copyright:: Copyright (c) 2014 Chef Software, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'spec_helper'
20
+ require 'chef/mixin/shell_out'
21
+ require 'chef/mixin/windows_architecture_helper'
22
+
23
+ describe Chef::Resource::DscScript, :windows_powershell_dsc_only do
24
+ include Chef::Mixin::WindowsArchitectureHelper
25
+ before(:all) do
26
+ @temp_dir = ::Dir.mktmpdir("dsc-functional-test")
27
+ end
28
+
29
+ after(:all) do
30
+ ::FileUtils.rm_rf(@temp_dir) if ::Dir.exist?(@temp_dir)
31
+ end
32
+
33
+ include Chef::Mixin::ShellOut
34
+
35
+ def create_config_script_from_code(code, configuration_name, data = false)
36
+ script_code = data ? code : "Configuration '#{configuration_name}'\n{\n\t#{code}\n}\n"
37
+ data_suffix = data ? '_config_data' : ''
38
+ extension = data ? 'psd1' : 'ps1'
39
+ script_path = "#{@temp_dir}/dsc_functional_test#{data_suffix}.#{extension}"
40
+ ::File.open(script_path, 'wt') do | script |
41
+ script.write(script_code)
42
+ end
43
+ script_path
44
+ end
45
+
46
+ def user_exists?(target_user)
47
+ result = false
48
+ begin
49
+ shell_out!("net user #{target_user}")
50
+ result = true
51
+ rescue Mixlib::ShellOut::ShellCommandFailed
52
+ end
53
+ result
54
+ end
55
+
56
+ def delete_user(target_user)
57
+ begin
58
+ shell_out!("net user #{target_user} /delete")
59
+ rescue Mixlib::ShellOut::ShellCommandFailed
60
+ end
61
+ end
62
+
63
+ let(:dsc_env_variable) { 'chefenvtest' }
64
+ let(:dsc_env_value1) { 'value1' }
65
+ let(:env_value2) { 'value2' }
66
+ let(:dsc_test_run_context) {
67
+ node = Chef::Node.new
68
+ node.automatic['platform'] = 'windows'
69
+ node.automatic['platform_version'] = '6.1'
70
+ node.automatic['kernel'][:machine] =
71
+ is_i386_process_on_x86_64_windows? ? :x86_64 : :i386
72
+ node.automatic[:languages][:powershell][:version] = '4.0'
73
+ empty_events = Chef::EventDispatch::Dispatcher.new
74
+ Chef::RunContext.new(node, {}, empty_events)
75
+ }
76
+ let(:dsc_test_resource_name) { 'DSCTest' }
77
+ let(:dsc_test_resource_base) {
78
+ Chef::Resource::DscScript.new(dsc_test_resource_name, dsc_test_run_context)
79
+ }
80
+ let(:test_registry_key) { 'HKEY_LOCAL_MACHINE\Software\Chef\Spec\Functional\Resource\dsc_script_spec' }
81
+ let(:test_registry_value) { 'Registration' }
82
+ let(:test_registry_data1) { 'LL927' }
83
+ let(:test_registry_data2) { 'LL928' }
84
+ let(:dsc_code) { <<-EOH
85
+ Registry "ChefRegKey"
86
+ {
87
+ Key = '#{test_registry_key}'
88
+ ValueName = '#{test_registry_value}'
89
+ ValueData = '#{test_registry_data}'
90
+ Ensure = 'Present'
91
+ }
92
+ EOH
93
+ }
94
+
95
+ let(:dsc_user_prefix) { 'dsc' }
96
+ let(:dsc_user_suffix) { 'chefx' }
97
+ let(:dsc_user) {"#{dsc_user_prefix}_usr_#{dsc_user_suffix}" }
98
+ let(:dsc_user_prefix_env_var_name) { 'dsc_user_env_prefix' }
99
+ let(:dsc_user_suffix_env_var_name) { 'dsc_user_env_suffix' }
100
+ let(:dsc_user_prefix_env_code) { "$env:#{dsc_user_prefix_env_var_name}"}
101
+ let(:dsc_user_suffix_env_code) { "$env:#{dsc_user_suffix_env_var_name}"}
102
+ let(:dsc_user_prefix_param_name) { 'dsc_user_prefix_param' }
103
+ let(:dsc_user_suffix_param_name) { 'dsc_user_suffix_param' }
104
+ let(:dsc_user_prefix_param_code) { "$#{dsc_user_prefix_param_name}"}
105
+ let(:dsc_user_suffix_param_code) { "$#{dsc_user_suffix_param_name}"}
106
+ let(:dsc_user_env_code) { "\"$(#{dsc_user_prefix_env_code})_usr_$(#{dsc_user_suffix_env_code})\""}
107
+ let(:dsc_user_param_code) { "\"$(#{dsc_user_prefix_param_code})_usr_$(#{dsc_user_suffix_param_code})\""}
108
+
109
+ let(:config_flags) { nil }
110
+ let(:config_params) { <<-EOH
111
+
112
+ [CmdletBinding()]
113
+ param
114
+ (
115
+ $#{dsc_user_prefix_param_name},
116
+ $#{dsc_user_suffix_param_name}
117
+ )
118
+ EOH
119
+ }
120
+
121
+ let(:config_param_section) { '' }
122
+ let(:dsc_user_code) { "'#{dsc_user}'" }
123
+ let(:dsc_user_prefix_code) { dsc_user_prefix }
124
+ let(:dsc_user_suffix_code) { dsc_user_suffix }
125
+ let(:dsc_script_environment_attribute) { nil }
126
+ let(:dsc_user_resources_code) { <<-EOH
127
+ #{config_param_section}
128
+ node localhost
129
+ {
130
+ $testuser = #{dsc_user_code}
131
+ $testpassword = ConvertTo-SecureString -String "jf9a8m49jrajf4#" -AsPlainText -Force
132
+ $testcred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $testuser, $testpassword
133
+
134
+ User dsctestusercreate
135
+ {
136
+ UserName = $testuser
137
+ Password = $testcred
138
+ Description = "DSC test user"
139
+ Ensure = "Present"
140
+ Disabled = $false
141
+ PasswordNeverExpires = $true
142
+ PasswordChangeRequired = $false
143
+ }
144
+ }
145
+ EOH
146
+ }
147
+
148
+ let(:dsc_user_config_data) {
149
+ <<-EOH
150
+ @{
151
+ AllNodes = @(
152
+ @{
153
+ NodeName = "localhost";
154
+ PSDscAllowPlainTextPassword = $true
155
+ }
156
+ )
157
+ }
158
+
159
+ EOH
160
+ }
161
+
162
+ let(:dsc_environment_env_var_name) { 'dsc_test_cwd' }
163
+ let(:dsc_environment_no_fail_not_etc_directory) { "#{ENV['systemroot']}\\system32" }
164
+ let(:dsc_environment_fail_etc_directory) { "#{ENV['systemroot']}\\system32\\drivers\\etc" }
165
+ let(:exception_message_signature) { 'LL927-LL928' }
166
+ let(:dsc_environment_config) {<<-EOH
167
+ if (($pwd.path -eq '#{dsc_environment_fail_etc_directory}') -and (test-path('#{dsc_environment_fail_etc_directory}')))
168
+ {
169
+ throw 'Signature #{exception_message_signature}: Purposefully failing because cwd == #{dsc_environment_fail_etc_directory}'
170
+ }
171
+ environment "whatsmydir"
172
+ {
173
+ Name = '#{dsc_environment_env_var_name}'
174
+ Value = $pwd.path
175
+ Ensure = 'Present'
176
+ }
177
+ EOH
178
+ }
179
+
180
+ let(:dsc_config_name) {
181
+ dsc_test_resource_base.name
182
+ }
183
+ let(:dsc_resource_from_code) {
184
+ dsc_test_resource_base.code(dsc_code)
185
+ dsc_test_resource_base
186
+ }
187
+ let(:config_name_value) { dsc_test_resource_base.name }
188
+
189
+ let(:dsc_resource_from_path) {
190
+ dsc_test_resource_base.command(create_config_script_from_code(dsc_code, config_name_value))
191
+ dsc_test_resource_base
192
+ }
193
+
194
+ before(:each) do
195
+ test_key_resource = Chef::Resource::RegistryKey.new(test_registry_key, dsc_test_run_context)
196
+ test_key_resource.recursive(true)
197
+ test_key_resource.run_action(:delete_key)
198
+ end
199
+
200
+ after(:each) do
201
+ test_key_resource = Chef::Resource::RegistryKey.new(test_registry_key, dsc_test_run_context)
202
+ test_key_resource.recursive(true)
203
+ test_key_resource.run_action(:delete_key)
204
+ end
205
+
206
+ shared_examples_for 'a dsc_script resource with specified PowerShell configuration code' do
207
+ let(:test_registry_data) { test_registry_data1 }
208
+ it 'should create a registry key with a specific registry value and data' do
209
+ expect(dsc_test_resource.registry_key_exists?(test_registry_key)).to eq(false)
210
+ dsc_test_resource.run_action(:run)
211
+ expect(dsc_test_resource.registry_key_exists?(test_registry_key)).to eq(true)
212
+ expect(dsc_test_resource.registry_value_exists?(test_registry_key, {:name => test_registry_value, :type => :string, :data => test_registry_data})).to eq(true)
213
+ end
214
+
215
+ it_should_behave_like 'a dsc_script resource with configuration affected by cwd'
216
+ end
217
+
218
+ shared_examples_for 'a dsc_script resource with configuration affected by cwd' do
219
+ after(:each) do
220
+ removal_resource = Chef::Resource::DscScript.new(dsc_test_resource_name, dsc_test_run_context)
221
+ removal_resource.code <<-EOH
222
+ environment 'removethis'
223
+ {
224
+ Name = '#{dsc_environment_env_var_name}'
225
+ Ensure = 'Absent'
226
+ }
227
+ EOH
228
+ removal_resource.run_action(:run)
229
+ end
230
+ let(:dsc_code) { dsc_environment_config }
231
+ it 'should not raise an exception if the cwd is not etc' do
232
+ dsc_test_resource.cwd(dsc_environment_no_fail_not_etc_directory)
233
+ expect {dsc_test_resource.run_action(:run)}.not_to raise_error
234
+ end
235
+
236
+ it 'should raise an exception if the cwd is etc' do
237
+ dsc_test_resource.cwd(dsc_environment_fail_etc_directory)
238
+ expect {dsc_test_resource.run_action(:run)}.to raise_error(Chef::Exceptions::PowershellCmdletException)
239
+ begin
240
+ dsc_test_resource.run_action(:run)
241
+ rescue Chef::Exceptions::PowershellCmdletException => e
242
+ expect(e.message).to match(exception_message_signature)
243
+ end
244
+ end
245
+ end
246
+
247
+ shared_examples_for 'a parameterized DSC configuration script' do
248
+ context 'when specifying environment variables in the environment attribute' do
249
+ let(:dsc_user_prefix_code) { dsc_user_prefix_env_code }
250
+ let(:dsc_user_suffix_code) { dsc_user_suffix_env_code }
251
+ it_behaves_like 'a dsc_script with configuration that uses environment variables'
252
+ end
253
+ end
254
+
255
+ shared_examples_for 'a dsc_script with configuration data' do
256
+ context 'when using the configuration_data attribute' do
257
+ let(:configuration_data_attribute) { 'configuration_data' }
258
+ it_behaves_like 'a dsc_script with configuration data set via an attribute'
259
+ end
260
+
261
+ context 'when using the configuration_data_script attribute' do
262
+ let(:configuration_data_attribute) { 'configuration_data_script' }
263
+ it_behaves_like 'a dsc_script with configuration data set via an attribute'
264
+ end
265
+ end
266
+
267
+ shared_examples_for 'a dsc_script with configuration data set via an attribute' do
268
+ it 'should run a configuration script that creates a user' do
269
+ config_data_value = dsc_user_config_data
270
+ dsc_test_resource.configuration_name(config_name_value)
271
+ if configuration_data_attribute == 'configuration_data_script'
272
+ config_data_value = create_config_script_from_code(dsc_user_config_data, '', true)
273
+ end
274
+ dsc_test_resource.environment({dsc_user_prefix_env_var_name => dsc_user_prefix,
275
+ dsc_user_suffix_env_var_name => dsc_user_suffix})
276
+ dsc_test_resource.send(configuration_data_attribute, config_data_value)
277
+ dsc_test_resource.flags(config_flags)
278
+ expect(user_exists?(dsc_user)).to eq(false)
279
+ expect {dsc_test_resource.run_action(:run)}.not_to raise_error
280
+ expect(user_exists?(dsc_user)).to eq(true)
281
+ end
282
+ end
283
+
284
+ shared_examples_for 'a dsc_script with configuration data that takes parameters' do
285
+ context 'when script code takes parameters for configuration' do
286
+ let(:dsc_user_code) { dsc_user_param_code }
287
+ let(:config_param_section) { config_params }
288
+ let(:config_flags) {{:"#{dsc_user_prefix_param_name}" => "#{dsc_user_prefix}", :"#{dsc_user_suffix_param_name}" => "#{dsc_user_suffix}"}}
289
+ it 'does not directly contain the user name' do
290
+ configuration_script_content = ::File.open(dsc_test_resource.command) do | file |
291
+ file.read
292
+ end
293
+ expect(configuration_script_content.include?(dsc_user)).to be(false)
294
+ end
295
+ it_behaves_like 'a dsc_script with configuration data'
296
+ end
297
+
298
+ end
299
+
300
+ shared_examples_for 'a dsc_script with configuration data that uses environment variables' do
301
+ context 'when script code uses environment variables' do
302
+ let(:dsc_user_code) { dsc_user_env_code }
303
+
304
+ it 'does not directly contain the user name' do
305
+ configuration_script_content = ::File.open(dsc_test_resource.command) do | file |
306
+ file.read
307
+ end
308
+ expect(configuration_script_content.include?(dsc_user)).to be(false)
309
+ end
310
+ it_behaves_like 'a dsc_script with configuration data'
311
+ end
312
+ end
313
+
314
+ context 'when supplying configuration through the configuration attribute' do
315
+ let(:dsc_test_resource) { dsc_resource_from_code }
316
+ it_behaves_like 'a dsc_script resource with specified PowerShell configuration code'
317
+ end
318
+
319
+ context 'when supplying configuration using the path attribute' do
320
+ let(:dsc_test_resource) { dsc_resource_from_path }
321
+ it_behaves_like 'a dsc_script resource with specified PowerShell configuration code'
322
+ end
323
+
324
+ context 'when running a configuration that manages users' do
325
+ before(:each) do
326
+ delete_user(dsc_user)
327
+ end
328
+
329
+ let(:dsc_code) { dsc_user_resources_code }
330
+ let(:config_name_value) { 'DSCTestConfig' }
331
+ let(:dsc_test_resource) { dsc_resource_from_path }
332
+
333
+ it_behaves_like 'a dsc_script with configuration data'
334
+ it_behaves_like 'a dsc_script with configuration data that uses environment variables'
335
+ it_behaves_like 'a dsc_script with configuration data that takes parameters'
336
+ end
337
+ end
@@ -40,6 +40,11 @@ describe Chef::Resource::Group, :requires_root_or_running_windows, :not_supporte
40
40
  when "windows"
41
41
  user_sid = sid_string_from_user(user)
42
42
  user_sid.nil? ? false : Chef::Util::Windows::NetGroup.new(group_name).local_get_members.include?(user_sid)
43
+ when "mac_os_x"
44
+ membership_info = shell_out("dscl . -read /Groups/#{group_name}").stdout
45
+ members = membership_info.split(" ")
46
+ members.shift # Get rid of GroupMembership: string
47
+ members.include?(user)
43
48
  else
44
49
  Etc::getgrnam(group_name).mem.include?(user)
45
50
  end
@@ -420,4 +425,3 @@ downthestreetalwayshadagoodsmileonhisfacetheoldmanwalkingdownthestreeQQQQQQ" }
420
425
  end
421
426
  end
422
427
  end
423
-
@@ -0,0 +1,114 @@
1
+ #
2
+ # Author:: Adam Edwards (<adamed@getchef.com>)
3
+ #
4
+ # Copyright:: 2014, Chef Software, Inc.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'json'
20
+ require File.expand_path('../../../../spec_helper', __FILE__)
21
+
22
+ describe Chef::Util::Powershell::Cmdlet, :windows_only do
23
+ before(:all) do
24
+ ohai = Ohai::System.new
25
+ ohai.load_plugins
26
+ ohai.run_plugins(true, ['platform', 'kernel'])
27
+ @node = Chef::Node.new
28
+ @node.consume_external_attrs(ohai.data, {})
29
+ end
30
+ let(:cmd_output_format) { :text }
31
+ let(:simple_cmdlet) { Chef::Util::Powershell::Cmdlet.new(@node, 'get-childitem', cmd_output_format, {:depth => 2}) }
32
+ let(:invalid_cmdlet) { Chef::Util::Powershell::Cmdlet.new(@node, 'get-idontexist', cmd_output_format) }
33
+ let(:cmdlet_get_item_requires_switch_or_argument) { Chef::Util::Powershell::Cmdlet.new(@node, 'get-item', cmd_output_format, {:depth => 2}) }
34
+ let(:cmdlet_alias_requires_switch_or_argument) { Chef::Util::Powershell::Cmdlet.new(@node, 'alias', cmd_output_format, {:depth => 2}) }
35
+ let(:etc_directory) { "#{ENV['systemroot']}\\system32\\drivers\\etc" }
36
+ let(:architecture_cmdlet) { Chef::Util::Powershell::Cmdlet.new(@node, "$env:PROCESSOR_ARCHITECTURE")}
37
+
38
+ it "executes a simple process" do
39
+ result = simple_cmdlet.run
40
+ expect(result.succeeded?).to eq(true)
41
+ end
42
+
43
+ it "#run does not raise a PowershellCmdletException exception if the command cannot be executed" do
44
+ expect {invalid_cmdlet.run}.not_to raise_error
45
+ end
46
+
47
+ it "#run! raises a PowershellCmdletException exception if the command cannot be executed" do
48
+ expect {invalid_cmdlet.run!}.to raise_error(Chef::Exceptions::PowershellCmdletException)
49
+ end
50
+
51
+ it "executes a 64-bit command on a 64-bit OS, 32-bit otherwise" do
52
+ os_arch = ENV['PROCESSOR_ARCHITEW6432']
53
+ if os_arch.nil?
54
+ os_arch = ENV['PROCESSOR_ARCHITECTURE']
55
+ end
56
+
57
+ result = architecture_cmdlet.run
58
+ execution_arch = result.return_value
59
+ execution_arch.strip!
60
+ expect(execution_arch).to eq(os_arch)
61
+ end
62
+
63
+ it "passes command line switches to the command" do
64
+ result = cmdlet_alias_requires_switch_or_argument.run({:name => 'ls'})
65
+ expect(result.succeeded?).to eq(true)
66
+ end
67
+
68
+ it "passes command line arguments to the command" do
69
+ result = cmdlet_alias_requires_switch_or_argument.run({},{},'ls')
70
+ expect(result.succeeded?).to eq(true)
71
+ end
72
+
73
+ it "passes command line arguments and switches to the command" do
74
+ result = cmdlet_get_item_requires_switch_or_argument.run({:path => etc_directory},{},' | select-object -property fullname | format-table -hidetableheaders')
75
+ expect(result.succeeded?).to eq(true)
76
+ returned_directory = result.return_value
77
+ returned_directory.strip!
78
+ expect(returned_directory).to eq(etc_directory)
79
+ end
80
+
81
+ it "passes execution options to the command" do
82
+ result = cmdlet_get_item_requires_switch_or_argument.run({},{:cwd => etc_directory},'. | select-object -property fullname | format-table -hidetableheaders')
83
+ expect(result.succeeded?).to eq(true)
84
+ returned_directory = result.return_value
85
+ returned_directory.strip!
86
+ expect(returned_directory).to eq(etc_directory)
87
+ end
88
+
89
+ context "when returning json" do
90
+ let(:cmd_output_format) { :json }
91
+ it "returns json format data", :windows_powershell_dsc_only do
92
+ result = cmdlet_alias_requires_switch_or_argument.run({},{},'ls')
93
+ expect(result.succeeded?).to eq(true)
94
+ expect(lambda{JSON.parse(result.return_value)}).not_to raise_error
95
+ end
96
+ end
97
+
98
+ context "when returning Ruby objects" do
99
+ let(:cmd_output_format) { :object }
100
+ it "returns object format data", :windows_powershell_dsc_only do
101
+ result = simple_cmdlet.run({},{:cwd => etc_directory}, 'hosts')
102
+ expect(result.succeeded?).to eq(true)
103
+ data = result.return_value
104
+ expect(data['Name']).to eq('hosts')
105
+ end
106
+ end
107
+
108
+ context "when constructor is given invalid arguments" do
109
+ let(:cmd_output_format) { :invalid }
110
+ it "throws an exception if an invalid format is passed to the constructor" do
111
+ expect(lambda{simple_cmdlet}).to raise_error
112
+ end
113
+ end
114
+ end