kitchen-rackspace 0.22.0 → 0.22.1
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/.release-please-manifest.json +1 -1
- data/.rspec +1 -0
- data/CHANGELOG.md +7 -0
- data/CONTRIBUTING.md +33 -1
- data/README.md +28 -6
- data/lib/kitchen/driver/rackspace.rb +25 -3
- data/lib/kitchen/driver/rackspace_version.rb +1 -1
- data/spec/kitchen/driver/rackspace/compute_spec.rb +162 -0
- data/spec/kitchen/driver/rackspace/configuration_spec.rb +210 -0
- data/spec/kitchen/driver/rackspace/create_spec.rb +150 -0
- data/spec/kitchen/driver/rackspace/destroy_spec.rb +63 -0
- data/spec/kitchen/driver/rackspace/image_spec.rb +58 -0
- data/spec/kitchen/driver/rackspace/plugin_spec.rb +14 -0
- data/spec/kitchen/driver/rackspace/server_name_spec.rb +63 -0
- data/spec/kitchen/driver/rackspace/status_spec.rb +151 -0
- data/spec/kitchen/driver/rackspace/tcp_check_spec.rb +37 -0
- data/spec/spec_helper.rb +21 -5
- data/spec/support/driver_context.rb +51 -0
- data/spec/support/rackspace_environment.rb +27 -0
- metadata +14 -3
- data/spec/kitchen/driver/rackspace_spec.rb +0 -785
|
@@ -1,785 +0,0 @@
|
|
|
1
|
-
require_relative "../../spec_helper"
|
|
2
|
-
|
|
3
|
-
describe Kitchen::Driver::Rackspace do
|
|
4
|
-
let(:logged_output) { StringIO.new }
|
|
5
|
-
let(:logger) { Logger.new(logged_output) }
|
|
6
|
-
let(:config) { {} }
|
|
7
|
-
let(:state) { {} }
|
|
8
|
-
let(:platform_name) { "ubuntu" }
|
|
9
|
-
let(:default_networks) { nil }
|
|
10
|
-
let(:instance_name) { "potatoes" }
|
|
11
|
-
|
|
12
|
-
let(:instance) do
|
|
13
|
-
double(
|
|
14
|
-
name: instance_name,
|
|
15
|
-
logger:,
|
|
16
|
-
to_str: "instance",
|
|
17
|
-
platform: double(name: platform_name)
|
|
18
|
-
)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
let(:driver) { described_class.new(config) }
|
|
22
|
-
|
|
23
|
-
before(:each) do
|
|
24
|
-
allow_any_instance_of(described_class).to receive(:instance)
|
|
25
|
-
.and_return(instance)
|
|
26
|
-
ENV["RACKSPACE_USERNAME"] = "user"
|
|
27
|
-
ENV["RACKSPACE_API_KEY"] = "key"
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
describe "plugin metadata" do
|
|
31
|
-
it "declares the driver API version" do
|
|
32
|
-
expect(described_class.instance_variable_get(:@api_version)).to eq(2)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
it "reports its own gem version to kitchen diagnose" do
|
|
36
|
-
expect(driver.diagnose_plugin[:version])
|
|
37
|
-
.to eq(Kitchen::Driver::RACKSPACE_VERSION)
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
describe "#status" do
|
|
42
|
-
let(:server) { double(state: "ACTIVE") }
|
|
43
|
-
let(:servers) { double }
|
|
44
|
-
|
|
45
|
-
before(:each) do
|
|
46
|
-
allow(driver).to receive(:compute).and_return(double(servers:))
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
context "with no server in state" do
|
|
50
|
-
it "reports an unknown status" do
|
|
51
|
-
expect(driver.status({})).to include(live: nil, state: "unknown")
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
context "with a server Rackspace does not know" do
|
|
56
|
-
it "reports an unknown status" do
|
|
57
|
-
expect(servers).to receive(:get).with("gone").and_return(nil)
|
|
58
|
-
|
|
59
|
-
expect(driver.status(server_id: "gone")).to include(state: "unknown")
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
context "with a live server" do
|
|
64
|
-
before(:each) do
|
|
65
|
-
allow(servers).to receive(:get).with("s-1").and_return(server)
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
it "reports the server as live" do
|
|
69
|
-
expect(driver.status(server_id: "s-1")).to include(
|
|
70
|
-
live: true, state: "ACTIVE", source: "driver", resource_id: "s-1"
|
|
71
|
-
)
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
it "stamps when the check happened" do
|
|
75
|
-
expect(driver.status(server_id: "s-1")[:checked_at])
|
|
76
|
-
.to match(/\A\d{4}-\d{2}-\d{2}T/)
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
context "with a server that is not active" do
|
|
81
|
-
it "reports the server as not live" do
|
|
82
|
-
allow(servers).to receive(:get)
|
|
83
|
-
.with("s-1").and_return(double(state: "ERROR"))
|
|
84
|
-
|
|
85
|
-
expect(driver.status(server_id: "s-1"))
|
|
86
|
-
.to include(live: false, state: "ERROR")
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
context "when Rackspace cannot be reached" do
|
|
91
|
-
it "reports an unknown status rather than raising" do
|
|
92
|
-
allow(servers).to receive(:get)
|
|
93
|
-
.and_raise(Fog::Errors::Error.new("boom"))
|
|
94
|
-
|
|
95
|
-
expect(driver.status(server_id: "s-1")).to include(state: "unknown")
|
|
96
|
-
end
|
|
97
|
-
end
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
describe "#doctor" do
|
|
101
|
-
let(:config) do
|
|
102
|
-
{ image_id: "img-1", public_key_path: "/home/user/.ssh/id_rsa.pub" }
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
before(:each) do
|
|
106
|
-
allow(driver).to receive(:compute)
|
|
107
|
-
.and_return(double(servers: double(summary: [])))
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
it "reports no problem when the configuration is complete" do
|
|
111
|
-
expect(driver.doctor(state)).to eq(false)
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
context "with no resolvable image" do
|
|
115
|
-
let(:config) { { public_key_path: "/key.pub" } }
|
|
116
|
-
|
|
117
|
-
it "reports a problem" do
|
|
118
|
-
allow(driver).to receive(:default_image).and_return(nil)
|
|
119
|
-
|
|
120
|
-
expect(driver.doctor(state)).to eq(true)
|
|
121
|
-
expect(logged_output.string).to match(/No image_id is set/)
|
|
122
|
-
end
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
context "with no public key" do
|
|
126
|
-
let(:config) { { image_id: "img-1", public_key_path: nil } }
|
|
127
|
-
|
|
128
|
-
it "reports a problem" do
|
|
129
|
-
expect(driver.doctor(state)).to eq(true)
|
|
130
|
-
expect(logged_output.string).to match(/No public key was found/)
|
|
131
|
-
end
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
context "with credentials Rackspace rejects" do
|
|
135
|
-
it "reports a problem" do
|
|
136
|
-
allow(driver).to receive(:compute)
|
|
137
|
-
.and_raise(Fog::Errors::Error.new("unauthorized"))
|
|
138
|
-
|
|
139
|
-
expect(driver.doctor(state)).to eq(true)
|
|
140
|
-
expect(logged_output.string).to match(/rejected the configured credentials/)
|
|
141
|
-
end
|
|
142
|
-
end
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
describe "#initialize" do
|
|
146
|
-
before(:each) do
|
|
147
|
-
allow(Fog).to receive(:timeout=)
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
context "default options" do
|
|
151
|
-
it "defaults to v2 cloud" do
|
|
152
|
-
expect(driver[:version]).to eq("v2")
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
it "defaults to a 2 GB general purpose flavor" do
|
|
156
|
-
expect(driver[:flavor_id]).to eq("general1-2")
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
it "defaults to local user's SSH public key" do
|
|
160
|
-
path = File.expand_path("~/.ssh/id_rsa.pub")
|
|
161
|
-
expect(File).to receive(:exist?).with(path).and_return(true)
|
|
162
|
-
expect(driver[:public_key_path]).to eq(path)
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
it "defaults to SSH with root user on port 22" do
|
|
166
|
-
expect(driver[:username]).to eq("root")
|
|
167
|
-
expect(driver[:port]).to eq("22")
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
it "defaults to a random server name" do
|
|
171
|
-
expect(driver[:server_name]).to be_a(String)
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
it "defaults to the DFW region" do
|
|
175
|
-
expect(driver[:rackspace_region]).to eq("dfw")
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
it "defaults to username from $RACKSPACE_USERNAME" do
|
|
179
|
-
expect(driver[:rackspace_username]).to eq("user")
|
|
180
|
-
end
|
|
181
|
-
|
|
182
|
-
it "defaults to API key from $RACKSPACE_API_KEY" do
|
|
183
|
-
expect(driver[:rackspace_api_key]).to eq("key")
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
it "defaults to wait_for timeout of 600 seconds" do
|
|
187
|
-
expect(driver[:wait_for]).to eq(600)
|
|
188
|
-
expect(Fog).to have_received(:timeout=).with(600)
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
it "defaults the SSH TCP bypassing to false" do
|
|
192
|
-
expect(driver[:no_ssh_tcp_check]).to eq(false)
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
it "defaults the TCP bypass sleep time to 120 seconds" do
|
|
196
|
-
expect(driver[:no_ssh_tcp_check_sleep]).to eq(120)
|
|
197
|
-
end
|
|
198
|
-
|
|
199
|
-
it "defaults to the standard Rackspace networks" do
|
|
200
|
-
expect(driver[:networks]).to eq(default_networks)
|
|
201
|
-
end
|
|
202
|
-
|
|
203
|
-
it "defaults to not waiting for rackconnect" do
|
|
204
|
-
expect(driver[:rackconnect_wait]).to eq(false)
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
it "defaults to not waiting for managed service level" do
|
|
208
|
-
expect(driver[:servicelevel_wait]).to eq(false)
|
|
209
|
-
end
|
|
210
|
-
|
|
211
|
-
it "defaults to the public ip address" do
|
|
212
|
-
expect(driver[:servicenet]).to eq(false)
|
|
213
|
-
end
|
|
214
|
-
|
|
215
|
-
it "defaults to no_passwd_lock as false" do
|
|
216
|
-
expect(driver[:no_passwd_lock]).to eq(false)
|
|
217
|
-
end
|
|
218
|
-
end
|
|
219
|
-
|
|
220
|
-
platforms = {
|
|
221
|
-
"ubuntu-12.04" => "f2d30a56-bc2b-4906-8027-92f8a45bbb10",
|
|
222
|
-
"ubuntu-12" => "f2d30a56-bc2b-4906-8027-92f8a45bbb10",
|
|
223
|
-
"ubuntu-14.04" => "e6baca58-c5f4-48d3-901a-abdeb0cfe907",
|
|
224
|
-
"ubuntu-14" => "e6baca58-c5f4-48d3-901a-abdeb0cfe907",
|
|
225
|
-
"ubuntu" => "9b3ae961-0ba0-4d5a-973f-2e79043f0ddd",
|
|
226
|
-
"centos-6" => "7d791876-4c8f-44a2-8d4b-e84bfb0b1c8c",
|
|
227
|
-
"centos" => "1a79f262-33d2-428c-924b-9852a6c15ea8",
|
|
228
|
-
}
|
|
229
|
-
platforms.each do |platform, id|
|
|
230
|
-
context "name is #{platform}" do
|
|
231
|
-
let(:platform_name) { platform }
|
|
232
|
-
|
|
233
|
-
it "defaults to the correct image ID" do
|
|
234
|
-
expect(driver[:image_id]).to eq(id)
|
|
235
|
-
end
|
|
236
|
-
end
|
|
237
|
-
end
|
|
238
|
-
|
|
239
|
-
context "overridden options" do
|
|
240
|
-
config = {
|
|
241
|
-
image_id: "22",
|
|
242
|
-
flavor_id: "33",
|
|
243
|
-
public_key_path: "/tmp",
|
|
244
|
-
username: "admin",
|
|
245
|
-
port: "2222",
|
|
246
|
-
server_name: "puppy",
|
|
247
|
-
rackspace_region: "ord",
|
|
248
|
-
wait_for: 1200,
|
|
249
|
-
rackconnect_wait: true,
|
|
250
|
-
servicelevel_wait: true,
|
|
251
|
-
use_private_ip_address: true,
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
let(:config) { config }
|
|
255
|
-
|
|
256
|
-
config.each do |key, value|
|
|
257
|
-
it "it uses the overridden #{key} option" do
|
|
258
|
-
expect(driver[key]).to eq(value)
|
|
259
|
-
end
|
|
260
|
-
end
|
|
261
|
-
|
|
262
|
-
it "sets the new wait_for variable" do
|
|
263
|
-
expect(driver[:wait_for]).to eq(1200)
|
|
264
|
-
expect(Fog).to have_received(:timeout=).with(1200)
|
|
265
|
-
end
|
|
266
|
-
end
|
|
267
|
-
|
|
268
|
-
context "OpenStack environment variables" do
|
|
269
|
-
before(:each) do
|
|
270
|
-
ENV.delete("RACKSPACE_USERNAME")
|
|
271
|
-
ENV.delete("RACKSPACE_API_KEY")
|
|
272
|
-
ENV.delete("RACKSPACE_REGION")
|
|
273
|
-
ENV["OS_USERNAME"] = "os_user"
|
|
274
|
-
ENV["OS_PASSWORD"] = "os_pass"
|
|
275
|
-
ENV["OS_REGION_NAME"] = "os_region"
|
|
276
|
-
end
|
|
277
|
-
|
|
278
|
-
after(:each) do
|
|
279
|
-
ENV.delete("OS_USERNAME")
|
|
280
|
-
ENV.delete("OS_PASSWORD")
|
|
281
|
-
ENV.delete("OS_REGION_NAME")
|
|
282
|
-
end
|
|
283
|
-
|
|
284
|
-
it "gets to username from $OS_USERNAME" do
|
|
285
|
-
expect(driver[:rackspace_username]).to eq("os_user")
|
|
286
|
-
end
|
|
287
|
-
|
|
288
|
-
it "gets to API key from $OS_PASSWORD" do
|
|
289
|
-
expect(driver[:rackspace_api_key]).to eq("os_pass")
|
|
290
|
-
end
|
|
291
|
-
|
|
292
|
-
it "gets to region from $OS_REGION_NAME" do
|
|
293
|
-
expect(driver[:rackspace_region]).to eq("os_region")
|
|
294
|
-
end
|
|
295
|
-
end
|
|
296
|
-
end
|
|
297
|
-
|
|
298
|
-
describe "#create" do
|
|
299
|
-
let(:config) { super().merge(wait_for: "1200") }
|
|
300
|
-
let(:server) do
|
|
301
|
-
double(id: "test123",
|
|
302
|
-
wait_for: true,
|
|
303
|
-
public_ip_address: "1.2.3.4")
|
|
304
|
-
end
|
|
305
|
-
|
|
306
|
-
before(:each) do
|
|
307
|
-
{
|
|
308
|
-
default_name: "a_monkey!",
|
|
309
|
-
create_server: server,
|
|
310
|
-
tcp_check: true,
|
|
311
|
-
}.each do |k, v|
|
|
312
|
-
allow_any_instance_of(described_class).to receive(k).and_return(v)
|
|
313
|
-
end
|
|
314
|
-
end
|
|
315
|
-
|
|
316
|
-
context "username and API key only provided" do
|
|
317
|
-
let(:config) do
|
|
318
|
-
{
|
|
319
|
-
rackspace_username: "hello",
|
|
320
|
-
rackspace_api_key: "world",
|
|
321
|
-
wait_for: 1200,
|
|
322
|
-
}
|
|
323
|
-
end
|
|
324
|
-
|
|
325
|
-
it "generates a server name in the absence of one" do
|
|
326
|
-
driver.create(state)
|
|
327
|
-
expect(driver[:server_name]).to eq("a_monkey!")
|
|
328
|
-
end
|
|
329
|
-
|
|
330
|
-
it "gets a proper server ID" do
|
|
331
|
-
driver.create(state)
|
|
332
|
-
expect(state[:server_id]).to eq("test123")
|
|
333
|
-
end
|
|
334
|
-
|
|
335
|
-
it "gets a proper hostname (IP)" do
|
|
336
|
-
driver.create(state)
|
|
337
|
-
expect(state[:hostname]).to eq("1.2.3.4")
|
|
338
|
-
end
|
|
339
|
-
|
|
340
|
-
it "calls tcp_check" do
|
|
341
|
-
expect(driver).to receive(:tcp_check)
|
|
342
|
-
driver.create(state)
|
|
343
|
-
end
|
|
344
|
-
end
|
|
345
|
-
|
|
346
|
-
context "a Fog error" do
|
|
347
|
-
before(:each) do
|
|
348
|
-
allow_any_instance_of(described_class).to receive(:create_server)
|
|
349
|
-
.and_raise(Fog::Errors::Error, "Uhoh")
|
|
350
|
-
end
|
|
351
|
-
|
|
352
|
-
it "re-raises the error" do
|
|
353
|
-
expect { driver.create(state) }.to raise_error(Kitchen::ActionFailed,
|
|
354
|
-
"Uhoh")
|
|
355
|
-
end
|
|
356
|
-
end
|
|
357
|
-
end
|
|
358
|
-
|
|
359
|
-
describe "#create and rackconnect_wait" do
|
|
360
|
-
let(:server) do
|
|
361
|
-
double(id: "test123",
|
|
362
|
-
wait_for: true,
|
|
363
|
-
public_ip_address: "1.2.3.4",
|
|
364
|
-
private_ip_address: "10.9.8.7",
|
|
365
|
-
update: nil)
|
|
366
|
-
end
|
|
367
|
-
|
|
368
|
-
before(:each) do
|
|
369
|
-
{
|
|
370
|
-
default_name: "a_monkey!",
|
|
371
|
-
create_server: server,
|
|
372
|
-
tcp_check: true,
|
|
373
|
-
}.each do |k, v|
|
|
374
|
-
allow_any_instance_of(described_class).to receive(k).and_return(v)
|
|
375
|
-
end
|
|
376
|
-
end
|
|
377
|
-
|
|
378
|
-
context "username and API key only provided" do
|
|
379
|
-
let(:config) do
|
|
380
|
-
{
|
|
381
|
-
rackspace_username: "hello",
|
|
382
|
-
rackspace_api_key: "world",
|
|
383
|
-
wait_for: 1200,
|
|
384
|
-
rackconnect_wait: true,
|
|
385
|
-
}
|
|
386
|
-
end
|
|
387
|
-
|
|
388
|
-
it "generates a server name in the absence of one" do
|
|
389
|
-
driver.create(state)
|
|
390
|
-
expect(driver[:server_name]).to eq("a_monkey!")
|
|
391
|
-
end
|
|
392
|
-
|
|
393
|
-
it "gets a proper server ID" do
|
|
394
|
-
driver.create(state)
|
|
395
|
-
expect(state[:server_id]).to eq("test123")
|
|
396
|
-
end
|
|
397
|
-
|
|
398
|
-
it "gets a proper hostname (IP)" do
|
|
399
|
-
driver.create(state)
|
|
400
|
-
expect(state[:hostname]).to eq("1.2.3.4")
|
|
401
|
-
end
|
|
402
|
-
|
|
403
|
-
it "calls tcp_check" do
|
|
404
|
-
expect(driver).to receive(:tcp_check)
|
|
405
|
-
driver.create(state)
|
|
406
|
-
end
|
|
407
|
-
|
|
408
|
-
it "calls rackconnect_check " do
|
|
409
|
-
expect(driver).to receive(:rackconnect_check)
|
|
410
|
-
driver.create(state)
|
|
411
|
-
end
|
|
412
|
-
|
|
413
|
-
it "rackconnect_check waits for rackconnect_automation" do
|
|
414
|
-
expect(server).to receive(:wait_for)
|
|
415
|
-
driver.send(:rackconnect_check, server)
|
|
416
|
-
end
|
|
417
|
-
end
|
|
418
|
-
end
|
|
419
|
-
|
|
420
|
-
describe "#create and servicelevel_wait" do
|
|
421
|
-
let(:server) do
|
|
422
|
-
double(id: "test123",
|
|
423
|
-
wait_for: true,
|
|
424
|
-
public_ip_address: "1.2.3.4",
|
|
425
|
-
private_ip_address: "10.9.8.7",
|
|
426
|
-
update: nil)
|
|
427
|
-
end
|
|
428
|
-
|
|
429
|
-
before(:each) do
|
|
430
|
-
{
|
|
431
|
-
default_name: "a_monkey!",
|
|
432
|
-
create_server: server,
|
|
433
|
-
tcp_check: true,
|
|
434
|
-
}.each do |k, v|
|
|
435
|
-
allow_any_instance_of(described_class).to receive(k).and_return(v)
|
|
436
|
-
end
|
|
437
|
-
end
|
|
438
|
-
|
|
439
|
-
context "username and API key only provided" do
|
|
440
|
-
let(:config) do
|
|
441
|
-
{
|
|
442
|
-
rackspace_username: "hello",
|
|
443
|
-
rackspace_api_key: "world",
|
|
444
|
-
wait_for: 1200,
|
|
445
|
-
servicelevel_wait: true,
|
|
446
|
-
}
|
|
447
|
-
end
|
|
448
|
-
|
|
449
|
-
it "generates a server name in the absence of one" do
|
|
450
|
-
driver.create(state)
|
|
451
|
-
expect(driver[:server_name]).to eq("a_monkey!")
|
|
452
|
-
end
|
|
453
|
-
|
|
454
|
-
it "gets a proper server ID" do
|
|
455
|
-
driver.create(state)
|
|
456
|
-
expect(state[:server_id]).to eq("test123")
|
|
457
|
-
end
|
|
458
|
-
|
|
459
|
-
it "gets a proper hostname (IP)" do
|
|
460
|
-
driver.create(state)
|
|
461
|
-
expect(state[:hostname]).to eq("1.2.3.4")
|
|
462
|
-
end
|
|
463
|
-
|
|
464
|
-
it "calls tcp_check" do
|
|
465
|
-
expect(driver).to receive(:tcp_check)
|
|
466
|
-
driver.create(state)
|
|
467
|
-
end
|
|
468
|
-
|
|
469
|
-
it "calls servicelevel_check " do
|
|
470
|
-
expect(driver).to receive(:servicelevel_check)
|
|
471
|
-
driver.create(state)
|
|
472
|
-
end
|
|
473
|
-
|
|
474
|
-
it "servicelevel_check waits for managed service level automation" do
|
|
475
|
-
expect(server).to receive(:wait_for)
|
|
476
|
-
driver.send(:servicelevel_check, server)
|
|
477
|
-
end
|
|
478
|
-
end
|
|
479
|
-
end
|
|
480
|
-
|
|
481
|
-
describe "#create and use_private_ip_address" do
|
|
482
|
-
let(:server) do
|
|
483
|
-
double(id: "test123",
|
|
484
|
-
wait_for: true,
|
|
485
|
-
public_ip_address: "1.2.3.4",
|
|
486
|
-
private_ip_address: "10.9.8.7")
|
|
487
|
-
end
|
|
488
|
-
|
|
489
|
-
before(:each) do
|
|
490
|
-
{
|
|
491
|
-
default_name: "a_monkey!",
|
|
492
|
-
create_server: server,
|
|
493
|
-
tcp_check: true,
|
|
494
|
-
}.each do |k, v|
|
|
495
|
-
allow_any_instance_of(described_class).to receive(k).and_return(v)
|
|
496
|
-
end
|
|
497
|
-
end
|
|
498
|
-
|
|
499
|
-
context "username and API key only provided" do
|
|
500
|
-
let(:config) do
|
|
501
|
-
{
|
|
502
|
-
rackspace_username: "hello",
|
|
503
|
-
rackspace_api_key: "world",
|
|
504
|
-
wait_for: 1200,
|
|
505
|
-
servicenet: true,
|
|
506
|
-
}
|
|
507
|
-
end
|
|
508
|
-
|
|
509
|
-
it "generates a server name in the absence of one" do
|
|
510
|
-
driver.create(state)
|
|
511
|
-
expect(driver[:server_name]).to eq("a_monkey!")
|
|
512
|
-
end
|
|
513
|
-
|
|
514
|
-
it "gets a proper server ID" do
|
|
515
|
-
driver.create(state)
|
|
516
|
-
expect(state[:server_id]).to eq("test123")
|
|
517
|
-
end
|
|
518
|
-
|
|
519
|
-
it "gets a private ip as the hostname" do
|
|
520
|
-
driver.create(state)
|
|
521
|
-
expect(state[:hostname]).to eq("10.9.8.7")
|
|
522
|
-
end
|
|
523
|
-
end
|
|
524
|
-
end
|
|
525
|
-
|
|
526
|
-
describe "#destroy" do
|
|
527
|
-
let(:server_id) { "12345" }
|
|
528
|
-
let(:hostname) { "example.com" }
|
|
529
|
-
let(:state) { { server_id:, hostname: } }
|
|
530
|
-
let(:server) { double(nil?: false, destroy: true) }
|
|
531
|
-
let(:servers) { double(get: server) }
|
|
532
|
-
let(:compute) { double(servers:) }
|
|
533
|
-
|
|
534
|
-
before(:each) do
|
|
535
|
-
allow_any_instance_of(described_class).to receive(:compute)
|
|
536
|
-
.and_return(compute)
|
|
537
|
-
end
|
|
538
|
-
|
|
539
|
-
context "a live server that needs to be destroyed" do
|
|
540
|
-
it "destroys the server" do
|
|
541
|
-
expect(state).to receive(:delete).with(:server_id)
|
|
542
|
-
expect(state).to receive(:delete).with(:hostname)
|
|
543
|
-
driver.destroy(state)
|
|
544
|
-
end
|
|
545
|
-
end
|
|
546
|
-
|
|
547
|
-
context "no server ID present" do
|
|
548
|
-
let(:state) { {} }
|
|
549
|
-
|
|
550
|
-
it "does nothing" do
|
|
551
|
-
allow(driver).to receive(:compute)
|
|
552
|
-
expect(driver).to_not receive(:compute)
|
|
553
|
-
expect(state).to_not receive(:delete)
|
|
554
|
-
driver.destroy(state)
|
|
555
|
-
end
|
|
556
|
-
end
|
|
557
|
-
|
|
558
|
-
context "a server that was already destroyed" do
|
|
559
|
-
let(:servers) do
|
|
560
|
-
s = double("servers")
|
|
561
|
-
allow(s).to receive(:get).with("12345").and_return(nil)
|
|
562
|
-
s
|
|
563
|
-
end
|
|
564
|
-
let(:compute) { double(servers:) }
|
|
565
|
-
|
|
566
|
-
before(:each) do
|
|
567
|
-
allow_any_instance_of(described_class).to receive(:compute)
|
|
568
|
-
.and_return(compute)
|
|
569
|
-
end
|
|
570
|
-
|
|
571
|
-
it "does not try to destroy the server again" do
|
|
572
|
-
allow_message_expectations_on_nil
|
|
573
|
-
driver.destroy(state)
|
|
574
|
-
end
|
|
575
|
-
end
|
|
576
|
-
end
|
|
577
|
-
|
|
578
|
-
describe "#compute" do
|
|
579
|
-
let(:config) do
|
|
580
|
-
{
|
|
581
|
-
rackspace_username: "monkey",
|
|
582
|
-
rackspace_api_key: "potato",
|
|
583
|
-
rackspace_region: "ord",
|
|
584
|
-
}
|
|
585
|
-
end
|
|
586
|
-
|
|
587
|
-
context "all requirements provided" do
|
|
588
|
-
it "creates a new compute connection" do
|
|
589
|
-
allow(Fog::Compute).to receive(:new) { |arg| arg }
|
|
590
|
-
res = config.merge(provider: "Rackspace", version: "v2")
|
|
591
|
-
expect(driver.send(:compute)).to eq(res)
|
|
592
|
-
end
|
|
593
|
-
end
|
|
594
|
-
|
|
595
|
-
context "no username provided" do
|
|
596
|
-
let(:config) do
|
|
597
|
-
{ rackspace_username: nil, rackspace_api_key: "1234" }
|
|
598
|
-
end
|
|
599
|
-
|
|
600
|
-
it "raises an error" do
|
|
601
|
-
expect { driver.send(:compute) }.to raise_error(ArgumentError)
|
|
602
|
-
end
|
|
603
|
-
end
|
|
604
|
-
|
|
605
|
-
context "no API key provided" do
|
|
606
|
-
let(:config) do
|
|
607
|
-
{ rackspace_username: "monkey", rackspace_api_key: nil }
|
|
608
|
-
end
|
|
609
|
-
|
|
610
|
-
it "raises an error" do
|
|
611
|
-
expect { driver.send(:compute) }.to raise_error(ArgumentError)
|
|
612
|
-
end
|
|
613
|
-
end
|
|
614
|
-
end
|
|
615
|
-
|
|
616
|
-
describe "#create_server" do
|
|
617
|
-
let(:config) do
|
|
618
|
-
{
|
|
619
|
-
server_name: "hello",
|
|
620
|
-
image_id: "there",
|
|
621
|
-
flavor_id: "captain",
|
|
622
|
-
public_key_path: "tarpals",
|
|
623
|
-
no_passwd_lock: false,
|
|
624
|
-
networks: default_networks,
|
|
625
|
-
user_data: nil,
|
|
626
|
-
config_drive: false,
|
|
627
|
-
}
|
|
628
|
-
end
|
|
629
|
-
before(:each) do
|
|
630
|
-
@expected = config.merge(name: config[:server_name])
|
|
631
|
-
@expected.delete_if do |k, _|
|
|
632
|
-
k == :server_name
|
|
633
|
-
end
|
|
634
|
-
end
|
|
635
|
-
let(:servers) do
|
|
636
|
-
s = double("servers")
|
|
637
|
-
allow(s).to receive(:bootstrap) { |arg| arg }
|
|
638
|
-
s
|
|
639
|
-
end
|
|
640
|
-
let(:compute) { double(servers:) }
|
|
641
|
-
|
|
642
|
-
before(:each) do
|
|
643
|
-
allow_any_instance_of(described_class).to receive(:compute)
|
|
644
|
-
.and_return(compute)
|
|
645
|
-
end
|
|
646
|
-
|
|
647
|
-
it "creates the server using a compute connection" do
|
|
648
|
-
expect(driver.send(:create_server)).to eq(@expected)
|
|
649
|
-
end
|
|
650
|
-
|
|
651
|
-
context "additional networks specified" do
|
|
652
|
-
let(:server_id) { "12345" }
|
|
653
|
-
let(:server) do
|
|
654
|
-
double(id: "test123", wait_for: true,
|
|
655
|
-
public_ip_address: "1.2.3.4")
|
|
656
|
-
end
|
|
657
|
-
let(:hostname) { "example.com" }
|
|
658
|
-
let(:servers) { double("servers", bootstrap: server) }
|
|
659
|
-
let(:compute) { double(Fog::Compute, servers:) }
|
|
660
|
-
let(:state) { { server_id:, hostname: } }
|
|
661
|
-
let(:user_specified_network) { "bob_dole" }
|
|
662
|
-
let(:config) do
|
|
663
|
-
{
|
|
664
|
-
rackspace_username: "monkey",
|
|
665
|
-
rackspace_api_key: "potato",
|
|
666
|
-
rackspace_region: "ord",
|
|
667
|
-
networks: [user_specified_network],
|
|
668
|
-
}
|
|
669
|
-
end
|
|
670
|
-
|
|
671
|
-
before(:each) do
|
|
672
|
-
{ wait_for_sshd: true, compute: }.each do |k, v|
|
|
673
|
-
allow_any_instance_of(described_class).to receive(k).and_return(v)
|
|
674
|
-
end
|
|
675
|
-
end
|
|
676
|
-
|
|
677
|
-
it "has the user specified network, plus default Rackspace networks" do
|
|
678
|
-
driver.send(:create_server)
|
|
679
|
-
expect(servers).to have_received(:bootstrap) do |arg|
|
|
680
|
-
expect(arg[:networks][2]).to eq user_specified_network
|
|
681
|
-
end
|
|
682
|
-
end
|
|
683
|
-
end
|
|
684
|
-
end
|
|
685
|
-
|
|
686
|
-
describe "#default_name" do
|
|
687
|
-
let(:login) { "user" }
|
|
688
|
-
let(:hostname) { "host" }
|
|
689
|
-
|
|
690
|
-
before(:each) do
|
|
691
|
-
allow(Etc).to receive(:getlogin).and_return(login)
|
|
692
|
-
allow(Socket).to receive(:gethostname).and_return(hostname)
|
|
693
|
-
end
|
|
694
|
-
|
|
695
|
-
it "generates a name" do
|
|
696
|
-
expect(driver.send(:default_name)).to match(/^potatoes-user-host-(\S*)/)
|
|
697
|
-
end
|
|
698
|
-
|
|
699
|
-
context "local node with a long hostname" do
|
|
700
|
-
let(:hostname) { "ab.c" * 20 }
|
|
701
|
-
|
|
702
|
-
it "limits the generated name to 63 characters" do
|
|
703
|
-
expect(driver.send(:default_name).length).to be <= 63
|
|
704
|
-
end
|
|
705
|
-
end
|
|
706
|
-
|
|
707
|
-
context "node with a long hostname, username, and base name" do
|
|
708
|
-
let(:login) { "abcd" * 20 }
|
|
709
|
-
let(:hostname) { "efgh" * 20 }
|
|
710
|
-
let(:instance_name) { "ijkl" * 20 }
|
|
711
|
-
|
|
712
|
-
it "limits the generated name to 63 characters" do
|
|
713
|
-
expect(driver.send(:default_name).length).to eq(63)
|
|
714
|
-
end
|
|
715
|
-
end
|
|
716
|
-
|
|
717
|
-
context "a login and hostname with punctuation in them" do
|
|
718
|
-
let(:login) { "some.u-se-r" }
|
|
719
|
-
let(:hostname) { "a.host-name" }
|
|
720
|
-
let(:instance_name) { "a.instance-name" }
|
|
721
|
-
|
|
722
|
-
it "strips out the dots to prevent bad server names" do
|
|
723
|
-
expect(driver.send(:default_name)).to_not include(".")
|
|
724
|
-
end
|
|
725
|
-
|
|
726
|
-
it "strips out all but the three hyphen separators" do
|
|
727
|
-
expect(driver.send(:default_name).count("-")).to eq(3)
|
|
728
|
-
end
|
|
729
|
-
end
|
|
730
|
-
|
|
731
|
-
context "a non-login shell" do
|
|
732
|
-
let(:login) { nil }
|
|
733
|
-
|
|
734
|
-
it "subs in a placeholder login string" do
|
|
735
|
-
expect(driver.send(:default_name)).to match(/^potatoes-nologin-/)
|
|
736
|
-
end
|
|
737
|
-
end
|
|
738
|
-
end
|
|
739
|
-
|
|
740
|
-
describe "#tcp_check" do
|
|
741
|
-
before(:each) do
|
|
742
|
-
allow_any_instance_of(described_class).to receive(:wait_for_sshd)
|
|
743
|
-
allow_any_instance_of(described_class).to receive(:sleep)
|
|
744
|
-
end
|
|
745
|
-
|
|
746
|
-
context "the default non-skipping behavior" do
|
|
747
|
-
it "uses Kitchen's own SSH check" do
|
|
748
|
-
expect(driver).to receive(:wait_for_sshd)
|
|
749
|
-
expect(driver).to_not receive(:sleep)
|
|
750
|
-
driver.send(:tcp_check, state)
|
|
751
|
-
end
|
|
752
|
-
end
|
|
753
|
-
|
|
754
|
-
context "a config set to wait instead of TCP check" do
|
|
755
|
-
let(:config) { { no_ssh_tcp_check: true } }
|
|
756
|
-
|
|
757
|
-
it "uses a sleep instead of a port check" do
|
|
758
|
-
expect(driver).to_not receive(:wait_for_sshd)
|
|
759
|
-
expect(driver).to receive(:sleep)
|
|
760
|
-
driver.send(:tcp_check, state)
|
|
761
|
-
end
|
|
762
|
-
end
|
|
763
|
-
end
|
|
764
|
-
|
|
765
|
-
describe "#networks" do
|
|
766
|
-
context "the default Rackspace networks" do
|
|
767
|
-
it "returns nil so Fog will use the defaults" do
|
|
768
|
-
expect(driver.send(:networks)).to eq(nil)
|
|
769
|
-
end
|
|
770
|
-
end
|
|
771
|
-
|
|
772
|
-
context "a custom Rackspace network" do
|
|
773
|
-
let(:config) { { networks: %w{abcdefg} } }
|
|
774
|
-
|
|
775
|
-
it "returns the base networks plus the custom one" do
|
|
776
|
-
expected = %w{
|
|
777
|
-
00000000-0000-0000-0000-000000000000
|
|
778
|
-
11111111-1111-1111-1111-111111111111
|
|
779
|
-
abcdefg
|
|
780
|
-
}
|
|
781
|
-
expect(driver.send(:networks)).to eq(expected)
|
|
782
|
-
end
|
|
783
|
-
end
|
|
784
|
-
end
|
|
785
|
-
end
|