chef 11.16.0.rc.0 → 11.16.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/lib/chef/exceptions.rb +2 -0
- data/lib/chef/platform/query_helpers.rb +5 -1
- data/lib/chef/provider/user/dscl.rb +32 -28
- data/lib/chef/resource/dsc_script.rb +18 -1
- data/lib/chef/util/dsc/lcm_output_parser.rb +33 -78
- data/lib/chef/version.rb +1 -1
- data/spec/functional/resource/dsc_script_spec.rb +4 -3
- data/spec/unit/platform/query_helpers_spec.rb +23 -0
- data/spec/unit/provider/dsc_script_spec.rb +5 -1
- data/spec/unit/provider/user/dscl_spec.rb +2 -1
- data/spec/unit/resource/dsc_script_spec.rb +90 -57
- data/spec/unit/util/dsc/configuration_generator_spec.rb +31 -33
- data/spec/unit/util/dsc/lcm_output_parser_spec.rb +18 -27
- metadata +61 -61
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 35d381547e2d87fff669607dd5c7c665715ab63a
|
4
|
+
data.tar.gz: 7bcec5986b17034f0516244df9abc05f18afc44c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b91d63e4a5419efe7383921f447b9b57ae07964bf498247e7269fa57b4009520be07758a9adb53f3c309e685cd8404cf6c13983d9a2c749f8f8d3747508f881
|
7
|
+
data.tar.gz: f96f17155457789f4aa2b0907ba67e624ec6e05fba6d89db5b11384b3249b6ac97c84e4dfd0c02df214fbfd7f62fe05d296687b030e2492bb5ffc0efd303538b
|
data/lib/chef/exceptions.rb
CHANGED
@@ -110,18 +110,18 @@ user password using shadow hash.")
|
|
110
110
|
@current_resource = Chef::Resource::User.new(@new_resource.username)
|
111
111
|
@current_resource.username(@new_resource.username)
|
112
112
|
|
113
|
-
user_info = read_user_info
|
114
|
-
if user_info
|
115
|
-
@current_resource.uid(dscl_get(user_info, :uid))
|
116
|
-
@current_resource.gid(dscl_get(user_info, :gid))
|
117
|
-
@current_resource.home(dscl_get(user_info, :home))
|
118
|
-
@current_resource.shell(dscl_get(user_info, :shell))
|
119
|
-
@current_resource.comment(dscl_get(user_info, :comment))
|
120
|
-
@authentication_authority = dscl_get(user_info, :auth_authority)
|
121
|
-
|
122
|
-
if @new_resource.password && dscl_get(user_info, :password) == "********"
|
113
|
+
@user_info = read_user_info
|
114
|
+
if @user_info
|
115
|
+
@current_resource.uid(dscl_get(@user_info, :uid))
|
116
|
+
@current_resource.gid(dscl_get(@user_info, :gid))
|
117
|
+
@current_resource.home(dscl_get(@user_info, :home))
|
118
|
+
@current_resource.shell(dscl_get(@user_info, :shell))
|
119
|
+
@current_resource.comment(dscl_get(@user_info, :comment))
|
120
|
+
@authentication_authority = dscl_get(@user_info, :auth_authority)
|
121
|
+
|
122
|
+
if @new_resource.password && dscl_get(@user_info, :password) == "********"
|
123
123
|
# A password is set. Let's get the password information from shadow file
|
124
|
-
shadow_hash_binary = dscl_get(user_info, :shadow_hash)
|
124
|
+
shadow_hash_binary = dscl_get(@user_info, :shadow_hash)
|
125
125
|
|
126
126
|
# Calling shell_out directly since we want to give an input stream
|
127
127
|
shadow_hash_xml = convert_binary_plist_to_xml(shadow_hash_binary.string)
|
@@ -158,22 +158,26 @@ user password using shadow hash.")
|
|
158
158
|
|
159
159
|
def create_user
|
160
160
|
dscl_create_user
|
161
|
+
# set_password modifies the plist file of the user directly. So update
|
162
|
+
# the password first before making any modifications to the user.
|
163
|
+
set_password
|
161
164
|
dscl_create_comment
|
162
165
|
dscl_set_uid
|
163
166
|
dscl_set_gid
|
164
167
|
dscl_set_home
|
165
168
|
dscl_set_shell
|
166
|
-
set_password
|
167
169
|
end
|
168
170
|
|
169
171
|
def manage_user
|
172
|
+
# set_password modifies the plist file of the user directly. So update
|
173
|
+
# the password first before making any modifications to the user.
|
174
|
+
set_password if diverged_password?
|
170
175
|
dscl_create_user if diverged?(:username)
|
171
176
|
dscl_create_comment if diverged?(:comment)
|
172
177
|
dscl_set_uid if diverged?(:uid)
|
173
178
|
dscl_set_gid if diverged?(:gid)
|
174
179
|
dscl_set_home if diverged?(:home)
|
175
180
|
dscl_set_shell if diverged?(:shell)
|
176
|
-
set_password if diverged_password?
|
177
181
|
end
|
178
182
|
|
179
183
|
#
|
@@ -339,22 +343,18 @@ user password using shadow hash.")
|
|
339
343
|
:input => shadow_info.to_plist, :live_stream => shadow_info_binary)
|
340
344
|
command.run_command
|
341
345
|
|
346
|
+
if @user_info.nil?
|
347
|
+
# User is just created. read_user_info() will read the fresh information
|
348
|
+
# for the user with a cache flush. However with experimentation we've seen
|
349
|
+
# that dscl cache is not immediately updated after the creation of the user
|
350
|
+
# This is odd and needs to be investigated further.
|
351
|
+
sleep 3
|
352
|
+
@user_info = read_user_info
|
353
|
+
end
|
354
|
+
|
342
355
|
# Replace the shadow info in user's plist
|
343
|
-
user_info
|
344
|
-
|
345
|
-
|
346
|
-
#
|
347
|
-
# Before saving the user's plist file we need to wait for dscl to
|
348
|
-
# update its caches and flush them to disk. In order to achieve this
|
349
|
-
# we need to wait first for our changes to get into the dscl cache
|
350
|
-
# and then flush the cache to disk before saving password into the
|
351
|
-
# plist file. 3 seconds is the minimum experimental value for dscl
|
352
|
-
# cache to be updated. We can get rid of this sleep when we find a
|
353
|
-
# trigger to update dscl cache.
|
354
|
-
#
|
355
|
-
sleep 3
|
356
|
-
shell_out("dscacheutil '-flushcache'")
|
357
|
-
save_user_info(user_info)
|
356
|
+
dscl_set(@user_info, :shadow_hash, shadow_info_binary)
|
357
|
+
save_user_info(@user_info)
|
358
358
|
end
|
359
359
|
|
360
360
|
#
|
@@ -555,6 +555,10 @@ user password using shadow hash.")
|
|
555
555
|
def read_user_info
|
556
556
|
user_info = nil
|
557
557
|
|
558
|
+
# We flush the cache here in order to make sure that we read fresh information
|
559
|
+
# for the user.
|
560
|
+
shell_out("dscacheutil '-flushcache'")
|
561
|
+
|
558
562
|
begin
|
559
563
|
user_plist_file = "#{USER_PLIST_DIRECTORY}/#{@new_resource.username}.plist"
|
560
564
|
user_plist_info = run_plutil("convert xml1 -o - #{user_plist_file}")
|
@@ -16,6 +16,8 @@
|
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
18
|
|
19
|
+
require 'chef/exceptions'
|
20
|
+
|
19
21
|
class Chef
|
20
22
|
class Resource
|
21
23
|
class DscScript < Chef::Resource
|
@@ -26,7 +28,12 @@ class Chef
|
|
26
28
|
super
|
27
29
|
@allowed_actions.push(:run)
|
28
30
|
@action = :run
|
29
|
-
|
31
|
+
if(run_context && Chef::Platform.supports_dsc?(run_context.node))
|
32
|
+
@provider = Chef::Provider::DscScript
|
33
|
+
else
|
34
|
+
raise Chef::Exceptions::NoProviderAvailable,
|
35
|
+
"#{powershell_info_str(run_context)}\nPowershell 4.0 or higher was not detected on your system and is required to use the dsc_script resource."
|
36
|
+
end
|
30
37
|
end
|
31
38
|
|
32
39
|
def code(arg=nil)
|
@@ -118,6 +125,16 @@ class Chef
|
|
118
125
|
:kind_of => [ Integer ]
|
119
126
|
)
|
120
127
|
end
|
128
|
+
|
129
|
+
private
|
130
|
+
|
131
|
+
def powershell_info_str(run_context)
|
132
|
+
if run_context && run_context.node[:languages] && run_context.node[:languages][:powershell]
|
133
|
+
install_info = "Powershell #{run_context.node[:languages][:powershell][:version]} was found on the system."
|
134
|
+
else
|
135
|
+
install_info = 'Powershell was not found.'
|
136
|
+
end
|
137
|
+
end
|
121
138
|
end
|
122
139
|
end
|
123
140
|
end
|
@@ -24,44 +24,6 @@ class Chef
|
|
24
24
|
class DSC
|
25
25
|
class LocalConfigurationManager
|
26
26
|
module Parser
|
27
|
-
class ParseException < RuntimeError; end
|
28
|
-
|
29
|
-
class Operation
|
30
|
-
attr_reader :op_type
|
31
|
-
attr_reader :resources
|
32
|
-
attr_reader :info
|
33
|
-
attr_reader :sets
|
34
|
-
attr_reader :tests
|
35
|
-
|
36
|
-
def initialize(op_type, info)
|
37
|
-
@op_type = op_type
|
38
|
-
@info = []
|
39
|
-
@sets = []
|
40
|
-
@tests = []
|
41
|
-
@resources = []
|
42
|
-
add_info(info)
|
43
|
-
end
|
44
|
-
|
45
|
-
def add_info(info)
|
46
|
-
@info << info
|
47
|
-
end
|
48
|
-
|
49
|
-
def add_set(set)
|
50
|
-
raise ParseException, "add_set is not allowed in this context. Found #{@op_type}" unless [:resource, :set].include?(@op_type)
|
51
|
-
@sets << set
|
52
|
-
end
|
53
|
-
|
54
|
-
def add_test(test)
|
55
|
-
raise ParseException, "add_test is not allowed in this context. Found #{@op_type}" unless [:resource, :set].include?(@op_type)
|
56
|
-
@tests << test
|
57
|
-
end
|
58
|
-
|
59
|
-
def add_resource(resource)
|
60
|
-
raise ParseException, 'add_resource is only allowed to be added to the set op_type' unless @op_type == :set
|
61
|
-
@resources << resource
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
27
|
# Parses the output from LCM and returns a list of Chef::Util::DSC::ResourceInfo objects
|
66
28
|
# that describe how the resources affected the system
|
67
29
|
#
|
@@ -93,83 +55,76 @@ class Chef
|
|
93
55
|
def self.parse(lcm_output)
|
94
56
|
return [] unless lcm_output
|
95
57
|
|
96
|
-
|
97
|
-
|
58
|
+
current_resource = Hash.new
|
59
|
+
|
60
|
+
resources = []
|
98
61
|
lcm_output.lines.each do |line|
|
99
62
|
op_action, op_type, info = parse_line(line)
|
100
|
-
info.strip! # Because this was formatted for humans
|
101
63
|
|
102
|
-
# The rules:
|
103
|
-
# - For each `start` action, there must be a matching `end` action
|
104
|
-
# - `skip` actions do not not do anything (They don't add to the stack)
|
105
64
|
case op_action
|
106
65
|
when :start
|
107
|
-
new_op = Operation.new(op_type, info)
|
108
66
|
case op_type
|
109
67
|
when :set
|
110
|
-
|
111
|
-
|
112
|
-
|
68
|
+
if current_resource[:name]
|
69
|
+
current_resource[:context] = :logging
|
70
|
+
current_resource[:logs] = [info]
|
71
|
+
end
|
113
72
|
when :resource
|
114
|
-
|
115
|
-
|
116
|
-
popped_op = stack.pop
|
73
|
+
if current_resource[:name]
|
74
|
+
resources.push(current_resource)
|
117
75
|
end
|
118
|
-
|
76
|
+
current_resource = {:name => info}
|
119
77
|
else
|
120
|
-
Chef::Log.
|
78
|
+
Chef::Log.debug("Ignoring op_action #{op_action}: Read line #{line}")
|
121
79
|
end
|
122
|
-
stack.push(new_op)
|
123
80
|
when :end
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
Chef::Log::warn("Unmatching end for op_type. Expected op_type=#{op_type}, found op_type=#{popped_op.op_type}. From output:\n#{lcm_output}")
|
128
|
-
popped_op = stack.pop
|
81
|
+
# Make sure we log the last line
|
82
|
+
if current_resource[:context] == :logging and info.include? current_resource[:name]
|
83
|
+
current_resource[:logs].push(info)
|
129
84
|
end
|
85
|
+
current_resource[:context] = nil
|
130
86
|
when :skip
|
131
|
-
|
87
|
+
current_resource[:skipped] = true
|
132
88
|
when :info
|
133
|
-
|
134
|
-
|
135
|
-
|
89
|
+
if current_resource[:context] == :logging
|
90
|
+
current_resource[:logs].push(info)
|
91
|
+
end
|
136
92
|
end
|
137
93
|
end
|
138
94
|
|
139
|
-
|
95
|
+
if current_resource[:name]
|
96
|
+
resources.push(current_resource)
|
97
|
+
end
|
98
|
+
|
99
|
+
build_resource_info(resources)
|
140
100
|
end
|
141
101
|
|
142
102
|
def self.parse_line(line)
|
143
103
|
if match = line.match(/^.*?:.*?:\s*LCM:\s*\[(.*?)\](.*)/)
|
144
104
|
# If the line looks like
|
145
|
-
#
|
105
|
+
# What If: [machinename]: LCM: [op_action op_type] message
|
146
106
|
# extract op_action, op_type, and message
|
147
107
|
operation, info = match.captures
|
148
108
|
op_action, op_type = operation.strip.split(' ').map {|m| m.downcase.to_sym}
|
149
109
|
else
|
150
|
-
# If the line looks like
|
151
|
-
# x: [y]: message
|
152
|
-
# extract message
|
153
|
-
match = line.match(/^.*?:.*?: \s+(.*)/)
|
154
110
|
op_action = op_type = :info
|
155
|
-
|
111
|
+
if match = line.match(/^.*?:.*?: \s+(.*)/)
|
112
|
+
info = match.captures[0]
|
113
|
+
else
|
114
|
+
info = line
|
115
|
+
end
|
156
116
|
end
|
157
117
|
info.strip! # Because this was formatted for humans
|
158
118
|
return [op_action, op_type, info]
|
159
119
|
end
|
160
120
|
private_class_method :parse_line
|
161
121
|
|
162
|
-
def self.
|
163
|
-
resources = op ? op.resources : []
|
164
|
-
|
122
|
+
def self.build_resource_info(resources)
|
165
123
|
resources.map do |r|
|
166
|
-
name
|
167
|
-
sets = r.sets.length > 0
|
168
|
-
change_log = r.sets[-1].info if sets
|
169
|
-
Chef::Util::DSC::ResourceInfo.new(name, sets, change_log)
|
124
|
+
Chef::Util::DSC::ResourceInfo.new(r[:name], !r[:skipped], r[:logs])
|
170
125
|
end
|
171
126
|
end
|
172
|
-
private_class_method :
|
127
|
+
private_class_method :build_resource_info
|
173
128
|
|
174
129
|
end
|
175
130
|
end
|
data/lib/chef/version.rb
CHANGED
@@ -65,10 +65,11 @@ describe Chef::Resource::DscScript, :windows_powershell_dsc_only do
|
|
65
65
|
let(:env_value2) { 'value2' }
|
66
66
|
let(:dsc_test_run_context) {
|
67
67
|
node = Chef::Node.new
|
68
|
-
node.
|
69
|
-
node.
|
70
|
-
node.
|
68
|
+
node.automatic['platform'] = 'windows'
|
69
|
+
node.automatic['platform_version'] = '6.1'
|
70
|
+
node.automatic['kernel'][:machine] =
|
71
71
|
is_i386_process_on_x86_64_windows? ? :x86_64 : :i386
|
72
|
+
node.automatic[:languages][:powershell][:version] = '4.0'
|
72
73
|
empty_events = Chef::EventDispatch::Dispatcher.new
|
73
74
|
Chef::RunContext.new(node, {}, empty_events)
|
74
75
|
}
|
@@ -30,3 +30,26 @@ describe "Chef::Platform#windows_server_2003?" do
|
|
30
30
|
expect { Thread.fork { Chef::Platform.windows_server_2003? }.join }.not_to raise_error
|
31
31
|
end
|
32
32
|
end
|
33
|
+
|
34
|
+
describe 'Chef::Platform#supports_dsc?' do
|
35
|
+
it 'returns false if powershell is not present' do
|
36
|
+
node = Chef::Node.new
|
37
|
+
Chef::Platform.supports_dsc?(node).should be_false
|
38
|
+
end
|
39
|
+
|
40
|
+
['1.0', '2.0', '3.0'].each do |version|
|
41
|
+
it "returns false for Powershell #{version}" do
|
42
|
+
node = Chef::Node.new
|
43
|
+
node.automatic[:languages][:powershell][:version] = version
|
44
|
+
Chef::Platform.supports_dsc?(node).should be_false
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
['4.0', '5.0'].each do |version|
|
49
|
+
it "returns true for Powershell #{version}" do
|
50
|
+
node = Chef::Node.new
|
51
|
+
node.automatic[:languages][:powershell][:version] = version
|
52
|
+
Chef::Platform.supports_dsc?(node).should be_true
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -22,7 +22,11 @@ require 'chef/util/dsc/resource_info'
|
|
22
22
|
require 'spec_helper'
|
23
23
|
|
24
24
|
describe Chef::Provider::DscScript do
|
25
|
-
let (:node) {
|
25
|
+
let (:node) {
|
26
|
+
node = Chef::Node.new
|
27
|
+
node.automatic[:languages][:powershell][:version] = '4.0'
|
28
|
+
node
|
29
|
+
}
|
26
30
|
let (:events) { Chef::EventDispatch::Dispatcher.new }
|
27
31
|
let (:run_context) { Chef::RunContext.new(node, {}, events) }
|
28
32
|
let (:resource) { Chef::Resource::DscScript.new("script", run_context) }
|
@@ -376,6 +376,7 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30"
|
|
376
376
|
let(:user_plist_file) { nil }
|
377
377
|
|
378
378
|
before do
|
379
|
+
provider.should_receive(:shell_out).with("dscacheutil '-flushcache'")
|
379
380
|
provider.should_receive(:shell_out).with("plutil -convert xml1 -o - /var/db/dslocal/nodes/Default/users/toor.plist") do
|
380
381
|
if user_plist_file.nil?
|
381
382
|
ShellCmdResult.new('Can not find the file', 'Sorry!!', 1)
|
@@ -715,7 +716,6 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30")
|
|
715
716
|
provider.should_receive(:read_user_info)
|
716
717
|
provider.should_receive(:dscl_set)
|
717
718
|
provider.should_receive(:sleep).with(3)
|
718
|
-
provider.should_receive(:shell_out).with("dscacheutil '-flushcache'")
|
719
719
|
provider.should_receive(:save_user_info)
|
720
720
|
provider.set_password
|
721
721
|
end
|
@@ -822,6 +822,7 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30")
|
|
822
822
|
|
823
823
|
describe "when the user exists" do
|
824
824
|
before do
|
825
|
+
provider.should_receive(:shell_out).with("dscacheutil '-flushcache'")
|
825
826
|
provider.should_receive(:shell_out).with("plutil -convert xml1 -o - /var/db/dslocal/nodes/Default/users/toor.plist") do
|
826
827
|
ShellCmdResult.new(File.read(File.join(CHEF_SPEC_DATA, "mac_users/10.9.plist.xml")), "", 0)
|
827
828
|
end
|
@@ -19,76 +19,109 @@
|
|
19
19
|
require 'spec_helper'
|
20
20
|
|
21
21
|
describe Chef::Resource::DscScript do
|
22
|
-
let(:dsc_test_run_context) {
|
23
|
-
node = Chef::Node.new
|
24
|
-
empty_events = Chef::EventDispatch::Dispatcher.new
|
25
|
-
Chef::RunContext.new(node, {}, empty_events)
|
26
|
-
}
|
27
22
|
let(:dsc_test_resource_name) { 'DSCTest' }
|
28
|
-
let(:dsc_test_resource) {
|
29
|
-
Chef::Resource::DscScript.new(dsc_test_resource_name, dsc_test_run_context)
|
30
|
-
}
|
31
|
-
let(:configuration_code) {'echo "This is supposed to create a configuration document."'}
|
32
|
-
let(:configuration_path) {'c:/myconfigs/formatc.ps1'}
|
33
|
-
let(:configuration_name) { 'formatme' }
|
34
|
-
let(:configuration_data) { '@{AllNodes = @( @{ NodeName = "localhost"; PSDscAllowPlainTextPassword = $true })}' }
|
35
|
-
let(:configuration_data_script) { 'c:/myconfigs/data/safedata.psd1' }
|
36
|
-
|
37
|
-
it "has a default action of `:run`" do
|
38
|
-
expect(dsc_test_resource.action).to eq(:run)
|
39
|
-
end
|
40
23
|
|
41
|
-
|
42
|
-
|
43
|
-
|
24
|
+
context 'when Powershell supports Dsc' do
|
25
|
+
let(:dsc_test_run_context) {
|
26
|
+
node = Chef::Node.new
|
27
|
+
node.automatic[:languages][:powershell][:version] = '4.0'
|
28
|
+
empty_events = Chef::EventDispatch::Dispatcher.new
|
29
|
+
Chef::RunContext.new(node, {}, empty_events)
|
30
|
+
}
|
31
|
+
let(:dsc_test_resource) {
|
32
|
+
Chef::Resource::DscScript.new(dsc_test_resource_name, dsc_test_run_context)
|
33
|
+
}
|
34
|
+
let(:configuration_code) {'echo "This is supposed to create a configuration document."'}
|
35
|
+
let(:configuration_path) {'c:/myconfigs/formatc.ps1'}
|
36
|
+
let(:configuration_name) { 'formatme' }
|
37
|
+
let(:configuration_data) { '@{AllNodes = @( @{ NodeName = "localhost"; PSDscAllowPlainTextPassword = $true })}' }
|
38
|
+
let(:configuration_data_script) { 'c:/myconfigs/data/safedata.psd1' }
|
44
39
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
end
|
40
|
+
it "has a default action of `:run`" do
|
41
|
+
expect(dsc_test_resource.action).to eq(:run)
|
42
|
+
end
|
49
43
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
end
|
44
|
+
it "has an allowed_actions attribute with only the `:run` and `:nothing` attributes" do
|
45
|
+
expect(dsc_test_resource.allowed_actions.to_set).to eq([:run,:nothing].to_set)
|
46
|
+
end
|
54
47
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
48
|
+
it "allows the code attribute to be set" do
|
49
|
+
dsc_test_resource.code(configuration_code)
|
50
|
+
expect(dsc_test_resource.code).to eq(configuration_code)
|
51
|
+
end
|
59
52
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
53
|
+
it "allows the command attribute to be set" do
|
54
|
+
dsc_test_resource.command(configuration_path)
|
55
|
+
expect(dsc_test_resource.command).to eq(configuration_path)
|
56
|
+
end
|
64
57
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
58
|
+
it "allows the configuration_name attribute to be set" do
|
59
|
+
dsc_test_resource.configuration_name(configuration_name)
|
60
|
+
expect(dsc_test_resource.configuration_name).to eq(configuration_name)
|
61
|
+
end
|
69
62
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
63
|
+
it "allows the configuration_data attribute to be set" do
|
64
|
+
dsc_test_resource.configuration_data(configuration_data)
|
65
|
+
expect(dsc_test_resource.configuration_data).to eq(configuration_data)
|
66
|
+
end
|
74
67
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
68
|
+
it "allows the configuration_data_script attribute to be set" do
|
69
|
+
dsc_test_resource.configuration_data_script(configuration_data_script)
|
70
|
+
expect(dsc_test_resource.configuration_data_script).to eq(configuration_data_script)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "raises an ArgumentError exception if an attempt is made to set the code attribute when the command attribute is already set" do
|
74
|
+
dsc_test_resource.command(configuration_path)
|
75
|
+
expect { dsc_test_resource.code(configuration_code) }.to raise_error(ArgumentError)
|
76
|
+
end
|
77
|
+
|
78
|
+
it "raises an ArgumentError exception if an attempt is made to set the command attribute when the code attribute is already set" do
|
79
|
+
dsc_test_resource.code(configuration_code)
|
80
|
+
expect { dsc_test_resource.command(configuration_path) }.to raise_error(ArgumentError)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "raises an ArgumentError exception if an attempt is made to set the configuration_name attribute when the code attribute is already set" do
|
84
|
+
dsc_test_resource.code(configuration_code)
|
85
|
+
expect { dsc_test_resource.configuration_name(configuration_name) }.to raise_error(ArgumentError)
|
86
|
+
end
|
79
87
|
|
80
|
-
|
81
|
-
|
82
|
-
|
88
|
+
it "raises an ArgumentError exception if an attempt is made to set the configuration_data attribute when the configuration_data_script attribute is already set" do
|
89
|
+
dsc_test_resource.configuration_data_script(configuration_data_script)
|
90
|
+
expect { dsc_test_resource.configuration_data(configuration_data) }.to raise_error(ArgumentError)
|
91
|
+
end
|
92
|
+
|
93
|
+
it "raises an ArgumentError exception if an attempt is made to set the configuration_data_script attribute when the configuration_data attribute is already set" do
|
94
|
+
dsc_test_resource.configuration_data(configuration_data)
|
95
|
+
expect { dsc_test_resource.configuration_data_script(configuration_data_script) }.to raise_error(ArgumentError)
|
96
|
+
end
|
83
97
|
end
|
84
98
|
|
85
|
-
|
86
|
-
|
87
|
-
|
99
|
+
context 'when Powershell does not supported Dsc' do
|
100
|
+
['1.0', '2.0', '3.0'].each do |version|
|
101
|
+
it "raises an exception for powershell version '#{version}'" do
|
102
|
+
node = Chef::Node.new
|
103
|
+
node.automatic[:languages][:powershell][:version] = version
|
104
|
+
empty_events = Chef::EventDispatch::Dispatcher.new
|
105
|
+
dsc_test_run_context = Chef::RunContext.new(node, {}, empty_events)
|
106
|
+
|
107
|
+
expect {
|
108
|
+
Chef::Resource::DscScript.new(dsc_test_resource_name, dsc_test_run_context)
|
109
|
+
}.to raise_error(Chef::Exceptions::NoProviderAvailable)
|
110
|
+
end
|
111
|
+
end
|
88
112
|
end
|
89
113
|
|
90
|
-
|
91
|
-
|
92
|
-
|
114
|
+
context 'when Powershell is not present' do
|
115
|
+
let (:dsc_test_run_context) {
|
116
|
+
node = Chef::Node.new
|
117
|
+
empty_events = Chef::EventDispatch::Dispatcher.new
|
118
|
+
dsc_test_run_context = Chef::RunContext.new(node, {}, empty_events)
|
119
|
+
}
|
120
|
+
|
121
|
+
it 'raises an exception if powershell is not present' do
|
122
|
+
expect {
|
123
|
+
Chef::Resource::DscScript.new(dsc_test_resource_name, dsc_test_run_context)
|
124
|
+
}.to raise_error(Chef::Exceptions::NoProviderAvailable)
|
125
|
+
end
|
93
126
|
end
|
94
127
|
end
|