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
@@ -0,0 +1,584 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Steven Danna (steve@opscode.com)
|
3
|
+
# Copyright:: Copyright (c) 2012 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/user_v1'
|
22
|
+
require 'tempfile'
|
23
|
+
|
24
|
+
describe Chef::UserV1 do
|
25
|
+
before(:each) do
|
26
|
+
@user = Chef::UserV1.new
|
27
|
+
end
|
28
|
+
|
29
|
+
shared_examples_for "string fields with no contraints" do
|
30
|
+
it "should let you set the public key" do
|
31
|
+
expect(@user.send(method, "some_string")).to eq("some_string")
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should return the current public key" do
|
35
|
+
@user.send(method, "some_string")
|
36
|
+
expect(@user.send(method)).to eq("some_string")
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should throw an ArgumentError if you feed it something lame" do
|
40
|
+
expect { @user.send(method, Hash.new) }.to raise_error(ArgumentError)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
shared_examples_for "boolean fields with no constraints" do
|
45
|
+
it "should let you set the field" do
|
46
|
+
expect(@user.send(method, true)).to eq(true)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should return the current field value" do
|
50
|
+
@user.send(method, true)
|
51
|
+
expect(@user.send(method)).to eq(true)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should return the false value when false" do
|
55
|
+
@user.send(method, false)
|
56
|
+
expect(@user.send(method)).to eq(false)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should throw an ArgumentError if you feed it anything but true or false" do
|
60
|
+
expect { @user.send(method, Hash.new) }.to raise_error(ArgumentError)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "initialize" do
|
65
|
+
it "should be a Chef::UserV1" do
|
66
|
+
expect(@user).to be_a_kind_of(Chef::UserV1)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "username" do
|
71
|
+
it "should let you set the username to a string" do
|
72
|
+
expect(@user.username("ops_master")).to eq("ops_master")
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should return the current username" do
|
76
|
+
@user.username "ops_master"
|
77
|
+
expect(@user.username).to eq("ops_master")
|
78
|
+
end
|
79
|
+
|
80
|
+
# It is not feasible to check all invalid characters. Here are a few
|
81
|
+
# that we probably care about.
|
82
|
+
it "should not accept invalid characters" do
|
83
|
+
# capital letters
|
84
|
+
expect { @user.username "Bar" }.to raise_error(ArgumentError)
|
85
|
+
# slashes
|
86
|
+
expect { @user.username "foo/bar" }.to raise_error(ArgumentError)
|
87
|
+
# ?
|
88
|
+
expect { @user.username "foo?" }.to raise_error(ArgumentError)
|
89
|
+
# &
|
90
|
+
expect { @user.username "foo&" }.to raise_error(ArgumentError)
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
it "should not accept spaces" do
|
95
|
+
expect { @user.username "ops master" }.to raise_error(ArgumentError)
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should throw an ArgumentError if you feed it anything but a string" do
|
99
|
+
expect { @user.username Hash.new }.to raise_error(ArgumentError)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe "boolean fields" do
|
104
|
+
describe "create_key" do
|
105
|
+
it_should_behave_like "boolean fields with no constraints" do
|
106
|
+
let(:method) { :create_key }
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe "string fields" do
|
112
|
+
describe "public_key" do
|
113
|
+
it_should_behave_like "string fields with no contraints" do
|
114
|
+
let(:method) { :public_key }
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe "private_key" do
|
119
|
+
it_should_behave_like "string fields with no contraints" do
|
120
|
+
let(:method) { :private_key }
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe "display_name" do
|
125
|
+
it_should_behave_like "string fields with no contraints" do
|
126
|
+
let(:method) { :display_name }
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe "first_name" do
|
131
|
+
it_should_behave_like "string fields with no contraints" do
|
132
|
+
let(:method) { :first_name }
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe "middle_name" do
|
137
|
+
it_should_behave_like "string fields with no contraints" do
|
138
|
+
let(:method) { :middle_name }
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
describe "last_name" do
|
143
|
+
it_should_behave_like "string fields with no contraints" do
|
144
|
+
let(:method) { :last_name }
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
describe "email" do
|
149
|
+
it_should_behave_like "string fields with no contraints" do
|
150
|
+
let(:method) { :email }
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
describe "password" do
|
155
|
+
it_should_behave_like "string fields with no contraints" do
|
156
|
+
let(:method) { :password }
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
describe "when serializing to JSON" do
|
162
|
+
before(:each) do
|
163
|
+
@user.username("black")
|
164
|
+
@json = @user.to_json
|
165
|
+
end
|
166
|
+
|
167
|
+
it "serializes as a JSON object" do
|
168
|
+
expect(@json).to match(/^\{.+\}$/)
|
169
|
+
end
|
170
|
+
|
171
|
+
it "includes the username value" do
|
172
|
+
expect(@json).to include(%q{"username":"black"})
|
173
|
+
end
|
174
|
+
|
175
|
+
it "includes the display name when present" do
|
176
|
+
@user.display_name("get_displayed")
|
177
|
+
expect(@user.to_json).to include(%{"display_name":"get_displayed"})
|
178
|
+
end
|
179
|
+
|
180
|
+
it "does not include the display name if not present" do
|
181
|
+
expect(@json).not_to include("display_name")
|
182
|
+
end
|
183
|
+
|
184
|
+
it "includes the first name when present" do
|
185
|
+
@user.first_name("char")
|
186
|
+
expect(@user.to_json).to include(%{"first_name":"char"})
|
187
|
+
end
|
188
|
+
|
189
|
+
it "does not include the first name if not present" do
|
190
|
+
expect(@json).not_to include("first_name")
|
191
|
+
end
|
192
|
+
|
193
|
+
it "includes the middle name when present" do
|
194
|
+
@user.middle_name("man")
|
195
|
+
expect(@user.to_json).to include(%{"middle_name":"man"})
|
196
|
+
end
|
197
|
+
|
198
|
+
it "does not include the middle name if not present" do
|
199
|
+
expect(@json).not_to include("middle_name")
|
200
|
+
end
|
201
|
+
|
202
|
+
it "includes the last name when present" do
|
203
|
+
@user.last_name("der")
|
204
|
+
expect(@user.to_json).to include(%{"last_name":"der"})
|
205
|
+
end
|
206
|
+
|
207
|
+
it "does not include the last name if not present" do
|
208
|
+
expect(@json).not_to include("last_name")
|
209
|
+
end
|
210
|
+
|
211
|
+
it "includes the email when present" do
|
212
|
+
@user.email("charmander@pokemon.poke")
|
213
|
+
expect(@user.to_json).to include(%{"email":"charmander@pokemon.poke"})
|
214
|
+
end
|
215
|
+
|
216
|
+
it "does not include the email if not present" do
|
217
|
+
expect(@json).not_to include("email")
|
218
|
+
end
|
219
|
+
|
220
|
+
it "includes the public key when present" do
|
221
|
+
@user.public_key("crowes")
|
222
|
+
expect(@user.to_json).to include(%{"public_key":"crowes"})
|
223
|
+
end
|
224
|
+
|
225
|
+
it "does not include the public key if not present" do
|
226
|
+
expect(@json).not_to include("public_key")
|
227
|
+
end
|
228
|
+
|
229
|
+
it "includes the private key when present" do
|
230
|
+
@user.private_key("monkeypants")
|
231
|
+
expect(@user.to_json).to include(%q{"private_key":"monkeypants"})
|
232
|
+
end
|
233
|
+
|
234
|
+
it "does not include the private key if not present" do
|
235
|
+
expect(@json).not_to include("private_key")
|
236
|
+
end
|
237
|
+
|
238
|
+
it "includes the password if present" do
|
239
|
+
@user.password "password"
|
240
|
+
expect(@user.to_json).to include(%q{"password":"password"})
|
241
|
+
end
|
242
|
+
|
243
|
+
it "does not include the password if not present" do
|
244
|
+
expect(@json).not_to include("password")
|
245
|
+
end
|
246
|
+
|
247
|
+
include_examples "to_json equivalent to Chef::JSONCompat.to_json" do
|
248
|
+
let(:jsonable) { @user }
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
describe "when deserializing from JSON" do
|
253
|
+
before(:each) do
|
254
|
+
user = {
|
255
|
+
"username" => "mr_spinks",
|
256
|
+
"display_name" => "displayed",
|
257
|
+
"first_name" => "char",
|
258
|
+
"middle_name" => "man",
|
259
|
+
"last_name" => "der",
|
260
|
+
"email" => "charmander@pokemon.poke",
|
261
|
+
"password" => "password",
|
262
|
+
"public_key" => "turtles",
|
263
|
+
"private_key" => "pandas",
|
264
|
+
"create_key" => false
|
265
|
+
}
|
266
|
+
@user = Chef::UserV1.from_json(Chef::JSONCompat.to_json(user))
|
267
|
+
end
|
268
|
+
|
269
|
+
it "should deserialize to a Chef::UserV1 object" do
|
270
|
+
expect(@user).to be_a_kind_of(Chef::UserV1)
|
271
|
+
end
|
272
|
+
|
273
|
+
it "preserves the username" do
|
274
|
+
expect(@user.username).to eq("mr_spinks")
|
275
|
+
end
|
276
|
+
|
277
|
+
it "preserves the display name if present" do
|
278
|
+
expect(@user.display_name).to eq("displayed")
|
279
|
+
end
|
280
|
+
|
281
|
+
it "preserves the first name if present" do
|
282
|
+
expect(@user.first_name).to eq("char")
|
283
|
+
end
|
284
|
+
|
285
|
+
it "preserves the middle name if present" do
|
286
|
+
expect(@user.middle_name).to eq("man")
|
287
|
+
end
|
288
|
+
|
289
|
+
it "preserves the last name if present" do
|
290
|
+
expect(@user.last_name).to eq("der")
|
291
|
+
end
|
292
|
+
|
293
|
+
it "preserves the email if present" do
|
294
|
+
expect(@user.email).to eq("charmander@pokemon.poke")
|
295
|
+
end
|
296
|
+
|
297
|
+
it "includes the password if present" do
|
298
|
+
expect(@user.password).to eq("password")
|
299
|
+
end
|
300
|
+
|
301
|
+
it "preserves the public key if present" do
|
302
|
+
expect(@user.public_key).to eq("turtles")
|
303
|
+
end
|
304
|
+
|
305
|
+
it "includes the private key if present" do
|
306
|
+
expect(@user.private_key).to eq("pandas")
|
307
|
+
end
|
308
|
+
|
309
|
+
it "includes the create key status if not nil" do
|
310
|
+
expect(@user.create_key).to be_falsey
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
describe "Versioned API Interactions" do
|
315
|
+
let(:response_406) { OpenStruct.new(:code => '406') }
|
316
|
+
let(:exception_406) { Net::HTTPServerException.new("406 Not Acceptable", response_406) }
|
317
|
+
|
318
|
+
before (:each) do
|
319
|
+
@user = Chef::UserV1.new
|
320
|
+
allow(@user).to receive(:chef_root_rest_v0).and_return(double('chef rest root v0 object'))
|
321
|
+
allow(@user).to receive(:chef_root_rest_v1).and_return(double('chef rest root v1 object'))
|
322
|
+
end
|
323
|
+
|
324
|
+
describe "update" do
|
325
|
+
before do
|
326
|
+
# populate all fields that are valid between V0 and V1
|
327
|
+
@user.username "some_username"
|
328
|
+
@user.display_name "some_display_name"
|
329
|
+
@user.first_name "some_first_name"
|
330
|
+
@user.middle_name "some_middle_name"
|
331
|
+
@user.last_name "some_last_name"
|
332
|
+
@user.email "some_email"
|
333
|
+
@user.password "some_password"
|
334
|
+
end
|
335
|
+
|
336
|
+
let(:payload) {
|
337
|
+
{
|
338
|
+
:username => "some_username",
|
339
|
+
:display_name => "some_display_name",
|
340
|
+
:first_name => "some_first_name",
|
341
|
+
:middle_name => "some_middle_name",
|
342
|
+
:last_name => "some_last_name",
|
343
|
+
:email => "some_email",
|
344
|
+
:password => "some_password"
|
345
|
+
}
|
346
|
+
}
|
347
|
+
|
348
|
+
context "when server API V1 is valid on the Chef Server receiving the request" do
|
349
|
+
context "when the user submits valid data" do
|
350
|
+
it "properly updates the user" do
|
351
|
+
expect(@user.chef_root_rest_v1).to receive(:put).with("users/some_username", payload).and_return({})
|
352
|
+
@user.update
|
353
|
+
end
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
context "when server API V1 is not valid on the Chef Server receiving the request" do
|
358
|
+
let(:payload) {
|
359
|
+
{
|
360
|
+
:username => "some_username",
|
361
|
+
:display_name => "some_display_name",
|
362
|
+
:first_name => "some_first_name",
|
363
|
+
:middle_name => "some_middle_name",
|
364
|
+
:last_name => "some_last_name",
|
365
|
+
:email => "some_email",
|
366
|
+
:password => "some_password",
|
367
|
+
:public_key => "some_public_key"
|
368
|
+
}
|
369
|
+
}
|
370
|
+
|
371
|
+
before do
|
372
|
+
@user.public_key "some_public_key"
|
373
|
+
allow(@user.chef_root_rest_v1).to receive(:put)
|
374
|
+
end
|
375
|
+
|
376
|
+
context "when the server returns a 400" do
|
377
|
+
let(:response_400) { OpenStruct.new(:code => '400') }
|
378
|
+
let(:exception_400) { Net::HTTPServerException.new("400 Bad Request", response_400) }
|
379
|
+
|
380
|
+
context "when the 400 was due to public / private key fields no longer being supported" do
|
381
|
+
let(:response_body_400) { '{"error":["Since Server API v1, all keys must be updated via the keys endpoint. "]}' }
|
382
|
+
|
383
|
+
before do
|
384
|
+
allow(response_400).to receive(:body).and_return(response_body_400)
|
385
|
+
allow(@user.chef_root_rest_v1).to receive(:put).and_raise(exception_400)
|
386
|
+
end
|
387
|
+
|
388
|
+
it "proceeds with the V0 PUT since it can handle public / private key fields" do
|
389
|
+
expect(@user.chef_root_rest_v0).to receive(:put).with("users/some_username", payload).and_return({})
|
390
|
+
@user.update
|
391
|
+
end
|
392
|
+
|
393
|
+
it "does not call server_client_api_version_intersection, since we know to proceed with V0 in this case" do
|
394
|
+
expect(@user).to_not receive(:server_client_api_version_intersection)
|
395
|
+
allow(@user.chef_root_rest_v0).to receive(:put).and_return({})
|
396
|
+
@user.update
|
397
|
+
end
|
398
|
+
end # when the 400 was due to public / private key fields
|
399
|
+
|
400
|
+
context "when the 400 was NOT due to public / private key fields no longer being supported" do
|
401
|
+
let(:response_body_400) { '{"error":["Some other error. "]}' }
|
402
|
+
|
403
|
+
before do
|
404
|
+
allow(response_400).to receive(:body).and_return(response_body_400)
|
405
|
+
allow(@user.chef_root_rest_v1).to receive(:put).and_raise(exception_400)
|
406
|
+
end
|
407
|
+
|
408
|
+
it "will not proceed with the V0 PUT since the original bad request was not key related" do
|
409
|
+
expect(@user.chef_root_rest_v0).to_not receive(:put).with("users/some_username", payload)
|
410
|
+
expect { @user.update }.to raise_error(exception_400)
|
411
|
+
end
|
412
|
+
|
413
|
+
it "raises the original error" do
|
414
|
+
expect { @user.update }.to raise_error(exception_400)
|
415
|
+
end
|
416
|
+
|
417
|
+
end
|
418
|
+
end # when the server returns a 400
|
419
|
+
|
420
|
+
context "when the server returns a 406" do
|
421
|
+
# from spec/support/shared/unit/api_versioning.rb
|
422
|
+
it_should_behave_like "version handling" do
|
423
|
+
let(:object) { @user }
|
424
|
+
let(:method) { :update }
|
425
|
+
let(:http_verb) { :put }
|
426
|
+
let(:rest_v1) { @user.chef_root_rest_v1 }
|
427
|
+
end
|
428
|
+
|
429
|
+
context "when the server supports API V0" do
|
430
|
+
before do
|
431
|
+
allow(@user).to receive(:server_client_api_version_intersection).and_return([0])
|
432
|
+
allow(@user.chef_root_rest_v1).to receive(:put).and_raise(exception_406)
|
433
|
+
end
|
434
|
+
|
435
|
+
it "properly updates the user" do
|
436
|
+
expect(@user.chef_root_rest_v0).to receive(:put).with("users/some_username", payload).and_return({})
|
437
|
+
@user.update
|
438
|
+
end
|
439
|
+
end # when the server supports API V0
|
440
|
+
end # when the server returns a 406
|
441
|
+
|
442
|
+
end # when server API V1 is not valid on the Chef Server receiving the request
|
443
|
+
end # update
|
444
|
+
|
445
|
+
describe "create" do
|
446
|
+
let(:payload) {
|
447
|
+
{
|
448
|
+
:username => "some_username",
|
449
|
+
:display_name => "some_display_name",
|
450
|
+
:first_name => "some_first_name",
|
451
|
+
:last_name => "some_last_name",
|
452
|
+
:email => "some_email",
|
453
|
+
:password => "some_password"
|
454
|
+
}
|
455
|
+
}
|
456
|
+
before do
|
457
|
+
@user.username "some_username"
|
458
|
+
@user.display_name "some_display_name"
|
459
|
+
@user.first_name "some_first_name"
|
460
|
+
@user.last_name "some_last_name"
|
461
|
+
@user.email "some_email"
|
462
|
+
@user.password "some_password"
|
463
|
+
end
|
464
|
+
|
465
|
+
# from spec/support/shared/unit/user_and_client_shared.rb
|
466
|
+
it_should_behave_like "user or client create" do
|
467
|
+
let(:object) { @user }
|
468
|
+
let(:error) { Chef::Exceptions::InvalidUserAttribute }
|
469
|
+
let(:rest_v0) { @user.chef_root_rest_v0 }
|
470
|
+
let(:rest_v1) { @user.chef_root_rest_v1 }
|
471
|
+
let(:url) { "users" }
|
472
|
+
end
|
473
|
+
|
474
|
+
context "when handling API V1" do
|
475
|
+
it "creates a new user via the API with a middle_name when it exists" do
|
476
|
+
@user.middle_name "some_middle_name"
|
477
|
+
expect(@user.chef_root_rest_v1).to receive(:post).with("users", payload.merge({:middle_name => "some_middle_name"})).and_return({})
|
478
|
+
@user.create
|
479
|
+
end
|
480
|
+
end # when server API V1 is valid on the Chef Server receiving the request
|
481
|
+
|
482
|
+
context "when API V1 is not supported by the server" do
|
483
|
+
# from spec/support/shared/unit/api_versioning.rb
|
484
|
+
it_should_behave_like "version handling" do
|
485
|
+
let(:object) { @user }
|
486
|
+
let(:method) { :create }
|
487
|
+
let(:http_verb) { :post }
|
488
|
+
let(:rest_v1) { @user.chef_root_rest_v1 }
|
489
|
+
end
|
490
|
+
end
|
491
|
+
|
492
|
+
context "when handling API V0" do
|
493
|
+
before do
|
494
|
+
allow(@user).to receive(:server_client_api_version_intersection).and_return([0])
|
495
|
+
allow(@user.chef_root_rest_v1).to receive(:post).and_raise(exception_406)
|
496
|
+
end
|
497
|
+
|
498
|
+
it "creates a new user via the API with a middle_name when it exists" do
|
499
|
+
@user.middle_name "some_middle_name"
|
500
|
+
expect(@user.chef_root_rest_v0).to receive(:post).with("users", payload.merge({:middle_name => "some_middle_name"})).and_return({})
|
501
|
+
@user.create
|
502
|
+
end
|
503
|
+
end # when server API V1 is not valid on the Chef Server receiving the request
|
504
|
+
|
505
|
+
end # create
|
506
|
+
|
507
|
+
# DEPRECATION
|
508
|
+
# This can be removed after API V0 support is gone
|
509
|
+
describe "reregister" do
|
510
|
+
let(:payload) {
|
511
|
+
{
|
512
|
+
"username" => "some_username",
|
513
|
+
}
|
514
|
+
}
|
515
|
+
|
516
|
+
before do
|
517
|
+
@user.username "some_username"
|
518
|
+
end
|
519
|
+
|
520
|
+
context "when server API V0 is valid on the Chef Server receiving the request" do
|
521
|
+
it "creates a new object via the API" do
|
522
|
+
expect(@user.chef_root_rest_v0).to receive(:put).with("users/#{@user.username}", payload.merge({"private_key" => true})).and_return({})
|
523
|
+
@user.reregister
|
524
|
+
end
|
525
|
+
end # when server API V0 is valid on the Chef Server receiving the request
|
526
|
+
|
527
|
+
context "when server API V0 is not supported by the Chef Server" do
|
528
|
+
# from spec/support/shared/unit/api_versioning.rb
|
529
|
+
it_should_behave_like "user and client reregister" do
|
530
|
+
let(:object) { @user }
|
531
|
+
let(:rest_v0) { @user.chef_root_rest_v0 }
|
532
|
+
end
|
533
|
+
end # when server API V0 is not supported by the Chef Server
|
534
|
+
end # reregister
|
535
|
+
|
536
|
+
end # Versioned API Interactions
|
537
|
+
|
538
|
+
describe "API Interactions" do
|
539
|
+
before (:each) do
|
540
|
+
@user = Chef::UserV1.new
|
541
|
+
@user.username "foobar"
|
542
|
+
@http_client = double("Chef::REST mock")
|
543
|
+
allow(Chef::REST).to receive(:new).and_return(@http_client)
|
544
|
+
end
|
545
|
+
|
546
|
+
describe "list" do
|
547
|
+
before(:each) do
|
548
|
+
Chef::Config[:chef_server_url] = "http://www.example.com"
|
549
|
+
@osc_response = { "admin" => "http://www.example.com/users/admin"}
|
550
|
+
@ohc_response = [ { "user" => { "username" => "admin" }} ]
|
551
|
+
allow(Chef::UserV1).to receive(:load).with("admin").and_return(@user)
|
552
|
+
@osc_inflated_response = { "admin" => @user }
|
553
|
+
end
|
554
|
+
|
555
|
+
it "lists all clients on an OHC/OPC server" do
|
556
|
+
allow(@http_client).to receive(:get).with("users").and_return(@ohc_response)
|
557
|
+
# We expect that Chef::UserV1.list will give a consistent response
|
558
|
+
# so OHC API responses should be transformed to OSC-style output.
|
559
|
+
expect(Chef::UserV1.list).to eq(@osc_response)
|
560
|
+
end
|
561
|
+
|
562
|
+
it "inflate all clients on an OHC/OPC server" do
|
563
|
+
allow(@http_client).to receive(:get).with("users").and_return(@ohc_response)
|
564
|
+
expect(Chef::UserV1.list(true)).to eq(@osc_inflated_response)
|
565
|
+
end
|
566
|
+
end
|
567
|
+
|
568
|
+
describe "read" do
|
569
|
+
it "loads a named user from the API" do
|
570
|
+
expect(@http_client).to receive(:get).with("users/foobar").and_return({"username" => "foobar", "admin" => true, "public_key" => "pubkey"})
|
571
|
+
user = Chef::UserV1.load("foobar")
|
572
|
+
expect(user.username).to eq("foobar")
|
573
|
+
expect(user.public_key).to eq("pubkey")
|
574
|
+
end
|
575
|
+
end
|
576
|
+
|
577
|
+
describe "destroy" do
|
578
|
+
it "deletes the specified user via the API" do
|
579
|
+
expect(@http_client).to receive(:delete).with("users/foobar")
|
580
|
+
@user.destroy
|
581
|
+
end
|
582
|
+
end
|
583
|
+
end
|
584
|
+
end
|