chef 11.16.0.rc.0 → 11.16.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|