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

Sign up to get free protection for your applications and to get access to all the features.
@@ -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