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