chef 12.4.0-universal-mingw32 → 12.4.1-universal-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/chef/api_client.rb +31 -129
- data/lib/chef/api_client_v1.rb +325 -0
- data/lib/chef/chef_class.rb +15 -7
- data/lib/chef/chef_fs/file_system/chef_server_root_dir.rb +2 -2
- data/lib/chef/dsl/resources.rb +6 -4
- data/lib/chef/exceptions.rb +2 -2
- data/lib/chef/guard_interpreter/resource_guard_interpreter.rb +2 -1
- data/lib/chef/knife/bootstrap/templates/chef-full.erb +4 -4
- data/lib/chef/knife/client_bulk_delete.rb +2 -2
- data/lib/chef/knife/client_create.rb +4 -4
- data/lib/chef/knife/client_delete.rb +3 -3
- data/lib/chef/knife/client_edit.rb +10 -2
- data/lib/chef/knife/client_list.rb +2 -2
- data/lib/chef/knife/client_reregister.rb +2 -2
- data/lib/chef/knife/client_show.rb +2 -2
- data/lib/chef/knife/osc_user_create.rb +3 -3
- data/lib/chef/knife/osc_user_delete.rb +2 -2
- data/lib/chef/knife/osc_user_edit.rb +3 -3
- data/lib/chef/knife/osc_user_list.rb +2 -2
- data/lib/chef/knife/osc_user_reregister.rb +2 -2
- data/lib/chef/knife/osc_user_show.rb +2 -2
- data/lib/chef/knife/user_create.rb +3 -3
- data/lib/chef/knife/user_delete.rb +4 -4
- data/lib/chef/knife/user_edit.rb +3 -3
- data/lib/chef/knife/user_list.rb +2 -2
- data/lib/chef/knife/user_reregister.rb +2 -2
- data/lib/chef/knife/user_show.rb +2 -2
- data/lib/chef/node_map.rb +14 -18
- data/lib/chef/platform/handler_map.rb +45 -0
- data/lib/chef/platform/priority_map.rb +19 -32
- data/lib/chef/platform/provider_handler_map.rb +29 -0
- data/lib/chef/platform/provider_mapping.rb +3 -2
- data/lib/chef/platform/resource_handler_map.rb +29 -0
- data/lib/chef/platform/resource_priority_map.rb +0 -6
- data/lib/chef/provider.rb +1 -1
- data/lib/chef/provider/dsc_resource.rb +2 -2
- data/lib/chef/provider/dsc_script.rb +1 -1
- data/lib/chef/provider/mount/aix.rb +1 -1
- data/lib/chef/provider/package.rb +0 -31
- data/lib/chef/provider/package/aix.rb +1 -0
- data/lib/chef/provider/package/apt.rb +1 -0
- data/lib/chef/provider/package/homebrew.rb +1 -0
- data/lib/chef/provider/package/ips.rb +1 -0
- data/lib/chef/provider/package/macports.rb +1 -0
- data/lib/chef/provider/package/openbsd.rb +1 -0
- data/lib/chef/provider/package/pacman.rb +1 -0
- data/lib/chef/provider/package/paludis.rb +1 -0
- data/lib/chef/provider/package/portage.rb +2 -0
- data/lib/chef/provider/package/smartos.rb +1 -0
- data/lib/chef/provider/package/solaris.rb +2 -0
- data/lib/chef/provider/package/yum.rb +1 -0
- data/lib/chef/provider/package/zypper.rb +1 -0
- data/lib/chef/provider/service.rb +4 -22
- data/lib/chef/provider/service/debian.rb +2 -0
- data/lib/chef/provider/service/insserv.rb +2 -0
- data/lib/chef/provider/service/invokercd.rb +2 -0
- data/lib/chef/provider/service/openbsd.rb +1 -1
- data/lib/chef/provider/service/redhat.rb +2 -0
- data/lib/chef/provider/service/upstart.rb +3 -0
- data/lib/chef/provider_resolver.rb +59 -53
- data/lib/chef/resource.rb +22 -73
- data/lib/chef/resource/dsc_script.rb +1 -1
- data/lib/chef/resource/ips_package.rb +1 -0
- data/lib/chef/resource/mount.rb +8 -0
- data/lib/chef/resource/openbsd_package.rb +0 -11
- data/lib/chef/resource/solaris_package.rb +1 -4
- data/lib/chef/resource_resolver.rb +54 -26
- data/lib/chef/run_list/versioned_recipe_list.rb +6 -5
- data/lib/chef/user.rb +52 -188
- data/lib/chef/user_v1.rb +335 -0
- data/lib/chef/version.rb +1 -1
- data/spec/data/trusted_certs/opscode.pem +53 -56
- data/spec/functional/provider/whyrun_safe_ruby_block_spec.rb +1 -1
- data/spec/functional/resource/package_spec.rb +0 -2
- data/spec/integration/recipes/recipe_dsl_spec.rb +661 -126
- data/spec/spec_helper.rb +19 -13
- data/spec/support/shared/unit/api_versioning.rb +2 -2
- data/spec/unit/api_client_spec.rb +22 -201
- data/spec/unit/api_client_v1_spec.rb +457 -0
- data/spec/unit/knife/client_bulk_delete_spec.rb +4 -4
- data/spec/unit/knife/client_create_spec.rb +1 -1
- data/spec/unit/knife/client_delete_spec.rb +3 -3
- data/spec/unit/knife/client_edit_spec.rb +14 -1
- data/spec/unit/knife/client_list_spec.rb +1 -1
- data/spec/unit/knife/client_reregister_spec.rb +2 -2
- data/spec/unit/knife/client_show_spec.rb +2 -2
- data/spec/unit/knife/osc_user_create_spec.rb +5 -5
- data/spec/unit/knife/osc_user_delete_spec.rb +1 -1
- data/spec/unit/knife/osc_user_edit_spec.rb +1 -1
- data/spec/unit/knife/osc_user_list_spec.rb +1 -1
- data/spec/unit/knife/osc_user_reregister_spec.rb +1 -1
- data/spec/unit/knife/osc_user_show_spec.rb +1 -1
- data/spec/unit/knife/user_create_spec.rb +1 -1
- data/spec/unit/knife/user_delete_spec.rb +2 -2
- data/spec/unit/knife/user_edit_spec.rb +2 -2
- data/spec/unit/knife/user_list_spec.rb +1 -1
- data/spec/unit/knife/user_reregister_spec.rb +1 -1
- data/spec/unit/knife/user_show_spec.rb +2 -2
- data/spec/unit/lwrp_spec.rb +146 -134
- data/spec/unit/node_map_spec.rb +12 -0
- data/spec/unit/platform_spec.rb +1 -1
- data/spec/unit/provider/deploy_spec.rb +1 -1
- data/spec/unit/provider/dsc_resource_spec.rb +3 -3
- data/spec/unit/provider/dsc_script_spec.rb +2 -2
- data/spec/unit/provider_resolver_spec.rb +170 -135
- data/spec/unit/recipe_spec.rb +3 -3
- data/spec/unit/resource/breakpoint_spec.rb +1 -1
- data/spec/unit/resource/cron_spec.rb +1 -1
- data/spec/unit/resource/directory_spec.rb +1 -1
- data/spec/unit/resource/dsc_resource_spec.rb +1 -1
- data/spec/unit/resource/dsc_script_spec.rb +2 -2
- data/spec/unit/resource/env_spec.rb +1 -1
- data/spec/unit/resource/erl_call_spec.rb +1 -1
- data/spec/unit/resource/file_spec.rb +1 -1
- data/spec/unit/resource/group_spec.rb +1 -1
- data/spec/unit/resource/link_spec.rb +1 -1
- data/spec/unit/resource/mdadm_spec.rb +1 -1
- data/spec/unit/resource/mount_spec.rb +1 -1
- data/spec/unit/resource/ohai_spec.rb +1 -1
- data/spec/unit/resource/registry_key_spec.rb +1 -1
- data/spec/unit/resource/route_spec.rb +1 -1
- data/spec/unit/resource/ruby_block_spec.rb +3 -3
- data/spec/unit/resource/user_spec.rb +1 -1
- data/spec/unit/resource/windows_service_spec.rb +1 -1
- data/spec/unit/resource_resolver_spec.rb +8 -4
- data/spec/unit/resource_spec.rb +89 -3
- data/spec/unit/run_list/versioned_recipe_list_spec.rb +115 -48
- data/spec/unit/user_spec.rb +97 -405
- data/spec/unit/user_v1_spec.rb +584 -0
- metadata +11 -6
- data/lib/chef/osc_user.rb +0 -194
- data/spec/unit/osc_user_spec.rb +0 -276
data/spec/spec_helper.rb
CHANGED
@@ -87,12 +87,14 @@ Dir["spec/support/**/*.rb"].
|
|
87
87
|
OHAI_SYSTEM = Ohai::System.new
|
88
88
|
OHAI_SYSTEM.all_plugins("platform")
|
89
89
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
90
|
+
test_node = Chef::Node.new
|
91
|
+
test_node.automatic['os'] = (OHAI_SYSTEM['os'] || 'unknown_os').dup.freeze
|
92
|
+
test_node.automatic['platform_family'] = (OHAI_SYSTEM['platform_family'] || 'unknown_platform_family').dup.freeze
|
93
|
+
test_node.automatic['platform'] = (OHAI_SYSTEM['platform'] || 'unknown_platform').dup.freeze
|
94
|
+
test_node.automatic['platform_version'] = (OHAI_SYSTEM['platform_version'] || 'unknown_platform_version').dup.freeze
|
95
|
+
TEST_NODE = test_node.freeze
|
96
|
+
TEST_PLATFORM = TEST_NODE['platform']
|
97
|
+
TEST_PLATFORM_VERSION = TEST_NODE['platform_version']
|
96
98
|
|
97
99
|
RSpec.configure do |config|
|
98
100
|
config.include(Matchers)
|
@@ -162,13 +164,17 @@ RSpec.configure do |config|
|
|
162
164
|
config.filter_run_excluding :provider => lambda {|criteria|
|
163
165
|
type, target_provider = criteria.first
|
164
166
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
167
|
+
node = TEST_NODE.dup
|
168
|
+
resource_class = Chef::ResourceResolver.resolve(type, node: node)
|
169
|
+
if resource_class
|
170
|
+
resource = resource_class.new('test', Chef::RunContext.new(node, nil, nil))
|
171
|
+
begin
|
172
|
+
provider = resource.provider_for_action(Array(resource_class.default_action).first)
|
173
|
+
provider.class != target_provider
|
174
|
+
rescue Chef::Exceptions::ProviderNotFound # no provider for platform
|
175
|
+
true
|
176
|
+
end
|
177
|
+
else
|
172
178
|
true
|
173
179
|
end
|
174
180
|
}
|
@@ -26,7 +26,7 @@ shared_examples_for "version handling" do
|
|
26
26
|
allow(rest_v1).to receive(http_verb).and_raise(exception_406)
|
27
27
|
end
|
28
28
|
|
29
|
-
context "when the server does not support the min or max server API version that Chef::
|
29
|
+
context "when the server does not support the min or max server API version that Chef::UserV1 supports" do
|
30
30
|
before do
|
31
31
|
allow(object).to receive(:server_client_api_version_intersection).and_return([])
|
32
32
|
end
|
@@ -34,7 +34,7 @@ shared_examples_for "version handling" do
|
|
34
34
|
it "raises the original exception" do
|
35
35
|
expect{ object.send(method) }.to raise_error(exception_406)
|
36
36
|
end
|
37
|
-
end # when the server does not support the min or max server API version that Chef::
|
37
|
+
end # when the server does not support the min or max server API version that Chef::UserV1 supports
|
38
38
|
end # version handling
|
39
39
|
|
40
40
|
shared_examples_for "user and client reregister" do
|
@@ -21,6 +21,11 @@ require 'spec_helper'
|
|
21
21
|
require 'chef/api_client'
|
22
22
|
require 'tempfile'
|
23
23
|
|
24
|
+
# DEPRECATION NOTE
|
25
|
+
#
|
26
|
+
# This code will be removed in Chef 13 in favor of the code in Chef::ApiClientV1,
|
27
|
+
# which will be moved to this namespace. New development should occur in
|
28
|
+
# Chef::ApiClientV1 until the time before Chef 13.
|
24
29
|
describe Chef::ApiClient do
|
25
30
|
before(:each) do
|
26
31
|
@client = Chef::ApiClient.new
|
@@ -53,20 +58,6 @@ describe Chef::ApiClient do
|
|
53
58
|
expect { @client.admin(Hash.new) }.to raise_error(ArgumentError)
|
54
59
|
end
|
55
60
|
|
56
|
-
it "has an create_key flag attribute" do
|
57
|
-
@client.create_key(true)
|
58
|
-
expect(@client.create_key).to be_truthy
|
59
|
-
end
|
60
|
-
|
61
|
-
it "create_key defaults to false" do
|
62
|
-
expect(@client.create_key).to be_falsey
|
63
|
-
end
|
64
|
-
|
65
|
-
it "allows only boolean values for the create_key flag" do
|
66
|
-
expect { @client.create_key(false) }.not_to raise_error
|
67
|
-
expect { @client.create_key(Hash.new) }.to raise_error(ArgumentError)
|
68
|
-
end
|
69
|
-
|
70
61
|
it "has a 'validator' flag attribute" do
|
71
62
|
@client.validator(true)
|
72
63
|
expect(@client.validator).to be_truthy
|
@@ -129,12 +120,6 @@ describe Chef::ApiClient do
|
|
129
120
|
expect(@json).to include(%q{"validator":false})
|
130
121
|
end
|
131
122
|
|
132
|
-
it "includes the 'create_key' flag when present" do
|
133
|
-
@client.create_key(true)
|
134
|
-
@json = @client.to_json
|
135
|
-
expect(@json).to include(%q{"create_key":true})
|
136
|
-
end
|
137
|
-
|
138
123
|
it "includes the private key when present" do
|
139
124
|
@client.private_key("monkeypants")
|
140
125
|
expect(@client.to_json).to include(%q{"private_key":"monkeypants"})
|
@@ -143,15 +128,11 @@ describe Chef::ApiClient do
|
|
143
128
|
it "does not include the private key if not present" do
|
144
129
|
expect(@json).not_to include("private_key")
|
145
130
|
end
|
146
|
-
|
147
|
-
include_examples "to_json equivalent to Chef::JSONCompat.to_json" do
|
148
|
-
let(:jsonable) { @client }
|
149
|
-
end
|
150
131
|
end
|
151
132
|
|
152
133
|
describe "when deserializing from JSON (string) using ApiClient#from_json" do
|
153
134
|
let(:client_string) do
|
154
|
-
"{\"name\":\"black\",\"public_key\":\"crowes\",\"private_key\":\"monkeypants\",\"admin\":true,\"validator\":true
|
135
|
+
"{\"name\":\"black\",\"public_key\":\"crowes\",\"private_key\":\"monkeypants\",\"admin\":true,\"validator\":true}"
|
155
136
|
end
|
156
137
|
|
157
138
|
let(:client) do
|
@@ -178,10 +159,6 @@ describe Chef::ApiClient do
|
|
178
159
|
expect(client.admin).to be_truthy
|
179
160
|
end
|
180
161
|
|
181
|
-
it "preserves the create_key status" do
|
182
|
-
expect(client.create_key).to be_truthy
|
183
|
-
end
|
184
|
-
|
185
162
|
it "preserves the 'validator' status" do
|
186
163
|
expect(client.validator).to be_truthy
|
187
164
|
end
|
@@ -199,7 +176,6 @@ describe Chef::ApiClient do
|
|
199
176
|
"private_key" => "monkeypants",
|
200
177
|
"admin" => true,
|
201
178
|
"validator" => true,
|
202
|
-
"create_key" => true,
|
203
179
|
"json_class" => "Chef::ApiClient"
|
204
180
|
}
|
205
181
|
end
|
@@ -224,10 +200,6 @@ describe Chef::ApiClient do
|
|
224
200
|
expect(client.admin).to be_truthy
|
225
201
|
end
|
226
202
|
|
227
|
-
it "preserves the create_key status" do
|
228
|
-
expect(client.create_key).to be_truthy
|
229
|
-
end
|
230
|
-
|
231
203
|
it "preserves the 'validator' status" do
|
232
204
|
expect(client.validator).to be_truthy
|
233
205
|
end
|
@@ -243,18 +215,16 @@ describe Chef::ApiClient do
|
|
243
215
|
|
244
216
|
before(:each) do
|
245
217
|
client = {
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
"json_class" => "Chef::ApiClient"
|
218
|
+
"name" => "black",
|
219
|
+
"clientname" => "black",
|
220
|
+
"public_key" => "crowes",
|
221
|
+
"private_key" => "monkeypants",
|
222
|
+
"admin" => true,
|
223
|
+
"validator" => true,
|
224
|
+
"json_class" => "Chef::ApiClient"
|
254
225
|
}
|
255
|
-
|
256
|
-
|
257
|
-
allow(Chef::REST).to receive(:new).and_return(@http_client)
|
226
|
+
@http_client = double("Chef::ServerAPI mock")
|
227
|
+
allow(Chef::ServerAPI).to receive(:new).and_return(@http_client)
|
258
228
|
expect(@http_client).to receive(:get).with("clients/black").and_return(client)
|
259
229
|
@client = Chef::ApiClient.load(client['name'])
|
260
230
|
end
|
@@ -275,10 +245,6 @@ describe Chef::ApiClient do
|
|
275
245
|
expect(@client.admin).to be_a_kind_of(TrueClass)
|
276
246
|
end
|
277
247
|
|
278
|
-
it "preserves the create_key status" do
|
279
|
-
expect(@client.create_key).to be_a_kind_of(TrueClass)
|
280
|
-
end
|
281
|
-
|
282
248
|
it "preserves the 'validator' status" do
|
283
249
|
expect(@client.validator).to be_a_kind_of(TrueClass)
|
284
250
|
end
|
@@ -304,18 +270,13 @@ describe Chef::ApiClient do
|
|
304
270
|
File.open(Chef::Config[:client_key], "r") {|f| f.read.chomp }
|
305
271
|
end
|
306
272
|
|
307
|
-
it "has an HTTP client configured with default credentials" do
|
308
|
-
expect(@client.http_api).to be_a_kind_of(Chef::REST)
|
309
|
-
expect(@client.http_api.client_name).to eq("silent-bob")
|
310
|
-
expect(@client.http_api.signing_key.to_s).to eq(private_key_data)
|
311
|
-
end
|
312
273
|
end
|
313
274
|
|
314
275
|
|
315
276
|
describe "when requesting a new key" do
|
316
277
|
before do
|
317
278
|
@http_client = double("Chef::REST mock")
|
318
|
-
allow(Chef::
|
279
|
+
allow(Chef::ServerAPI).to receive(:new).and_return(@http_client)
|
319
280
|
end
|
320
281
|
|
321
282
|
context "and the client does not exist on the server" do
|
@@ -332,34 +293,24 @@ describe Chef::ApiClient do
|
|
332
293
|
end
|
333
294
|
|
334
295
|
context "and the client exists" do
|
335
|
-
let(:chef_rest_v0_mock) { double('chef rest root v0 object') }
|
336
|
-
let(:payload) {
|
337
|
-
{:name => "lost-my-key", :admin => false, :validator => false, :private_key => true}
|
338
|
-
}
|
339
|
-
|
340
296
|
before do
|
341
297
|
@api_client_without_key = Chef::ApiClient.new
|
342
298
|
@api_client_without_key.name("lost-my-key")
|
343
|
-
|
344
|
-
#allow(@api_client_with_key).to receive(:http_api).and_return(_api_mock)
|
345
|
-
|
346
|
-
allow(chef_rest_v0_mock).to receive(:put).with("clients/lost-my-key", payload).and_return(@api_client_with_key)
|
347
|
-
allow(chef_rest_v0_mock).to receive(:get).with("clients/lost-my-key").and_return(@api_client_without_key)
|
348
|
-
allow(@http_client).to receive(:get).with("clients/lost-my-key").and_return(@api_client_without_key)
|
299
|
+
expect(@http_client).to receive(:get).with("clients/lost-my-key").and_return(@api_client_without_key)
|
349
300
|
end
|
350
301
|
|
302
|
+
|
351
303
|
context "and the client exists on a Chef 11-like server" do
|
352
304
|
before do
|
353
305
|
@api_client_with_key = Chef::ApiClient.new
|
354
306
|
@api_client_with_key.name("lost-my-key")
|
355
307
|
@api_client_with_key.private_key("the new private key")
|
356
|
-
|
308
|
+
expect(@http_client).to receive(:put).
|
309
|
+
with("clients/lost-my-key", :name => "lost-my-key", :admin => false, :validator => false, :private_key => true).
|
310
|
+
and_return(@api_client_with_key)
|
357
311
|
end
|
358
312
|
|
359
313
|
it "returns an ApiClient with a private key" do
|
360
|
-
expect(chef_rest_v0_mock).to receive(:put).with("clients/lost-my-key", payload).
|
361
|
-
and_return(@api_client_with_key)
|
362
|
-
|
363
314
|
response = Chef::ApiClient.reregister("lost-my-key")
|
364
315
|
# no sane == method for ApiClient :'(
|
365
316
|
expect(response).to eq(@api_client_without_key)
|
@@ -372,7 +323,7 @@ describe Chef::ApiClient do
|
|
372
323
|
context "and the client exists on a Chef 10-like server" do
|
373
324
|
before do
|
374
325
|
@api_client_with_key = {"name" => "lost-my-key", "private_key" => "the new private key"}
|
375
|
-
expect(
|
326
|
+
expect(@http_client).to receive(:put).
|
376
327
|
with("clients/lost-my-key", :name => "lost-my-key", :admin => false, :validator => false, :private_key => true).
|
377
328
|
and_return(@api_client_with_key)
|
378
329
|
end
|
@@ -390,134 +341,4 @@ describe Chef::ApiClient do
|
|
390
341
|
|
391
342
|
end
|
392
343
|
end
|
393
|
-
|
394
|
-
describe "Versioned API Interactions" do
|
395
|
-
let(:response_406) { OpenStruct.new(:code => '406') }
|
396
|
-
let(:exception_406) { Net::HTTPServerException.new("406 Not Acceptable", response_406) }
|
397
|
-
let(:payload) {
|
398
|
-
{
|
399
|
-
:name => "some_name",
|
400
|
-
:validator => true,
|
401
|
-
:admin => true
|
402
|
-
}
|
403
|
-
}
|
404
|
-
|
405
|
-
before do
|
406
|
-
@client = Chef::ApiClient.new
|
407
|
-
allow(@client).to receive(:chef_rest_v0).and_return(double('chef rest root v0 object'))
|
408
|
-
allow(@client).to receive(:chef_rest_v1).and_return(double('chef rest root v1 object'))
|
409
|
-
@client.name "some_name"
|
410
|
-
@client.validator true
|
411
|
-
@client.admin true
|
412
|
-
end
|
413
|
-
|
414
|
-
describe "create" do
|
415
|
-
|
416
|
-
# from spec/support/shared/unit/user_and_client_shared.rb
|
417
|
-
it_should_behave_like "user or client create" do
|
418
|
-
let(:object) { @client }
|
419
|
-
let(:error) { Chef::Exceptions::InvalidClientAttribute }
|
420
|
-
let(:rest_v0) { @client.chef_rest_v0 }
|
421
|
-
let(:rest_v1) { @client.chef_rest_v1 }
|
422
|
-
let(:url) { "clients" }
|
423
|
-
end
|
424
|
-
|
425
|
-
context "when API V1 is not supported by the server" do
|
426
|
-
# from spec/support/shared/unit/api_versioning.rb
|
427
|
-
it_should_behave_like "version handling" do
|
428
|
-
let(:object) { @client }
|
429
|
-
let(:method) { :create }
|
430
|
-
let(:http_verb) { :post }
|
431
|
-
let(:rest_v1) { @client.chef_rest_v1 }
|
432
|
-
end
|
433
|
-
end
|
434
|
-
|
435
|
-
end # create
|
436
|
-
|
437
|
-
describe "update" do
|
438
|
-
context "when a valid client is defined" do
|
439
|
-
|
440
|
-
shared_examples_for "client updating" do
|
441
|
-
it "updates the client" do
|
442
|
-
expect(rest). to receive(:put).with("clients/some_name", payload)
|
443
|
-
@client.update
|
444
|
-
end
|
445
|
-
|
446
|
-
context "when only the name field exists" do
|
447
|
-
|
448
|
-
before do
|
449
|
-
# needed since there is no way to set to nil via code
|
450
|
-
@client.instance_variable_set(:@validator, nil)
|
451
|
-
@client.instance_variable_set(:@admin, nil)
|
452
|
-
end
|
453
|
-
|
454
|
-
after do
|
455
|
-
@client.validator true
|
456
|
-
@client.admin true
|
457
|
-
end
|
458
|
-
|
459
|
-
it "updates the client with only the name" do
|
460
|
-
expect(rest). to receive(:put).with("clients/some_name", {:name => "some_name"})
|
461
|
-
@client.update
|
462
|
-
end
|
463
|
-
end
|
464
|
-
|
465
|
-
end
|
466
|
-
|
467
|
-
context "when API V1 is supported by the server" do
|
468
|
-
|
469
|
-
it_should_behave_like "client updating" do
|
470
|
-
let(:rest) { @client.chef_rest_v1 }
|
471
|
-
end
|
472
|
-
|
473
|
-
end # when API V1 is supported by the server
|
474
|
-
|
475
|
-
context "when API V1 is not supported by the server" do
|
476
|
-
context "when no version is supported" do
|
477
|
-
# from spec/support/shared/unit/api_versioning.rb
|
478
|
-
it_should_behave_like "version handling" do
|
479
|
-
let(:object) { @client }
|
480
|
-
let(:method) { :create }
|
481
|
-
let(:http_verb) { :post }
|
482
|
-
let(:rest_v1) { @client.chef_rest_v1 }
|
483
|
-
end
|
484
|
-
end # when no version is supported
|
485
|
-
|
486
|
-
context "when API V0 is supported" do
|
487
|
-
|
488
|
-
before do
|
489
|
-
allow(@client.chef_rest_v1).to receive(:put).and_raise(exception_406)
|
490
|
-
allow(@client).to receive(:server_client_api_version_intersection).and_return([0])
|
491
|
-
end
|
492
|
-
|
493
|
-
it_should_behave_like "client updating" do
|
494
|
-
let(:rest) { @client.chef_rest_v0 }
|
495
|
-
end
|
496
|
-
|
497
|
-
end
|
498
|
-
|
499
|
-
end # when API V1 is not supported by the server
|
500
|
-
end # when a valid client is defined
|
501
|
-
end # update
|
502
|
-
|
503
|
-
# DEPRECATION
|
504
|
-
# This can be removed after API V0 support is gone
|
505
|
-
describe "reregister" do
|
506
|
-
context "when server API V0 is valid on the Chef Server receiving the request" do
|
507
|
-
it "creates a new object via the API" do
|
508
|
-
expect(@client.chef_rest_v0).to receive(:put).with("clients/#{@client.name}", payload.merge({:private_key => true})).and_return({})
|
509
|
-
@client.reregister
|
510
|
-
end
|
511
|
-
end # when server API V0 is valid on the Chef Server receiving the request
|
512
|
-
|
513
|
-
context "when server API V0 is not supported by the Chef Server" do
|
514
|
-
# from spec/support/shared/unit/api_versioning.rb
|
515
|
-
it_should_behave_like "user and client reregister" do
|
516
|
-
let(:object) { @client }
|
517
|
-
let(:rest_v0) { @client.chef_rest_v0 }
|
518
|
-
end
|
519
|
-
end # when server API V0 is not supported by the Chef Server
|
520
|
-
end # reregister
|
521
|
-
|
522
|
-
end
|
523
344
|
end
|
@@ -0,0 +1,457 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Adam Jacob (<adam@opscode.com>)
|
3
|
+
# Copyright:: Copyright (c) 2008 Opscode, 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
|
+
require 'chef/api_client_v1'
|
22
|
+
require 'tempfile'
|
23
|
+
|
24
|
+
describe Chef::ApiClientV1 do
|
25
|
+
before(:each) do
|
26
|
+
@client = Chef::ApiClientV1.new
|
27
|
+
end
|
28
|
+
|
29
|
+
it "has a name attribute" do
|
30
|
+
@client.name("ops_master")
|
31
|
+
expect(@client.name).to eq("ops_master")
|
32
|
+
end
|
33
|
+
|
34
|
+
it "does not allow spaces in the name" do
|
35
|
+
expect { @client.name "ops master" }.to raise_error(ArgumentError)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "only allows string values for the name" do
|
39
|
+
expect { @client.name Hash.new }.to raise_error(ArgumentError)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "has an admin flag attribute" do
|
43
|
+
@client.admin(true)
|
44
|
+
expect(@client.admin).to be_truthy
|
45
|
+
end
|
46
|
+
|
47
|
+
it "defaults to non-admin" do
|
48
|
+
expect(@client.admin).to be_falsey
|
49
|
+
end
|
50
|
+
|
51
|
+
it "allows only boolean values for the admin flag" do
|
52
|
+
expect { @client.admin(false) }.not_to raise_error
|
53
|
+
expect { @client.admin(Hash.new) }.to raise_error(ArgumentError)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "has an create_key flag attribute" do
|
57
|
+
@client.create_key(true)
|
58
|
+
expect(@client.create_key).to be_truthy
|
59
|
+
end
|
60
|
+
|
61
|
+
it "create_key defaults to false" do
|
62
|
+
expect(@client.create_key).to be_falsey
|
63
|
+
end
|
64
|
+
|
65
|
+
it "allows only boolean values for the create_key flag" do
|
66
|
+
expect { @client.create_key(false) }.not_to raise_error
|
67
|
+
expect { @client.create_key(Hash.new) }.to raise_error(ArgumentError)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "has a 'validator' flag attribute" do
|
71
|
+
@client.validator(true)
|
72
|
+
expect(@client.validator).to be_truthy
|
73
|
+
end
|
74
|
+
|
75
|
+
it "defaults to non-validator" do
|
76
|
+
expect(@client.validator).to be_falsey
|
77
|
+
end
|
78
|
+
|
79
|
+
it "allows only boolean values for the 'validator' flag" do
|
80
|
+
expect { @client.validator(false) }.not_to raise_error
|
81
|
+
expect { @client.validator(Hash.new) }.to raise_error(ArgumentError)
|
82
|
+
end
|
83
|
+
|
84
|
+
it "has a public key attribute" do
|
85
|
+
@client.public_key("super public")
|
86
|
+
expect(@client.public_key).to eq("super public")
|
87
|
+
end
|
88
|
+
|
89
|
+
it "accepts only String values for the public key" do
|
90
|
+
expect { @client.public_key "" }.not_to raise_error
|
91
|
+
expect { @client.public_key Hash.new }.to raise_error(ArgumentError)
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
it "has a private key attribute" do
|
96
|
+
@client.private_key("super private")
|
97
|
+
expect(@client.private_key).to eq("super private")
|
98
|
+
end
|
99
|
+
|
100
|
+
it "accepts only String values for the private key" do
|
101
|
+
expect { @client.private_key "" }.not_to raise_error
|
102
|
+
expect { @client.private_key Hash.new }.to raise_error(ArgumentError)
|
103
|
+
end
|
104
|
+
|
105
|
+
describe "when serializing to JSON" do
|
106
|
+
before(:each) do
|
107
|
+
@client.name("black")
|
108
|
+
@client.public_key("crowes")
|
109
|
+
@json = @client.to_json
|
110
|
+
end
|
111
|
+
|
112
|
+
it "serializes as a JSON object" do
|
113
|
+
expect(@json).to match(/^\{.+\}$/)
|
114
|
+
end
|
115
|
+
|
116
|
+
it "includes the name value" do
|
117
|
+
expect(@json).to include(%q{"name":"black"})
|
118
|
+
end
|
119
|
+
|
120
|
+
it "includes the public key value" do
|
121
|
+
expect(@json).to include(%{"public_key":"crowes"})
|
122
|
+
end
|
123
|
+
|
124
|
+
it "includes the 'admin' flag" do
|
125
|
+
expect(@json).to include(%q{"admin":false})
|
126
|
+
end
|
127
|
+
|
128
|
+
it "includes the 'validator' flag" do
|
129
|
+
expect(@json).to include(%q{"validator":false})
|
130
|
+
end
|
131
|
+
|
132
|
+
it "includes the 'create_key' flag when present" do
|
133
|
+
@client.create_key(true)
|
134
|
+
@json = @client.to_json
|
135
|
+
expect(@json).to include(%q{"create_key":true})
|
136
|
+
end
|
137
|
+
|
138
|
+
it "includes the private key when present" do
|
139
|
+
@client.private_key("monkeypants")
|
140
|
+
expect(@client.to_json).to include(%q{"private_key":"monkeypants"})
|
141
|
+
end
|
142
|
+
|
143
|
+
it "does not include the private key if not present" do
|
144
|
+
expect(@json).not_to include("private_key")
|
145
|
+
end
|
146
|
+
|
147
|
+
include_examples "to_json equivalent to Chef::JSONCompat.to_json" do
|
148
|
+
let(:jsonable) { @client }
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
describe "when deserializing from JSON (string) using ApiClient#from_json" do
|
153
|
+
let(:client_string) do
|
154
|
+
"{\"name\":\"black\",\"public_key\":\"crowes\",\"private_key\":\"monkeypants\",\"admin\":true,\"validator\":true,\"create_key\":true}"
|
155
|
+
end
|
156
|
+
|
157
|
+
let(:client) do
|
158
|
+
Chef::ApiClientV1.from_json(client_string)
|
159
|
+
end
|
160
|
+
|
161
|
+
it "does not require a 'json_class' string" do
|
162
|
+
expect(Chef::JSONCompat.parse(client_string)["json_class"]).to eq(nil)
|
163
|
+
end
|
164
|
+
|
165
|
+
it "should deserialize to a Chef::ApiClientV1 object" do
|
166
|
+
expect(client).to be_a_kind_of(Chef::ApiClientV1)
|
167
|
+
end
|
168
|
+
|
169
|
+
it "preserves the name" do
|
170
|
+
expect(client.name).to eq("black")
|
171
|
+
end
|
172
|
+
|
173
|
+
it "preserves the public key" do
|
174
|
+
expect(client.public_key).to eq("crowes")
|
175
|
+
end
|
176
|
+
|
177
|
+
it "preserves the admin status" do
|
178
|
+
expect(client.admin).to be_truthy
|
179
|
+
end
|
180
|
+
|
181
|
+
it "preserves the create_key status" do
|
182
|
+
expect(client.create_key).to be_truthy
|
183
|
+
end
|
184
|
+
|
185
|
+
it "preserves the 'validator' status" do
|
186
|
+
expect(client.validator).to be_truthy
|
187
|
+
end
|
188
|
+
|
189
|
+
it "includes the private key if present" do
|
190
|
+
expect(client.private_key).to eq("monkeypants")
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
describe "when deserializing from JSON (hash) using ApiClientV1#from_json" do
|
195
|
+
let(:client_hash) do
|
196
|
+
{
|
197
|
+
"name" => "black",
|
198
|
+
"public_key" => "crowes",
|
199
|
+
"private_key" => "monkeypants",
|
200
|
+
"admin" => true,
|
201
|
+
"validator" => true,
|
202
|
+
"create_key" => true
|
203
|
+
}
|
204
|
+
end
|
205
|
+
|
206
|
+
let(:client) do
|
207
|
+
Chef::ApiClientV1.from_json(Chef::JSONCompat.to_json(client_hash))
|
208
|
+
end
|
209
|
+
|
210
|
+
it "should deserialize to a Chef::ApiClientV1 object" do
|
211
|
+
expect(client).to be_a_kind_of(Chef::ApiClientV1)
|
212
|
+
end
|
213
|
+
|
214
|
+
it "preserves the name" do
|
215
|
+
expect(client.name).to eq("black")
|
216
|
+
end
|
217
|
+
|
218
|
+
it "preserves the public key" do
|
219
|
+
expect(client.public_key).to eq("crowes")
|
220
|
+
end
|
221
|
+
|
222
|
+
it "preserves the admin status" do
|
223
|
+
expect(client.admin).to be_truthy
|
224
|
+
end
|
225
|
+
|
226
|
+
it "preserves the create_key status" do
|
227
|
+
expect(client.create_key).to be_truthy
|
228
|
+
end
|
229
|
+
|
230
|
+
it "preserves the 'validator' status" do
|
231
|
+
expect(client.validator).to be_truthy
|
232
|
+
end
|
233
|
+
|
234
|
+
it "includes the private key if present" do
|
235
|
+
expect(client.private_key).to eq("monkeypants")
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
describe "when loading from JSON" do
|
240
|
+
before do
|
241
|
+
end
|
242
|
+
|
243
|
+
before(:each) do
|
244
|
+
client = {
|
245
|
+
"name" => "black",
|
246
|
+
"clientname" => "black",
|
247
|
+
"public_key" => "crowes",
|
248
|
+
"private_key" => "monkeypants",
|
249
|
+
"admin" => true,
|
250
|
+
"create_key" => true,
|
251
|
+
"validator" => true
|
252
|
+
}
|
253
|
+
|
254
|
+
@http_client = double("Chef::ServerAPI mock")
|
255
|
+
allow(Chef::ServerAPI).to receive(:new).and_return(@http_client)
|
256
|
+
expect(@http_client).to receive(:get).with("clients/black").and_return(client)
|
257
|
+
@client = Chef::ApiClientV1.load(client['name'])
|
258
|
+
end
|
259
|
+
|
260
|
+
it "should deserialize to a Chef::ApiClientV1 object" do
|
261
|
+
expect(@client).to be_a_kind_of(Chef::ApiClientV1)
|
262
|
+
end
|
263
|
+
|
264
|
+
it "preserves the name" do
|
265
|
+
expect(@client.name).to eq("black")
|
266
|
+
end
|
267
|
+
|
268
|
+
it "preserves the public key" do
|
269
|
+
expect(@client.public_key).to eq("crowes")
|
270
|
+
end
|
271
|
+
|
272
|
+
it "preserves the admin status" do
|
273
|
+
expect(@client.admin).to be_a_kind_of(TrueClass)
|
274
|
+
end
|
275
|
+
|
276
|
+
it "preserves the create_key status" do
|
277
|
+
expect(@client.create_key).to be_a_kind_of(TrueClass)
|
278
|
+
end
|
279
|
+
|
280
|
+
it "preserves the 'validator' status" do
|
281
|
+
expect(@client.validator).to be_a_kind_of(TrueClass)
|
282
|
+
end
|
283
|
+
|
284
|
+
it "includes the private key if present" do
|
285
|
+
expect(@client.private_key).to eq("monkeypants")
|
286
|
+
end
|
287
|
+
|
288
|
+
end
|
289
|
+
|
290
|
+
describe "with correctly configured API credentials" do
|
291
|
+
before do
|
292
|
+
Chef::Config[:node_name] = "silent-bob"
|
293
|
+
Chef::Config[:client_key] = File.expand_path('ssl/private_key.pem', CHEF_SPEC_DATA)
|
294
|
+
end
|
295
|
+
|
296
|
+
after do
|
297
|
+
Chef::Config[:node_name] = nil
|
298
|
+
Chef::Config[:client_key] = nil
|
299
|
+
end
|
300
|
+
|
301
|
+
let :private_key_data do
|
302
|
+
File.open(Chef::Config[:client_key], "r") {|f| f.read.chomp }
|
303
|
+
end
|
304
|
+
|
305
|
+
end
|
306
|
+
|
307
|
+
|
308
|
+
describe "when requesting a new key" do
|
309
|
+
before do
|
310
|
+
@http_client = double("Chef::ServerAPI mock")
|
311
|
+
allow(Chef::ServerAPI).to receive(:new).and_return(@http_client)
|
312
|
+
end
|
313
|
+
|
314
|
+
context "and the client does not exist on the server" do
|
315
|
+
before do
|
316
|
+
@a_404_response = Net::HTTPNotFound.new("404 not found and such", nil, nil)
|
317
|
+
@a_404_exception = Net::HTTPServerException.new("404 not found exception", @a_404_response)
|
318
|
+
|
319
|
+
expect(@http_client).to receive(:get).with("clients/lost-my-key").and_raise(@a_404_exception)
|
320
|
+
end
|
321
|
+
|
322
|
+
it "raises a 404 error" do
|
323
|
+
expect { Chef::ApiClientV1.reregister("lost-my-key") }.to raise_error(Net::HTTPServerException)
|
324
|
+
end
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
describe "Versioned API Interactions" do
|
329
|
+
let(:response_406) { OpenStruct.new(:code => '406') }
|
330
|
+
let(:exception_406) { Net::HTTPServerException.new("406 Not Acceptable", response_406) }
|
331
|
+
let(:payload) {
|
332
|
+
{
|
333
|
+
:name => "some_name",
|
334
|
+
:validator => true,
|
335
|
+
:admin => true
|
336
|
+
}
|
337
|
+
}
|
338
|
+
|
339
|
+
before do
|
340
|
+
@client = Chef::ApiClientV1.new
|
341
|
+
allow(@client).to receive(:chef_rest_v0).and_return(double('chef rest root v0 object'))
|
342
|
+
allow(@client).to receive(:chef_rest_v1).and_return(double('chef rest root v1 object'))
|
343
|
+
@client.name "some_name"
|
344
|
+
@client.validator true
|
345
|
+
@client.admin true
|
346
|
+
end
|
347
|
+
|
348
|
+
describe "create" do
|
349
|
+
|
350
|
+
# from spec/support/shared/unit/user_and_client_shared.rb
|
351
|
+
it_should_behave_like "user or client create" do
|
352
|
+
let(:object) { @client }
|
353
|
+
let(:error) { Chef::Exceptions::InvalidClientAttribute }
|
354
|
+
let(:rest_v0) { @client.chef_rest_v0 }
|
355
|
+
let(:rest_v1) { @client.chef_rest_v1 }
|
356
|
+
let(:url) { "clients" }
|
357
|
+
end
|
358
|
+
|
359
|
+
context "when API V1 is not supported by the server" do
|
360
|
+
# from spec/support/shared/unit/api_versioning.rb
|
361
|
+
it_should_behave_like "version handling" do
|
362
|
+
let(:object) { @client }
|
363
|
+
let(:method) { :create }
|
364
|
+
let(:http_verb) { :post }
|
365
|
+
let(:rest_v1) { @client.chef_rest_v1 }
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
end # create
|
370
|
+
|
371
|
+
describe "update" do
|
372
|
+
context "when a valid client is defined" do
|
373
|
+
|
374
|
+
shared_examples_for "client updating" do
|
375
|
+
it "updates the client" do
|
376
|
+
expect(rest). to receive(:put).with("clients/some_name", payload).and_return(payload)
|
377
|
+
@client.update
|
378
|
+
end
|
379
|
+
|
380
|
+
context "when only the name field exists" do
|
381
|
+
|
382
|
+
before do
|
383
|
+
# needed since there is no way to set to nil via code
|
384
|
+
@client.instance_variable_set(:@validator, nil)
|
385
|
+
@client.instance_variable_set(:@admin, nil)
|
386
|
+
end
|
387
|
+
|
388
|
+
after do
|
389
|
+
@client.validator true
|
390
|
+
@client.admin true
|
391
|
+
end
|
392
|
+
|
393
|
+
it "updates the client with only the name" do
|
394
|
+
expect(rest). to receive(:put).with("clients/some_name", {:name => "some_name"}).and_return({:name => "some_name"})
|
395
|
+
@client.update
|
396
|
+
end
|
397
|
+
end
|
398
|
+
|
399
|
+
end
|
400
|
+
|
401
|
+
context "when API V1 is supported by the server" do
|
402
|
+
|
403
|
+
it_should_behave_like "client updating" do
|
404
|
+
let(:rest) { @client.chef_rest_v1 }
|
405
|
+
end
|
406
|
+
|
407
|
+
end # when API V1 is supported by the server
|
408
|
+
|
409
|
+
context "when API V1 is not supported by the server" do
|
410
|
+
context "when no version is supported" do
|
411
|
+
# from spec/support/shared/unit/api_versioning.rb
|
412
|
+
it_should_behave_like "version handling" do
|
413
|
+
let(:object) { @client }
|
414
|
+
let(:method) { :create }
|
415
|
+
let(:http_verb) { :post }
|
416
|
+
let(:rest_v1) { @client.chef_rest_v1 }
|
417
|
+
end
|
418
|
+
end # when no version is supported
|
419
|
+
|
420
|
+
context "when API V0 is supported" do
|
421
|
+
|
422
|
+
before do
|
423
|
+
allow(@client.chef_rest_v1).to receive(:put).and_raise(exception_406)
|
424
|
+
allow(@client).to receive(:server_client_api_version_intersection).and_return([0])
|
425
|
+
end
|
426
|
+
|
427
|
+
it_should_behave_like "client updating" do
|
428
|
+
let(:rest) { @client.chef_rest_v0 }
|
429
|
+
end
|
430
|
+
|
431
|
+
end
|
432
|
+
|
433
|
+
end # when API V1 is not supported by the server
|
434
|
+
end # when a valid client is defined
|
435
|
+
end # update
|
436
|
+
|
437
|
+
# DEPRECATION
|
438
|
+
# This can be removed after API V0 support is gone
|
439
|
+
describe "reregister" do
|
440
|
+
context "when server API V0 is valid on the Chef Server receiving the request" do
|
441
|
+
it "creates a new object via the API" do
|
442
|
+
expect(@client.chef_rest_v0).to receive(:put).with("clients/#{@client.name}", payload.merge({:private_key => true})).and_return({})
|
443
|
+
@client.reregister
|
444
|
+
end
|
445
|
+
end # when server API V0 is valid on the Chef Server receiving the request
|
446
|
+
|
447
|
+
context "when server API V0 is not supported by the Chef Server" do
|
448
|
+
# from spec/support/shared/unit/api_versioning.rb
|
449
|
+
it_should_behave_like "user and client reregister" do
|
450
|
+
let(:object) { @client }
|
451
|
+
let(:rest_v0) { @client.chef_rest_v0 }
|
452
|
+
end
|
453
|
+
end # when server API V0 is not supported by the Chef Server
|
454
|
+
end # reregister
|
455
|
+
|
456
|
+
end
|
457
|
+
end
|