chef 11.12.0.alpha.1 → 11.12.0.rc.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/chef/api_client/registration.rb +46 -9
- data/lib/chef/application.rb +1 -0
- data/lib/chef/application/client.rb +25 -24
- data/lib/chef/client.rb +34 -0
- data/lib/chef/config.rb +11 -0
- data/lib/chef/cookbook/chefignore.rb +10 -2
- data/lib/chef/cookbook/metadata.rb +31 -3
- data/lib/chef/cookbook/synchronizer.rb +2 -2
- data/lib/chef/cookbook/syntax_check.rb +4 -4
- data/lib/chef/encrypted_data_bag_item.rb +37 -1
- data/lib/chef/exceptions.rb +1 -0
- data/lib/chef/guard_interpreter/default_guard_interpreter.rb +42 -0
- data/lib/chef/guard_interpreter/resource_guard_interpreter.rb +122 -0
- data/lib/chef/http.rb +0 -1
- data/lib/chef/http/decompressor.rb +7 -4
- data/lib/chef/http/simple.rb +5 -0
- data/lib/chef/http/validate_content_length.rb +28 -12
- data/lib/chef/knife.rb +1 -0
- data/lib/chef/knife/client_bulk_delete.rb +48 -9
- data/lib/chef/knife/client_delete.rb +4 -4
- data/lib/chef/knife/cookbook_bulk_delete.rb +1 -1
- data/lib/chef/knife/cookbook_upload.rb +17 -7
- data/lib/chef/knife/core/bootstrap_context.rb +1 -1
- data/lib/chef/knife/core/ui.rb +42 -5
- data/lib/chef/knife/node_run_list_add.rb +31 -2
- data/lib/chef/knife/ssh.rb +44 -31
- data/lib/chef/knife/ssl_check.rb +213 -0
- data/lib/chef/knife/ssl_fetch.rb +145 -0
- data/lib/chef/mixin/deep_merge.rb +13 -5
- data/lib/chef/mixin/shell_out.rb +9 -3
- data/lib/chef/node.rb +23 -4
- data/lib/chef/node/immutable_collections.rb +32 -0
- data/lib/chef/platform/provider_mapping.rb +21 -18
- data/lib/chef/platform/query_helpers.rb +10 -2
- data/lib/chef/policy_builder/expand_node_object.rb +3 -6
- data/lib/chef/provider/cron.rb +25 -3
- data/lib/chef/provider/mount/mount.rb +1 -1
- data/lib/chef/provider/package/dpkg.rb +2 -1
- data/lib/chef/provider/package/windows.rb +80 -0
- data/lib/chef/provider/package/windows/msi.rb +69 -0
- data/lib/chef/provider/powershell_script.rb +19 -6
- data/lib/chef/provider/service/solaris.rb +11 -7
- data/lib/chef/resource.rb +18 -5
- data/lib/chef/resource/conditional.rb +20 -7
- data/lib/chef/resource/cron.rb +18 -2
- data/lib/chef/resource/execute.rb +0 -2
- data/lib/chef/resource/powershell_script.rb +23 -1
- data/lib/chef/resource/script.rb +25 -0
- data/lib/chef/resource/subversion.rb +4 -0
- data/lib/chef/resource/windows_package.rb +79 -0
- data/lib/chef/resource/windows_script.rb +0 -5
- data/lib/chef/resources.rb +1 -0
- data/lib/chef/rest.rb +6 -1
- data/lib/chef/run_context.rb +22 -2
- data/lib/chef/run_context/cookbook_compiler.rb +12 -0
- data/lib/chef/util/editor.rb +92 -0
- data/lib/chef/util/file_edit.rb +22 -54
- data/lib/chef/version.rb +2 -2
- data/lib/chef/win32/api/installer.rb +166 -0
- data/lib/chef/win32/version.rb +8 -0
- data/spec/data/standalone_cookbook/Gemfile +1 -0
- data/spec/data/standalone_cookbook/chefignore +9 -0
- data/spec/data/standalone_cookbook/recipes/default.rb +3 -0
- data/spec/data/standalone_cookbook/vendor/bundle/ruby/2.0.0/gems/multi_json-1.9.0/lib/multi_json.rb +1 -0
- data/spec/functional/resource/powershell_spec.rb +262 -1
- data/spec/functional/win32/versions_spec.rb +3 -3
- data/spec/integration/knife/chefignore_spec.rb +1 -2
- data/spec/integration/knife/raw_spec.rb +8 -13
- data/spec/integration/knife/redirection_spec.rb +6 -14
- data/spec/integration/solo/solo_spec.rb +19 -0
- data/spec/support/shared/functional/windows_script.rb +1 -1
- data/spec/support/shared/integration/app_server_support.rb +42 -0
- data/spec/support/shared/integration/integration_helper.rb +1 -0
- data/spec/support/shared/unit/script_resource.rb +38 -0
- data/spec/unit/api_client/registration_spec.rb +109 -38
- data/spec/unit/application/client_spec.rb +48 -1
- data/spec/unit/cookbook/chefignore_spec.rb +10 -0
- data/spec/unit/cookbook/metadata_spec.rb +45 -1
- data/spec/unit/cookbook/syntax_check_spec.rb +28 -0
- data/spec/unit/cookbook_spec.rb +0 -10
- data/spec/unit/guard_interpreter/resource_guard_interpreter_spec.rb +56 -0
- data/spec/unit/http/simple_spec.rb +32 -0
- data/spec/unit/http/validate_content_length_spec.rb +187 -0
- data/spec/unit/knife/bootstrap_spec.rb +13 -4
- data/spec/unit/knife/client_bulk_delete_spec.rb +123 -38
- data/spec/unit/knife/client_delete_spec.rb +4 -4
- data/spec/unit/knife/cookbook_upload_spec.rb +181 -88
- data/spec/unit/knife/core/bootstrap_context_spec.rb +11 -1
- data/spec/unit/knife/core/ui_spec.rb +109 -38
- data/spec/unit/knife/node_run_list_add_spec.rb +24 -1
- data/spec/unit/knife/ssh_spec.rb +17 -6
- data/spec/unit/knife/ssl_check_spec.rb +187 -0
- data/spec/unit/knife/ssl_fetch_spec.rb +151 -0
- data/spec/unit/mixin/deep_merge_spec.rb +17 -0
- data/spec/unit/node/immutable_collections_spec.rb +55 -0
- data/spec/unit/node_spec.rb +9 -0
- data/spec/unit/platform/query_helpers_spec.rb +32 -0
- data/spec/unit/platform_spec.rb +193 -175
- data/spec/unit/policy_builder/expand_node_object_spec.rb +1 -1
- data/spec/unit/provider/cron_spec.rb +175 -1
- data/spec/unit/provider/mount/mount_spec.rb +33 -3
- data/spec/unit/provider/package/dpkg_spec.rb +4 -0
- data/spec/unit/provider/package/windows/msi_spec.rb +60 -0
- data/spec/unit/provider/package/windows_spec.rb +80 -0
- data/spec/unit/provider/service/macosx_spec.rb +3 -3
- data/spec/unit/provider/service/solaris_smf_service_spec.rb +35 -10
- data/spec/unit/pure_application_spec.rb +32 -0
- data/spec/unit/recipe_spec.rb +4 -0
- data/spec/unit/resource/conditional_spec.rb +13 -12
- data/spec/unit/resource/cron_spec.rb +7 -2
- data/spec/unit/resource/powershell_spec.rb +85 -2
- data/spec/unit/resource/subversion_spec.rb +5 -0
- data/spec/unit/resource/windows_package_spec.rb +74 -0
- data/spec/unit/resource_spec.rb +23 -1
- data/spec/unit/rest_spec.rb +15 -0
- data/spec/unit/run_context/cookbook_compiler_spec.rb +12 -0
- data/spec/unit/run_context_spec.rb +7 -0
- data/spec/unit/util/editor_spec.rb +152 -0
- data/spec/unit/util/file_edit_spec.rb +37 -1
- metadata +41 -30
@@ -0,0 +1,151 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Daniel DeLeo (<dan@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/knife/ssl_fetch'
|
21
|
+
|
22
|
+
describe Chef::Knife::SslFetch do
|
23
|
+
|
24
|
+
let(:name_args) { [] }
|
25
|
+
let(:stdout_io) { StringIO.new }
|
26
|
+
let(:stderr_io) { StringIO.new }
|
27
|
+
|
28
|
+
def stderr
|
29
|
+
stderr_io.string
|
30
|
+
end
|
31
|
+
|
32
|
+
def stdout
|
33
|
+
stdout_io.string
|
34
|
+
end
|
35
|
+
|
36
|
+
subject(:ssl_fetch) do
|
37
|
+
s = Chef::Knife::SslFetch.new
|
38
|
+
s.name_args = name_args
|
39
|
+
s.ui.stub(:stdout).and_return(stdout_io)
|
40
|
+
s.ui.stub(:stderr).and_return(stderr_io)
|
41
|
+
s
|
42
|
+
end
|
43
|
+
|
44
|
+
context "when no arguments are given" do
|
45
|
+
|
46
|
+
before do
|
47
|
+
Chef::Config.chef_server_url = "https://example.com:8443/chef-server"
|
48
|
+
end
|
49
|
+
|
50
|
+
it "uses the chef_server_url as the host to fetch" do
|
51
|
+
expect(ssl_fetch.host).to eq("example.com")
|
52
|
+
expect(ssl_fetch.port).to eq(8443)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "when a specific URI is given" do
|
57
|
+
let(:name_args) { %w{https://example.test:10443/foo} }
|
58
|
+
|
59
|
+
it "fetchs the SSL configuration against the given host" do
|
60
|
+
expect(ssl_fetch.host).to eq("example.test")
|
61
|
+
expect(ssl_fetch.port).to eq(10443)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context "when an invalid URI is given" do
|
66
|
+
|
67
|
+
let(:name_args) { %w{foo.test} }
|
68
|
+
|
69
|
+
it "prints an error and exits" do
|
70
|
+
expect { ssl_fetch.run }.to raise_error(SystemExit)
|
71
|
+
expected_stdout=<<-E
|
72
|
+
USAGE: knife ssl fetch [URL] (options)
|
73
|
+
E
|
74
|
+
expected_stderr=<<-E
|
75
|
+
ERROR: Given URI: `foo.test' is invalid
|
76
|
+
E
|
77
|
+
expect(stdout_io.string).to eq(expected_stdout)
|
78
|
+
expect(stderr_io.string).to eq(expected_stderr)
|
79
|
+
end
|
80
|
+
|
81
|
+
context "and its malformed enough to make URI.parse barf" do
|
82
|
+
|
83
|
+
let(:name_args) { %w{ftp://lkj\\blah:example.com/blah} }
|
84
|
+
|
85
|
+
it "prints an error and exits" do
|
86
|
+
expect { ssl_fetch.run }.to raise_error(SystemExit)
|
87
|
+
expected_stdout=<<-E
|
88
|
+
USAGE: knife ssl fetch [URL] (options)
|
89
|
+
E
|
90
|
+
expected_stderr=<<-E
|
91
|
+
ERROR: Given URI: `#{name_args[0]}' is invalid
|
92
|
+
E
|
93
|
+
expect(stdout_io.string).to eq(expected_stdout)
|
94
|
+
expect(stderr_io.string).to eq(expected_stderr)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "normalizing CNs for use as paths" do
|
100
|
+
|
101
|
+
it "normalizes '*' to 'wildcard'" do
|
102
|
+
expect(ssl_fetch.normalize_cn("*.example.com")).to eq("wildcard_example_com")
|
103
|
+
end
|
104
|
+
|
105
|
+
it "normalizes non-alnum and hyphen characters to underscores" do
|
106
|
+
expect(ssl_fetch.normalize_cn("Billy-Bob's Super Awesome CA!")).to eq("Billy-Bob_s_Super_Awesome_CA_")
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
describe "fetching the remote cert chain" do
|
112
|
+
|
113
|
+
let(:name_args) { %w{https://foo.example.com:8443} }
|
114
|
+
|
115
|
+
let(:tcp_socket) { double(TCPSocket) }
|
116
|
+
let(:ssl_socket) { double(OpenSSL::SSL::SSLSocket) }
|
117
|
+
|
118
|
+
let(:self_signed_crt_path) { File.join(CHEF_SPEC_DATA, "trusted_certs", "example.crt") }
|
119
|
+
let(:self_signed_crt) { OpenSSL::X509::Certificate.new(File.read(self_signed_crt_path)) }
|
120
|
+
|
121
|
+
let(:trusted_certs_dir) { Dir.mktmpdir }
|
122
|
+
|
123
|
+
def run
|
124
|
+
ssl_fetch.run
|
125
|
+
rescue Exception
|
126
|
+
puts "OUT: #{stdout_io.string}"
|
127
|
+
puts "ERR: #{stderr_io.string}"
|
128
|
+
raise
|
129
|
+
end
|
130
|
+
|
131
|
+
before do
|
132
|
+
Chef::Config.trusted_certs_dir = trusted_certs_dir
|
133
|
+
|
134
|
+
TCPSocket.should_receive(:new).with("foo.example.com", 8443).and_return(tcp_socket)
|
135
|
+
OpenSSL::SSL::SSLSocket.should_receive(:new).with(tcp_socket, ssl_fetch.noverify_peer_ssl_context).and_return(ssl_socket)
|
136
|
+
ssl_socket.should_receive(:connect)
|
137
|
+
ssl_socket.should_receive(:peer_cert_chain).and_return([self_signed_crt])
|
138
|
+
end
|
139
|
+
|
140
|
+
after do
|
141
|
+
FileUtils.rm_rf(trusted_certs_dir)
|
142
|
+
end
|
143
|
+
|
144
|
+
it "fetches the cert chain and writes the certs to the trusted_certs_dir" do
|
145
|
+
run
|
146
|
+
stored_cert_path = File.join(trusted_certs_dir, "example_local.crt")
|
147
|
+
expect(File).to exist(stored_cert_path)
|
148
|
+
expect(File.read(stored_cert_path)).to eq(File.read(self_signed_crt_path))
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
@@ -284,6 +284,10 @@ describe Chef::Mixin::DeepMerge do
|
|
284
284
|
ret.should == {"property" => ["1","2","3","4","5","6"]}
|
285
285
|
end
|
286
286
|
|
287
|
+
it "should not error merging un-dupable objects" do
|
288
|
+
@dm.deep_merge(nil, 4)
|
289
|
+
end
|
290
|
+
|
287
291
|
end
|
288
292
|
|
289
293
|
describe "role_merge" do
|
@@ -347,5 +351,18 @@ describe Chef::Mixin::DeepMerge do
|
|
347
351
|
merged_result["top_level_a"]["1_deep_b"].should == %w[B B B]
|
348
352
|
end
|
349
353
|
|
354
|
+
it "does not mutate deeply-nested original hashes by default" do
|
355
|
+
merge_ee_hash = {"top_level_a" => {"1_deep_a" => { "2_deep_a" => { "3_deep_a" => "foo" }}}}
|
356
|
+
merge_with_hash = {"top_level_a" => {"1_deep_a" => { "2_deep_a" => { "3_deep_b" => "bar" }}}}
|
357
|
+
@dm.hash_only_merge(merge_ee_hash, merge_with_hash)
|
358
|
+
merge_ee_hash.should == {"top_level_a" => {"1_deep_a" => { "2_deep_a" => { "3_deep_a" => "foo" }}}}
|
359
|
+
merge_with_hash.should == {"top_level_a" => {"1_deep_a" => { "2_deep_a" => { "3_deep_b" => "bar" }}}}
|
360
|
+
end
|
361
|
+
|
362
|
+
it "does not error merging un-dupable items" do
|
363
|
+
merge_ee_hash = {"top_level_a" => 1, "top_level_b" => false}
|
364
|
+
merge_with_hash = {"top_level_a" => 2, "top_level_b" => true }
|
365
|
+
@dm.hash_only_merge(merge_ee_hash, merge_with_hash)
|
366
|
+
end
|
350
367
|
end
|
351
368
|
end
|
@@ -54,6 +54,32 @@ describe Chef::Node::ImmutableMash do
|
|
54
54
|
@immutable_mash[:top_level_4][:level2].should be_a(Chef::Node::ImmutableMash)
|
55
55
|
end
|
56
56
|
|
57
|
+
describe "to_hash" do
|
58
|
+
before do
|
59
|
+
@copy = @immutable_mash.to_hash
|
60
|
+
end
|
61
|
+
|
62
|
+
it "converts an immutable mash to a new mutable hash" do
|
63
|
+
@copy.should be_instance_of(Hash)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "converts an immutable nested mash to a new mutable hash" do
|
67
|
+
@copy['top_level_4']['level2'].should be_instance_of(Hash)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "converts an immutable nested array to a new mutable array" do
|
71
|
+
@copy['top_level_2'].should be_instance_of(Array)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should create a mash with the same content" do
|
75
|
+
@copy.should == @immutable_mash
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should allow mutation' do
|
79
|
+
lambda { @copy['m'] = 'm' }.should_not raise_error(Chef::Exceptions::ImmutableAttributeModification)
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
57
83
|
|
58
84
|
[
|
59
85
|
:[]=,
|
@@ -87,6 +113,8 @@ describe Chef::Node::ImmutableArray do
|
|
87
113
|
|
88
114
|
before do
|
89
115
|
@immutable_array = Chef::Node::ImmutableArray.new(%w[foo bar baz] + Array(1..3) + [nil, true, false, [ "el", 0, nil ] ])
|
116
|
+
immutable_mash = Chef::Node::ImmutableMash.new({:m => 'm'})
|
117
|
+
@immutable_nested_array = Chef::Node::ImmutableArray.new(["level1",@immutable_array, immutable_mash])
|
90
118
|
end
|
91
119
|
|
92
120
|
##
|
@@ -139,5 +167,32 @@ describe Chef::Node::ImmutableArray do
|
|
139
167
|
mutable[0] = :value
|
140
168
|
mutable[0].should == :value
|
141
169
|
end
|
170
|
+
|
171
|
+
describe "to_a" do
|
172
|
+
before do
|
173
|
+
@copy = @immutable_nested_array.to_a
|
174
|
+
end
|
175
|
+
|
176
|
+
it "converts an immutable array to a new mutable array" do
|
177
|
+
@copy.should be_instance_of(Array)
|
178
|
+
end
|
179
|
+
|
180
|
+
it "converts an immutable nested array to a new mutable array" do
|
181
|
+
@copy[1].should be_instance_of(Array)
|
182
|
+
end
|
183
|
+
|
184
|
+
it "converts an immutable nested mash to a new mutable hash" do
|
185
|
+
@copy[2].should be_instance_of(Hash)
|
186
|
+
end
|
187
|
+
|
188
|
+
it "should create an array with the same content" do
|
189
|
+
@copy.should == @immutable_nested_array
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'should allow mutation' do
|
193
|
+
lambda { @copy << 'm' }.should_not raise_error(Chef::Exceptions::ImmutableAttributeModification)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
142
197
|
end
|
143
198
|
|
data/spec/unit/node_spec.rb
CHANGED
@@ -724,6 +724,15 @@ describe Chef::Node do
|
|
724
724
|
json.should =~ /\"run_list\":\[\"role\[Cthulu\]\",\"role\[Hastur\]\"\]/
|
725
725
|
end
|
726
726
|
|
727
|
+
it "should serialize the correct run list", :json => true do
|
728
|
+
node.run_list << "role[marxist]"
|
729
|
+
node.run_list << "role[leninist]"
|
730
|
+
node.override_runlist << "role[stalinist]"
|
731
|
+
node.run_list.should be_include("role[stalinist]")
|
732
|
+
json = Chef::JSONCompat.to_json(node)
|
733
|
+
json.should =~ /\"run_list\":\[\"role\[marxist\]\",\"role\[leninist\]\"\]/
|
734
|
+
end
|
735
|
+
|
727
736
|
it "merges the override components into a combined override object" do
|
728
737
|
node.attributes.role_override["role override"] = "role override"
|
729
738
|
node.attributes.env_override["env override"] = "env override"
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Bryan McLellan <btm@loftninjas.org>
|
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
|
+
|
21
|
+
describe "Chef::Platform#windows_server_2003?" do
|
22
|
+
it "returns false early when not on windows" do
|
23
|
+
Chef::Platform.stub(:windows?).and_return(false)
|
24
|
+
expect(Chef::Platform).not_to receive(:require)
|
25
|
+
expect(Chef::Platform.windows_server_2003?).to be_false
|
26
|
+
end
|
27
|
+
|
28
|
+
# CHEF-4888: Need to call WIN32OLE.ole_initialize in new threads
|
29
|
+
it "does not raise an exception" do
|
30
|
+
expect { Thread.fork { Chef::Platform.windows_server_2003? }.join }.not_to raise_error
|
31
|
+
end
|
32
|
+
end
|
data/spec/unit/platform_spec.rb
CHANGED
@@ -37,7 +37,8 @@ describe "Chef::Platform supports" do
|
|
37
37
|
:mswin,
|
38
38
|
:mingw32,
|
39
39
|
:windows,
|
40
|
-
:gcel
|
40
|
+
:gcel,
|
41
|
+
:ibm_powerkvm
|
41
42
|
].each do |platform|
|
42
43
|
it "#{platform}" do
|
43
44
|
Chef::Platform.platforms.should have_key(platform)
|
@@ -47,209 +48,226 @@ end
|
|
47
48
|
|
48
49
|
describe Chef::Platform do
|
49
50
|
|
50
|
-
|
51
|
-
@original_platform_map = Chef::Platform.platforms
|
52
|
-
end
|
51
|
+
context "while testing with fake data" do
|
53
52
|
|
54
|
-
|
55
|
-
|
56
|
-
|
53
|
+
before :all do
|
54
|
+
@original_platform_map = Chef::Platform.platforms
|
55
|
+
end
|
57
56
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
57
|
+
after :all do ||
|
58
|
+
Chef::Platform.platforms = @original_platform_map
|
59
|
+
end
|
60
|
+
|
61
|
+
before(:each) do
|
62
|
+
Chef::Platform.platforms = {
|
63
|
+
:darwin => {
|
64
|
+
">= 10.11" => {
|
65
|
+
:file => "new_darwinian"
|
66
|
+
},
|
67
|
+
"9.2.2" => {
|
68
|
+
:file => "darwinian",
|
69
|
+
:else => "thing"
|
70
|
+
},
|
71
|
+
:default => {
|
72
|
+
:file => "old school",
|
73
|
+
:snicker => "snack"
|
74
|
+
}
|
63
75
|
},
|
64
|
-
|
65
|
-
:file => "darwinian",
|
66
|
-
:else => "thing"
|
76
|
+
:mars_volta => {
|
67
77
|
},
|
68
78
|
:default => {
|
69
|
-
:file =>
|
70
|
-
:
|
79
|
+
:file => Chef::Provider::File,
|
80
|
+
:pax => "brittania",
|
81
|
+
:cat => "nice"
|
71
82
|
}
|
72
|
-
},
|
73
|
-
:mars_volta => {
|
74
|
-
},
|
75
|
-
:default => {
|
76
|
-
:file => Chef::Provider::File,
|
77
|
-
:pax => "brittania",
|
78
|
-
:cat => "nice"
|
79
83
|
}
|
80
|
-
|
81
|
-
|
82
|
-
end
|
84
|
+
@events = Chef::EventDispatch::Dispatcher.new
|
85
|
+
end
|
83
86
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
87
|
+
it "should allow you to look up a platform by name and version, returning the provider map for it" do
|
88
|
+
pmap = Chef::Platform.find("Darwin", "9.2.2")
|
89
|
+
pmap.should be_a_kind_of(Hash)
|
90
|
+
pmap[:file].should eql("darwinian")
|
91
|
+
end
|
89
92
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
93
|
+
it "should allow you to look up a platform by name and version using \"greater than\" style operators" do
|
94
|
+
pmap = Chef::Platform.find("Darwin", "11.1.0")
|
95
|
+
pmap.should be_a_kind_of(Hash)
|
96
|
+
pmap[:file].should eql("new_darwinian")
|
97
|
+
end
|
95
98
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
99
|
+
it "should use the default providers for an os if the specific version does not exist" do
|
100
|
+
pmap = Chef::Platform.find("Darwin", "1")
|
101
|
+
pmap.should be_a_kind_of(Hash)
|
102
|
+
pmap[:file].should eql("old school")
|
103
|
+
end
|
101
104
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
105
|
+
it "should use the default providers if the os doesn't give me a default, but does exist" do
|
106
|
+
pmap = Chef::Platform.find("mars_volta", "1")
|
107
|
+
pmap.should be_a_kind_of(Hash)
|
108
|
+
pmap[:file].should eql(Chef::Provider::File)
|
109
|
+
end
|
107
110
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
111
|
+
it "should use the default provider if the os does not exist" do
|
112
|
+
pmap = Chef::Platform.find("AIX", "1")
|
113
|
+
pmap.should be_a_kind_of(Hash)
|
114
|
+
pmap[:file].should eql(Chef::Provider::File)
|
115
|
+
end
|
113
116
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
117
|
+
it "should merge the defaults for an os with the specific version" do
|
118
|
+
pmap = Chef::Platform.find("Darwin", "9.2.2")
|
119
|
+
pmap[:file].should eql("darwinian")
|
120
|
+
pmap[:snicker].should eql("snack")
|
121
|
+
end
|
119
122
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
123
|
+
it "should merge the defaults for an os with the universal defaults" do
|
124
|
+
pmap = Chef::Platform.find("Darwin", "9.2.2")
|
125
|
+
pmap[:file].should eql("darwinian")
|
126
|
+
pmap[:pax].should eql("brittania")
|
127
|
+
end
|
125
128
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
+
it "should allow you to look up a provider for a platform directly by symbol" do
|
130
|
+
Chef::Platform.find_provider("Darwin", "9.2.2", :file).should eql("darwinian")
|
131
|
+
end
|
129
132
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
+
it "should raise an exception if a provider cannot be found for a resource type" do
|
134
|
+
lambda { Chef::Platform.find_provider("Darwin", "9.2.2", :coffee) }.should raise_error(ArgumentError)
|
135
|
+
end
|
133
136
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
137
|
+
it "should look up a provider for a resource with a Chef::Resource object" do
|
138
|
+
kitty = Chef::Resource::Cat.new("loulou")
|
139
|
+
Chef::Platform.find_provider("Darwin", "9.2.2", kitty).should eql("nice")
|
140
|
+
end
|
138
141
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
142
|
+
it "should look up a provider with a node and a Chef::Resource object" do
|
143
|
+
kitty = Chef::Resource::Cat.new("loulou")
|
144
|
+
node = Chef::Node.new
|
145
|
+
node.name("Intel")
|
146
|
+
node.automatic_attrs[:platform] = "mac_os_x"
|
147
|
+
node.automatic_attrs[:platform_version] = "9.2.2"
|
148
|
+
Chef::Platform.find_provider_for_node(node, kitty).should eql("nice")
|
149
|
+
end
|
147
150
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
+
it "should not throw an exception when the platform version has an unknown format" do
|
152
|
+
Chef::Platform.find_provider(:darwin, "bad-version", :file).should eql("old school")
|
153
|
+
end
|
151
154
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
155
|
+
it "should prefer an explicit provider" do
|
156
|
+
kitty = Chef::Resource::Cat.new("loulou")
|
157
|
+
kitty.stub(:provider).and_return(Chef::Provider::File)
|
158
|
+
node = Chef::Node.new
|
159
|
+
node.name("Intel")
|
160
|
+
node.automatic_attrs[:platform] = "mac_os_x"
|
161
|
+
node.automatic_attrs[:platform_version] = "9.2.2"
|
162
|
+
Chef::Platform.find_provider_for_node(node, kitty).should eql(Chef::Provider::File)
|
163
|
+
end
|
161
164
|
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
165
|
+
it "should look up a provider based on the resource name if nothing else matches" do
|
166
|
+
kitty = Chef::Resource::Cat.new("loulou")
|
167
|
+
class Chef::Provider::Cat < Chef::Provider; end
|
168
|
+
Chef::Platform.platforms[:default].delete(:cat)
|
169
|
+
node = Chef::Node.new
|
170
|
+
node.name("Intel")
|
171
|
+
node.automatic_attrs[:platform] = "mac_os_x"
|
172
|
+
node.automatic_attrs[:platform_version] = "8.5"
|
173
|
+
Chef::Platform.find_provider_for_node(node, kitty).should eql(Chef::Provider::Cat)
|
174
|
+
end
|
172
175
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
176
|
+
def setup_file_resource
|
177
|
+
node = Chef::Node.new
|
178
|
+
node.automatic_attrs[:platform] = "mac_os_x"
|
179
|
+
node.automatic_attrs[:platform_version] = "9.2.2"
|
180
|
+
run_context = Chef::RunContext.new(node, {}, @events)
|
181
|
+
[ Chef::Resource::File.new("whateva", run_context), run_context ]
|
182
|
+
end
|
180
183
|
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
184
|
+
it "returns a provider object given a Chef::Resource object which has a valid run context and an action" do
|
185
|
+
file, run_context = setup_file_resource
|
186
|
+
provider = Chef::Platform.provider_for_resource(file, :foo)
|
187
|
+
provider.should be_an_instance_of(Chef::Provider::File)
|
188
|
+
provider.new_resource.should equal(file)
|
189
|
+
provider.run_context.should equal(run_context)
|
190
|
+
end
|
188
191
|
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
192
|
+
it "returns a provider object given a Chef::Resource object which has a valid run context without an action" do
|
193
|
+
file, run_context = setup_file_resource
|
194
|
+
provider = Chef::Platform.provider_for_resource(file)
|
195
|
+
provider.should be_an_instance_of(Chef::Provider::File)
|
196
|
+
provider.new_resource.should equal(file)
|
197
|
+
provider.run_context.should equal(run_context)
|
198
|
+
end
|
196
199
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
200
|
+
it "raises an error when trying to find the provider for a resource with no run context" do
|
201
|
+
file = Chef::Resource::File.new("whateva")
|
202
|
+
lambda {Chef::Platform.provider_for_resource(file)}.should raise_error(ArgumentError)
|
203
|
+
end
|
201
204
|
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
+
it "does not support finding a provider by resource and node -- a run context is required" do
|
206
|
+
lambda {Chef::Platform.provider_for_node('node', 'resource')}.should raise_error(NotImplementedError)
|
207
|
+
end
|
208
|
+
|
209
|
+
it "should update the provider map with map" do
|
210
|
+
Chef::Platform.set(
|
211
|
+
:platform => :darwin,
|
212
|
+
:version => "9.2.2",
|
213
|
+
:resource => :file,
|
214
|
+
:provider => "masterful"
|
215
|
+
)
|
216
|
+
Chef::Platform.platforms[:darwin]["9.2.2"][:file].should eql("masterful")
|
217
|
+
Chef::Platform.set(
|
218
|
+
:platform => :darwin,
|
219
|
+
:resource => :file,
|
220
|
+
:provider => "masterful"
|
221
|
+
)
|
222
|
+
Chef::Platform.platforms[:darwin][:default][:file].should eql("masterful")
|
223
|
+
Chef::Platform.set(
|
224
|
+
:resource => :file,
|
225
|
+
:provider => "masterful"
|
226
|
+
)
|
227
|
+
Chef::Platform.platforms[:default][:file].should eql("masterful")
|
228
|
+
|
229
|
+
Chef::Platform.set(
|
230
|
+
:platform => :hero,
|
231
|
+
:version => "9.2.2",
|
232
|
+
:resource => :file,
|
233
|
+
:provider => "masterful"
|
234
|
+
)
|
235
|
+
Chef::Platform.platforms[:hero]["9.2.2"][:file].should eql("masterful")
|
236
|
+
|
237
|
+
Chef::Platform.set(
|
238
|
+
:resource => :file,
|
239
|
+
:provider => "masterful"
|
240
|
+
)
|
241
|
+
Chef::Platform.platforms[:default][:file].should eql("masterful")
|
242
|
+
|
243
|
+
Chef::Platform.platforms = {}
|
244
|
+
|
245
|
+
Chef::Platform.set(
|
246
|
+
:resource => :file,
|
247
|
+
:provider => "masterful"
|
248
|
+
)
|
249
|
+
Chef::Platform.platforms[:default][:file].should eql("masterful")
|
250
|
+
|
251
|
+
Chef::Platform.platforms = { :neurosis => {} }
|
252
|
+
Chef::Platform.set(:platform => :neurosis, :resource => :package, :provider => "masterful")
|
253
|
+
Chef::Platform.platforms[:neurosis][:default][:package].should eql("masterful")
|
205
254
|
|
206
|
-
|
207
|
-
Chef::Platform.set(
|
208
|
-
:platform => :darwin,
|
209
|
-
:version => "9.2.2",
|
210
|
-
:resource => :file,
|
211
|
-
:provider => "masterful"
|
212
|
-
)
|
213
|
-
Chef::Platform.platforms[:darwin]["9.2.2"][:file].should eql("masterful")
|
214
|
-
Chef::Platform.set(
|
215
|
-
:platform => :darwin,
|
216
|
-
:resource => :file,
|
217
|
-
:provider => "masterful"
|
218
|
-
)
|
219
|
-
Chef::Platform.platforms[:darwin][:default][:file].should eql("masterful")
|
220
|
-
Chef::Platform.set(
|
221
|
-
:resource => :file,
|
222
|
-
:provider => "masterful"
|
223
|
-
)
|
224
|
-
Chef::Platform.platforms[:default][:file].should eql("masterful")
|
225
|
-
|
226
|
-
Chef::Platform.set(
|
227
|
-
:platform => :hero,
|
228
|
-
:version => "9.2.2",
|
229
|
-
:resource => :file,
|
230
|
-
:provider => "masterful"
|
231
|
-
)
|
232
|
-
Chef::Platform.platforms[:hero]["9.2.2"][:file].should eql("masterful")
|
233
|
-
|
234
|
-
Chef::Platform.set(
|
235
|
-
:resource => :file,
|
236
|
-
:provider => "masterful"
|
237
|
-
)
|
238
|
-
Chef::Platform.platforms[:default][:file].should eql("masterful")
|
239
|
-
|
240
|
-
Chef::Platform.platforms = {}
|
241
|
-
|
242
|
-
Chef::Platform.set(
|
243
|
-
:resource => :file,
|
244
|
-
:provider => "masterful"
|
245
|
-
)
|
246
|
-
Chef::Platform.platforms[:default][:file].should eql("masterful")
|
247
|
-
|
248
|
-
Chef::Platform.platforms = { :neurosis => {} }
|
249
|
-
Chef::Platform.set(:platform => :neurosis, :resource => :package, :provider => "masterful")
|
250
|
-
Chef::Platform.platforms[:neurosis][:default][:package].should eql("masterful")
|
255
|
+
end
|
251
256
|
|
252
257
|
end
|
253
258
|
|
259
|
+
context "while testing the configured platform data" do
|
260
|
+
|
261
|
+
it "should use the solaris package provider on Solaris <11" do
|
262
|
+
pmap = Chef::Platform.find("Solaris2", "5.9")
|
263
|
+
pmap[:package].should eql(Chef::Provider::Package::Solaris)
|
264
|
+
end
|
265
|
+
|
266
|
+
it "should use the IPS package provider on Solaris 11" do
|
267
|
+
pmap = Chef::Platform.find("Solaris2", "5.11")
|
268
|
+
pmap[:package].should eql(Chef::Provider::Package::Ips)
|
269
|
+
end
|
270
|
+
|
271
|
+
end
|
254
272
|
|
255
273
|
end
|