kitchen-google 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +8 -0
- data/kitchen-google.gemspec +1 -1
- data/lib/kitchen/driver/gce.rb +100 -10
- data/lib/kitchen/driver/gce_version.rb +1 -1
- data/spec/kitchen/driver/gce_spec.rb +224 -28
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 82664c984b7db17f6d04c2844f382e18e87047d2
|
4
|
+
data.tar.gz: a47939f2f42029ee55400669a5daee07848023b6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 52267771b0165f69641258d29dd85603574e402b5c506dcae6a2c5e3b4a1332fce62cb31826ae6a22139e98d5792abcc5fccde5d14ff0be110cdb4964f44c7f8
|
7
|
+
data.tar.gz: 7ff9cb61420f0d29c4f71b0dfe4678f5a76d755efa5e0a4b80f12efb496189c962f3b275ae801927cc3c0680d2765282e76f56f295d6ba42536db4d2d7ca9873
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
## 1.1.0 / 2016-03-17
|
2
|
+
|
3
|
+
* #32: Rubocop and Rake fixes to address Travis test issues
|
4
|
+
* #33: Automatically disable auto-restart and auto-migrate when using preemptible instances
|
5
|
+
* #34: Support for using subnetworks
|
6
|
+
* #35: Support for gcloud-style image aliases (i.e. "centos-7" will get you the latest CentOS image)
|
7
|
+
|
1
8
|
## 1.0.0 / 2016-03-10
|
2
9
|
|
3
10
|
### New Features
|
data/README.md
CHANGED
@@ -125,6 +125,10 @@ public image, the appropriate public project will be searched.
|
|
125
125
|
You can override the project in which to search for the image with the
|
126
126
|
`image_project` parameter.
|
127
127
|
|
128
|
+
Additionally, you can supply an image alias supported by the `gcloud compute instances create`
|
129
|
+
command and kitchen-google will find the latest version of that image to use.
|
130
|
+
For a full list of aliases, see the output of `gcloud compute instances create --help`.
|
131
|
+
|
128
132
|
### `zone`
|
129
133
|
|
130
134
|
**Required if `region` is left blank.** The name of the GCE zone in which to
|
@@ -183,6 +187,10 @@ GCE instance type (size) to launch; default: `n1-standard-1`
|
|
183
187
|
|
184
188
|
GCE network that instance will be attached to; default: `default`
|
185
189
|
|
190
|
+
### `subnet`
|
191
|
+
|
192
|
+
GCE subnetwork that instance will be attached to. Only applies to custom networks.
|
193
|
+
|
186
194
|
### `preemptible`
|
187
195
|
|
188
196
|
If set to `true`, GCE instance will be brought up as a [preemptible](https://cloud.google.com/compute/docs/instances/preemptible) virtual machine,
|
data/kitchen-google.gemspec
CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |s|
|
|
20
20
|
|
21
21
|
s.add_development_dependency "bundler"
|
22
22
|
s.add_development_dependency "pry"
|
23
|
-
s.add_development_dependency "rake"
|
23
|
+
s.add_development_dependency "rake", "~> 10.5"
|
24
24
|
s.add_development_dependency "rspec"
|
25
25
|
s.add_development_dependency "rubocop"
|
26
26
|
|
data/lib/kitchen/driver/gce.rb
CHANGED
@@ -53,6 +53,27 @@ module Kitchen
|
|
53
53
|
"userinfo-email" => "userinfo.email",
|
54
54
|
}
|
55
55
|
|
56
|
+
IMAGE_ALIAS_MAP = {
|
57
|
+
"centos-6" => { project: "centos-cloud", prefix: "centos-6" },
|
58
|
+
"centos-7" => { project: "centos-cloud", prefix: "centos-7" },
|
59
|
+
"container-vm" => { project: "google-containers", prefix: "container-vm" },
|
60
|
+
"coreos" => { project: "coreos-cloud", prefix: "coreos-stable" },
|
61
|
+
"debian-7" => { project: "debian-cloud", prefix: "debian-7-wheezy" },
|
62
|
+
"debian-7-backports" => { project: "debian-cloud", prefix: "backports-debian-7-wheezy" },
|
63
|
+
"debian-8" => { project: "debian-cloud", prefix: "debian-8-jessie" },
|
64
|
+
"opensuse-13" => { project: "opensuse-cloud", prefix: "opensuse-13" },
|
65
|
+
"rhel-6" => { project: "rhel-cloud", prefix: "rhel-6" },
|
66
|
+
"rhel-7" => { project: "rhel-cloud", prefix: "rhel-7" },
|
67
|
+
"sles-11" => { project: "suse-cloud", prefix: "sles-11" },
|
68
|
+
"sles-12" => { project: "suse-cloud", prefix: "sles-12" },
|
69
|
+
"ubuntu-12-04" => { project: "ubuntu-os-cloud", prefix: "ubuntu-1204-precise" },
|
70
|
+
"ubuntu-14-04" => { project: "ubuntu-os-cloud", prefix: "ubuntu-1404-trusty" },
|
71
|
+
"ubuntu-15-04" => { project: "ubuntu-os-cloud", prefix: "ubuntu-1504-vivid" },
|
72
|
+
"ubuntu-15-10" => { project: "ubuntu-os-cloud", prefix: "ubuntu-1510-wily" },
|
73
|
+
"windows-2008-r2" => { project: "windows-cloud", prefix: "windows-server-2008-r2" },
|
74
|
+
"windows-2012-r2" => { project: "windows-cloud", prefix: "windows-server-2012-r2" },
|
75
|
+
}
|
76
|
+
|
56
77
|
kitchen_driver_api_version 2
|
57
78
|
plugin_version Kitchen::Driver::GCE_VERSION
|
58
79
|
|
@@ -67,6 +88,7 @@ module Kitchen
|
|
67
88
|
default_config :disk_type, "pd-standard"
|
68
89
|
default_config :machine_type, "n1-standard-1"
|
69
90
|
default_config :network, "default"
|
91
|
+
default_config :subnet, nil
|
70
92
|
default_config :inst_name, nil
|
71
93
|
default_config :service_account_name, "default"
|
72
94
|
default_config :service_account_scopes, []
|
@@ -144,10 +166,14 @@ module Kitchen
|
|
144
166
|
raise "Region #{config[:region]} is not a valid region" if config[:region] && !valid_region?
|
145
167
|
raise "Machine type #{config[:machine_type]} is not valid" unless valid_machine_type?
|
146
168
|
raise "Disk type #{config[:disk_type]} is not valid" unless valid_disk_type?
|
169
|
+
raise "Disk image #{config[:image_name]} is not valid - check your image name and image project" if boot_disk_source_image.nil?
|
147
170
|
raise "Network #{config[:network]} is not valid" unless valid_network?
|
171
|
+
raise "Subnet #{config[:subnet]} is not valid" if config[:subnet] and !valid_subnet?
|
148
172
|
raise "Email address of GCE user is not set" if winrm_transport? && config[:email].nil?
|
149
173
|
|
150
174
|
warn("Both zone and region specified - region will be ignored.") if config[:zone] && config[:region]
|
175
|
+
warn("Auto-migrate disabled for preemptible instance") if preemptible? && config[:auto_migrate]
|
176
|
+
warn("Auto-restart disabled for preemptible instance") if preemptible? && config[:auto_restart]
|
151
177
|
end
|
152
178
|
|
153
179
|
def connection
|
@@ -195,7 +221,7 @@ module Kitchen
|
|
195
221
|
end
|
196
222
|
|
197
223
|
def check_api_call(&block)
|
198
|
-
|
224
|
+
yield
|
199
225
|
rescue Google::Apis::ClientError => e
|
200
226
|
debug("API error: #{e.message}")
|
201
227
|
false
|
@@ -217,6 +243,11 @@ module Kitchen
|
|
217
243
|
check_api_call { connection.get_network(project, config[:network]) }
|
218
244
|
end
|
219
245
|
|
246
|
+
def valid_subnet?
|
247
|
+
return false if config[:subnet].nil?
|
248
|
+
check_api_call { connection.get_subnetwork(project, region, config[:subnet]) }
|
249
|
+
end
|
250
|
+
|
220
251
|
def valid_zone?
|
221
252
|
return false if config[:zone].nil?
|
222
253
|
check_api_call { connection.get_zone(project, config[:zone]) }
|
@@ -245,7 +276,11 @@ module Kitchen
|
|
245
276
|
end
|
246
277
|
|
247
278
|
def region
|
248
|
-
config[:region]
|
279
|
+
config[:region].nil? ? region_for_zone : config[:region]
|
280
|
+
end
|
281
|
+
|
282
|
+
def region_for_zone
|
283
|
+
@region_for_zone ||= connection.get_zone(project, zone).region.split("/").last
|
249
284
|
end
|
250
285
|
|
251
286
|
def zone
|
@@ -320,7 +355,7 @@ module Kitchen
|
|
320
355
|
params.disk_name = server_name
|
321
356
|
params.disk_size_gb = config[:disk_size]
|
322
357
|
params.disk_type = disk_type_url_for(config[:disk_type])
|
323
|
-
params.source_image =
|
358
|
+
params.source_image = boot_disk_source_image
|
324
359
|
|
325
360
|
disk.initialize_params = params
|
326
361
|
disk
|
@@ -330,21 +365,40 @@ module Kitchen
|
|
330
365
|
"zones/#{zone}/diskTypes/#{type}"
|
331
366
|
end
|
332
367
|
|
368
|
+
def boot_disk_source_image
|
369
|
+
@boot_disk_source ||= disk_image_url
|
370
|
+
end
|
371
|
+
|
333
372
|
def disk_image_url
|
334
373
|
# if the user provided an image_project, assume they want it, no questions asked
|
335
|
-
|
374
|
+
unless config[:image_project].nil?
|
375
|
+
debug("Searching project #{config[:image_project]} for image #{config[:image_name]}")
|
376
|
+
return image_url_for(config[:image_project], config[:image_name])
|
377
|
+
end
|
378
|
+
|
379
|
+
# No image project has been provided. Check to see if the image is a known alias.
|
380
|
+
alias_url = image_alias_url
|
381
|
+
unless alias_url.nil?
|
382
|
+
debug("Image #{config[:image_name]} is a known alias - using image URL: #{alias_url}")
|
383
|
+
return alias_url
|
384
|
+
end
|
336
385
|
|
337
|
-
#
|
386
|
+
# Doesn't match an alias. Let's check the user's project for the image.
|
338
387
|
url = image_url_for(project, config[:image_name])
|
339
|
-
|
388
|
+
unless url.nil?
|
389
|
+
debug("Located image #{config[:image_name]} in project #{project} - using image URL: #{url}")
|
390
|
+
return url
|
391
|
+
end
|
340
392
|
|
341
393
|
# Image not found in user's project. Is there a public project this image might exist in?
|
342
394
|
public_project = public_project_for_image(config[:image_name])
|
343
395
|
if public_project
|
396
|
+
debug("Searching public image project #{public_project} for image #{config[:image_name]}")
|
344
397
|
return image_url_for(public_project, config[:image_name])
|
345
398
|
end
|
346
399
|
|
347
400
|
# No image in user's project or public project, so it doesn't exist.
|
401
|
+
error("Image search failed for image #{config[:image_name]} - no suitable image found")
|
348
402
|
nil
|
349
403
|
end
|
350
404
|
|
@@ -352,6 +406,23 @@ module Kitchen
|
|
352
406
|
return "projects/#{image_project}/global/images/#{image_name}" if image_exist?(image_project, image_name)
|
353
407
|
end
|
354
408
|
|
409
|
+
def image_alias_url
|
410
|
+
image_alias = config[:image_name]
|
411
|
+
return unless IMAGE_ALIAS_MAP.key?(image_alias)
|
412
|
+
|
413
|
+
image_project = IMAGE_ALIAS_MAP[image_alias][:project]
|
414
|
+
image_prefix = IMAGE_ALIAS_MAP[image_alias][:prefix]
|
415
|
+
|
416
|
+
latest_image = connection.list_images(image_project).items
|
417
|
+
.select { |image| image.name.start_with?(image_prefix) }
|
418
|
+
.sort { |a, b| a.name <=> b.name }
|
419
|
+
.last
|
420
|
+
|
421
|
+
return if latest_image.nil?
|
422
|
+
|
423
|
+
latest_image.self_link
|
424
|
+
end
|
425
|
+
|
355
426
|
def public_project_for_image(image)
|
356
427
|
case image
|
357
428
|
when /centos/
|
@@ -403,6 +474,7 @@ module Kitchen
|
|
403
474
|
def instance_network_interfaces
|
404
475
|
interface = Google::Apis::ComputeV1::NetworkInterface.new
|
405
476
|
interface.network = network_url
|
477
|
+
interface.subnetwork = subnet_url if subnet_url
|
406
478
|
interface.access_configs = interface_access_configs
|
407
479
|
|
408
480
|
Array(interface)
|
@@ -412,6 +484,12 @@ module Kitchen
|
|
412
484
|
"projects/#{project}/global/networks/#{config[:network]}"
|
413
485
|
end
|
414
486
|
|
487
|
+
def subnet_url
|
488
|
+
return unless config[:subnet]
|
489
|
+
|
490
|
+
"projects/#{project}/regions/#{region}/subnetworks/#{config[:subnet]}"
|
491
|
+
end
|
492
|
+
|
415
493
|
def interface_access_configs
|
416
494
|
return [] if config[:use_private_ip]
|
417
495
|
|
@@ -424,14 +502,26 @@ module Kitchen
|
|
424
502
|
|
425
503
|
def instance_scheduling
|
426
504
|
Google::Apis::ComputeV1::Scheduling.new.tap do |scheduling|
|
427
|
-
scheduling.automatic_restart =
|
428
|
-
scheduling.preemptible =
|
505
|
+
scheduling.automatic_restart = auto_restart?.to_s
|
506
|
+
scheduling.preemptible = preemptible?.to_s
|
429
507
|
scheduling.on_host_maintenance = migrate_setting
|
430
508
|
end
|
431
509
|
end
|
432
510
|
|
511
|
+
def preemptible?
|
512
|
+
config[:preemptible]
|
513
|
+
end
|
514
|
+
|
515
|
+
def auto_migrate?
|
516
|
+
preemptible? ? false : config[:auto_migrate]
|
517
|
+
end
|
518
|
+
|
519
|
+
def auto_restart?
|
520
|
+
preemptible? ? false : config[:auto_restart]
|
521
|
+
end
|
522
|
+
|
433
523
|
def migrate_setting
|
434
|
-
|
524
|
+
auto_migrate? ? "MIGRATE" : "TERMINATE"
|
435
525
|
end
|
436
526
|
|
437
527
|
def instance_service_accounts
|
@@ -471,7 +561,7 @@ module Kitchen
|
|
471
561
|
begin
|
472
562
|
Timeout.timeout(wait_time) do
|
473
563
|
loop do
|
474
|
-
item =
|
564
|
+
item = yield
|
475
565
|
current_status = item.status
|
476
566
|
|
477
567
|
unless last_status == current_status
|
@@ -71,6 +71,7 @@ describe Kitchen::Driver::Gce do
|
|
71
71
|
allow(driver).to receive(:instance).and_return(instance)
|
72
72
|
allow(driver).to receive(:project).and_return("test_project")
|
73
73
|
allow(driver).to receive(:zone).and_return("test_zone")
|
74
|
+
allow(driver).to receive(:region).and_return("test_region")
|
74
75
|
end
|
75
76
|
|
76
77
|
it "driver API version is 2" do
|
@@ -193,6 +194,7 @@ describe Kitchen::Driver::Gce do
|
|
193
194
|
zone: "test_zone",
|
194
195
|
machine_type: "test_machine_type",
|
195
196
|
disk_type: "test_disk_type",
|
197
|
+
image_name: "test_image",
|
196
198
|
network: "test_network",
|
197
199
|
}
|
198
200
|
end
|
@@ -203,7 +205,9 @@ describe Kitchen::Driver::Gce do
|
|
203
205
|
allow(driver).to receive(:valid_region?).and_return(true)
|
204
206
|
allow(driver).to receive(:valid_machine_type?).and_return(true)
|
205
207
|
allow(driver).to receive(:valid_disk_type?).and_return(true)
|
208
|
+
allow(driver).to receive(:boot_disk_source_image).and_return("image")
|
206
209
|
allow(driver).to receive(:valid_network?).and_return(true)
|
210
|
+
allow(driver).to receive(:valid_subnet?).and_return(true)
|
207
211
|
allow(driver).to receive(:winrm_transport?).and_return(false)
|
208
212
|
allow(driver).to receive(:config).and_return(config)
|
209
213
|
end
|
@@ -253,6 +257,24 @@ describe Kitchen::Driver::Gce do
|
|
253
257
|
end
|
254
258
|
end
|
255
259
|
|
260
|
+
context "when subnet is set" do
|
261
|
+
let(:config) do
|
262
|
+
{
|
263
|
+
project: "test_project",
|
264
|
+
zone: "test_zone",
|
265
|
+
machine_type: "test_machine_type",
|
266
|
+
disk_type: "test_disk_type",
|
267
|
+
network: "test_network",
|
268
|
+
subnet: "test_subnet",
|
269
|
+
}
|
270
|
+
end
|
271
|
+
|
272
|
+
it "raises an exception if the subnet is invalid" do
|
273
|
+
expect(driver).to receive(:valid_subnet?).and_return(false)
|
274
|
+
expect { driver.validate! }.to raise_error(RuntimeError, "Subnet test_subnet is not valid")
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
256
278
|
it "raises an exception if the project is invalid" do
|
257
279
|
expect(driver).to receive(:valid_project?).and_return(false)
|
258
280
|
expect { driver.validate! }.to raise_error(RuntimeError, "Project test_project is not a valid project")
|
@@ -268,6 +290,11 @@ describe Kitchen::Driver::Gce do
|
|
268
290
|
expect { driver.validate! }.to raise_error(RuntimeError, "Disk type test_disk_type is not valid")
|
269
291
|
end
|
270
292
|
|
293
|
+
it "raises an exception if the boot disk source image is invalid" do
|
294
|
+
expect(driver).to receive(:boot_disk_source_image).and_return(nil)
|
295
|
+
expect { driver.validate! }.to raise_error(RuntimeError, "Disk image test_image is not valid - check your image name and image project")
|
296
|
+
end
|
297
|
+
|
271
298
|
it "raises an exception if the network is invalid" do
|
272
299
|
expect(driver).to receive(:valid_network?).and_return(false)
|
273
300
|
expect { driver.validate! }.to raise_error(RuntimeError, "Network test_network is not valid")
|
@@ -372,6 +399,11 @@ describe Kitchen::Driver::Gce do
|
|
372
399
|
it_behaves_like "a validity checker", :network, :get_network, "test_project"
|
373
400
|
end
|
374
401
|
|
402
|
+
describe '#valid_subnet?' do
|
403
|
+
subject { driver.valid_subnet? }
|
404
|
+
it_behaves_like "a validity checker", :subnet, :get_subnetwork, "test_project", "test_region"
|
405
|
+
end
|
406
|
+
|
375
407
|
describe '#valid_zone?' do
|
376
408
|
subject { driver.valid_zone? }
|
377
409
|
it_behaves_like "a validity checker", :zone, :get_zone, "test_project"
|
@@ -414,10 +446,29 @@ describe Kitchen::Driver::Gce do
|
|
414
446
|
end
|
415
447
|
|
416
448
|
describe '#region' do
|
417
|
-
it "returns the region from the config" do
|
418
|
-
|
449
|
+
it "returns the region from the config if specified" do
|
450
|
+
allow(driver).to receive(:region).and_call_original
|
451
|
+
allow(driver).to receive(:config).and_return(region: "my_region")
|
419
452
|
expect(driver.region).to eq("my_region")
|
420
453
|
end
|
454
|
+
|
455
|
+
it "returns the region for the zone if no region is specified" do
|
456
|
+
allow(driver).to receive(:region).and_call_original
|
457
|
+
allow(driver).to receive(:config).and_return({})
|
458
|
+
expect(driver).to receive(:region_for_zone).and_return("zone_region")
|
459
|
+
expect(driver.region).to eq("zone_region")
|
460
|
+
end
|
461
|
+
end
|
462
|
+
|
463
|
+
describe '#region_for_zone' do
|
464
|
+
it "returns the region for a given zone" do
|
465
|
+
connection = double("connection")
|
466
|
+
zone_obj = double("zone_obj", region: "/path/to/test_region")
|
467
|
+
|
468
|
+
expect(driver).to receive(:connection).and_return(connection)
|
469
|
+
expect(connection).to receive(:get_zone).with(project, zone).and_return(zone_obj)
|
470
|
+
expect(driver.region_for_zone).to eq("test_region")
|
471
|
+
end
|
421
472
|
end
|
422
473
|
|
423
474
|
describe '#zone' do
|
@@ -614,33 +665,49 @@ describe Kitchen::Driver::Gce do
|
|
614
665
|
end
|
615
666
|
|
616
667
|
context "when the user does not supply an image project" do
|
617
|
-
let(:config) { { image_name: "my_image" } }
|
618
668
|
|
619
|
-
context "when the image
|
620
|
-
|
621
|
-
|
622
|
-
|
669
|
+
context "when the image provided is an alias" do
|
670
|
+
let(:config) { { image_name: "image_alias" } }
|
671
|
+
|
672
|
+
it "returns the alias URL" do
|
673
|
+
expect(driver).to receive(:image_alias_url).and_return("image_alias_url")
|
674
|
+
expect(driver.disk_image_url).to eq("image_alias_url")
|
623
675
|
end
|
624
676
|
end
|
625
677
|
|
626
|
-
context "when the image
|
678
|
+
context "when the image provided is not an alias" do
|
679
|
+
let(:config) { { image_name: "my_image" } }
|
680
|
+
|
627
681
|
before do
|
628
|
-
expect(driver).to receive(:
|
682
|
+
expect(driver).to receive(:image_alias_url).and_return(nil)
|
629
683
|
end
|
630
684
|
|
631
|
-
context "when the image
|
632
|
-
it "returns the image URL
|
633
|
-
expect(driver).to receive(:
|
634
|
-
expect(driver).to receive(:image_url_for).with("public_project", "my_image").and_return("image_url")
|
685
|
+
context "when the image exists in the user's project" do
|
686
|
+
it "returns the image URL" do
|
687
|
+
expect(driver).to receive(:image_url_for).with(project, "my_image").and_return("image_url")
|
635
688
|
expect(driver.disk_image_url).to eq("image_url")
|
636
689
|
end
|
637
690
|
end
|
638
691
|
|
639
|
-
context "when the image does not
|
640
|
-
|
641
|
-
expect(driver).to receive(:
|
642
|
-
|
643
|
-
|
692
|
+
context "when the image does not exist in the user's project" do
|
693
|
+
before do
|
694
|
+
expect(driver).to receive(:image_url_for).with(project, "my_image").and_return(nil)
|
695
|
+
end
|
696
|
+
|
697
|
+
context "when the image matches a known public project" do
|
698
|
+
it "returns the image URL from the public project" do
|
699
|
+
expect(driver).to receive(:public_project_for_image).with("my_image").and_return("public_project")
|
700
|
+
expect(driver).to receive(:image_url_for).with("public_project", "my_image").and_return("image_url")
|
701
|
+
expect(driver.disk_image_url).to eq("image_url")
|
702
|
+
end
|
703
|
+
end
|
704
|
+
|
705
|
+
context "when the image does not match a known project" do
|
706
|
+
it "returns nil" do
|
707
|
+
expect(driver).to receive(:public_project_for_image).with("my_image").and_return(nil)
|
708
|
+
expect(driver).not_to receive(:image_url_for)
|
709
|
+
expect(driver.disk_image_url).to eq(nil)
|
710
|
+
end
|
644
711
|
end
|
645
712
|
end
|
646
713
|
end
|
@@ -659,6 +726,60 @@ describe Kitchen::Driver::Gce do
|
|
659
726
|
end
|
660
727
|
end
|
661
728
|
|
729
|
+
describe '#image_alias_url' do
|
730
|
+
before do
|
731
|
+
allow(driver).to receive(:config).and_return(config)
|
732
|
+
end
|
733
|
+
|
734
|
+
context "when the image_alias is not a valid alias" do
|
735
|
+
let(:config) { { image_name: "fake_alias" } }
|
736
|
+
|
737
|
+
it "returns nil" do
|
738
|
+
expect(driver.image_alias_url).to eq(nil)
|
739
|
+
end
|
740
|
+
end
|
741
|
+
|
742
|
+
context "when the image_alias is a valid alias" do
|
743
|
+
let(:config) { { image_name: "centos-7" } }
|
744
|
+
let(:connection) { double("connection") }
|
745
|
+
|
746
|
+
before do
|
747
|
+
allow(driver).to receive(:connection).and_return(connection)
|
748
|
+
allow(connection).to receive(:list_images).and_return(response)
|
749
|
+
end
|
750
|
+
|
751
|
+
context "when the response contains no images" do
|
752
|
+
let(:response) { double("response", items: []) }
|
753
|
+
|
754
|
+
it "returns nil" do
|
755
|
+
expect(driver.image_alias_url).to eq(nil)
|
756
|
+
end
|
757
|
+
end
|
758
|
+
|
759
|
+
context "when the response contains images but none match the name" do
|
760
|
+
let(:image1) { double("image1", name: "centos-6-v20150101") }
|
761
|
+
let(:image2) { double("image2", name: "centos-6-v20150202") }
|
762
|
+
let(:image3) { double("image3", name: "ubuntu-14-v20150303") }
|
763
|
+
let(:response) { double("response", items: [ image1, image2, image3 ]) }
|
764
|
+
|
765
|
+
it "returns nil" do
|
766
|
+
expect(driver.image_alias_url).to eq(nil)
|
767
|
+
end
|
768
|
+
end
|
769
|
+
|
770
|
+
context "when the response contains images that match the name" do
|
771
|
+
let(:image1) { double("image1", name: "centos-7-v20160201", self_link: "image1_selflink") }
|
772
|
+
let(:image2) { double("image2", name: "centos-7-v20160301", self_link: "image2_selflink") }
|
773
|
+
let(:image3) { double("image3", name: "centos-6-v20160401", self_link: "image3_selflink") }
|
774
|
+
let(:response) { double("response", items: [ image1, image2, image3 ]) }
|
775
|
+
|
776
|
+
it "returns the link for image2 which is the most recent image" do
|
777
|
+
expect(driver.image_alias_url).to eq("image2_selflink")
|
778
|
+
end
|
779
|
+
end
|
780
|
+
end
|
781
|
+
end
|
782
|
+
|
662
783
|
describe '#public_project_for_image' do
|
663
784
|
{
|
664
785
|
"centos" => "centos-cloud",
|
@@ -722,17 +843,45 @@ describe Kitchen::Driver::Gce do
|
|
722
843
|
end
|
723
844
|
|
724
845
|
describe '#instance_network_interfaces' do
|
725
|
-
|
726
|
-
interface = double("interface")
|
846
|
+
let(:interface) { double("interface") }
|
727
847
|
|
728
|
-
|
729
|
-
|
848
|
+
before do
|
849
|
+
allow(Google::Apis::ComputeV1::NetworkInterface).to receive(:new).and_return(interface)
|
850
|
+
allow(driver).to receive(:network_url)
|
851
|
+
allow(driver).to receive(:subnet_url)
|
852
|
+
allow(driver).to receive(:interface_access_configs)
|
853
|
+
allow(interface).to receive(:network=)
|
854
|
+
allow(interface).to receive(:subnetwork=)
|
855
|
+
allow(interface).to receive(:access_configs=)
|
856
|
+
end
|
730
857
|
|
858
|
+
it "creates a network interface object and returns it" do
|
731
859
|
expect(Google::Apis::ComputeV1::NetworkInterface).to receive(:new).and_return(interface)
|
860
|
+
expect(driver.instance_network_interfaces).to eq([interface])
|
861
|
+
end
|
862
|
+
|
863
|
+
it "sets the network" do
|
864
|
+
expect(driver).to receive(:network_url).and_return("network_url")
|
732
865
|
expect(interface).to receive(:network=).with("network_url")
|
866
|
+
driver.instance_network_interfaces
|
867
|
+
end
|
868
|
+
|
869
|
+
it "sets the access configs" do
|
870
|
+
expect(driver).to receive(:interface_access_configs).and_return("access_configs")
|
733
871
|
expect(interface).to receive(:access_configs=).with("access_configs")
|
872
|
+
driver.instance_network_interfaces
|
873
|
+
end
|
734
874
|
|
735
|
-
|
875
|
+
it "does not set a subnetwork by default" do
|
876
|
+
allow(driver).to receive(:subnet_url).and_return(nil)
|
877
|
+
expect(interface).not_to receive(:subnetwork=)
|
878
|
+
driver.instance_network_interfaces
|
879
|
+
end
|
880
|
+
|
881
|
+
it "sets a subnetwork if one was specified" do
|
882
|
+
allow(driver).to receive(:subnet_url).and_return("subnet_url")
|
883
|
+
expect(interface).to receive(:subnetwork=).with("subnet_url")
|
884
|
+
driver.instance_network_interfaces
|
736
885
|
end
|
737
886
|
end
|
738
887
|
|
@@ -743,6 +892,19 @@ describe Kitchen::Driver::Gce do
|
|
743
892
|
end
|
744
893
|
end
|
745
894
|
|
895
|
+
describe '#subnet_url_for' do
|
896
|
+
it "returns nil if no subnet is specified" do
|
897
|
+
expect(driver).to receive(:config).and_return({})
|
898
|
+
expect(driver.subnet_url).to eq(nil)
|
899
|
+
end
|
900
|
+
|
901
|
+
it "returns a properly-formatted subnet URL" do
|
902
|
+
allow(driver).to receive(:config).and_return(subnet: "test_subnet")
|
903
|
+
expect(driver).to receive(:region).and_return("test_region")
|
904
|
+
expect(driver.subnet_url).to eq("projects/test_project/regions/test_region/subnetworks/test_subnet")
|
905
|
+
end
|
906
|
+
end
|
907
|
+
|
746
908
|
describe '#interface_access_configs' do
|
747
909
|
it "returns a properly-configured access config object" do
|
748
910
|
access_config = double("access_config")
|
@@ -765,24 +927,58 @@ describe Kitchen::Driver::Gce do
|
|
765
927
|
it "returns a properly-configured scheduling object" do
|
766
928
|
scheduling = double("scheduling")
|
767
929
|
|
768
|
-
|
930
|
+
expect(driver).to receive(:auto_restart?).and_return("restart")
|
931
|
+
expect(driver).to receive(:preemptible?).and_return("preempt")
|
769
932
|
expect(driver).to receive(:migrate_setting).and_return("host_maintenance")
|
770
933
|
expect(Google::Apis::ComputeV1::Scheduling).to receive(:new).and_return(scheduling)
|
771
|
-
expect(scheduling).to receive(:automatic_restart=).with("
|
772
|
-
expect(scheduling).to receive(:preemptible=).with("
|
934
|
+
expect(scheduling).to receive(:automatic_restart=).with("restart")
|
935
|
+
expect(scheduling).to receive(:preemptible=).with("preempt")
|
773
936
|
expect(scheduling).to receive(:on_host_maintenance=).with("host_maintenance")
|
774
937
|
expect(driver.instance_scheduling).to eq(scheduling)
|
775
938
|
end
|
776
939
|
end
|
777
940
|
|
941
|
+
describe '#preemptible?' do
|
942
|
+
it "returns the preemptible setting from the config" do
|
943
|
+
expect(driver).to receive(:config).and_return(preemptible: "test_preempt")
|
944
|
+
expect(driver.preemptible?).to eq("test_preempt")
|
945
|
+
end
|
946
|
+
end
|
947
|
+
|
948
|
+
describe '#auto_migrate?' do
|
949
|
+
it "returns false if the instance is preemptible" do
|
950
|
+
expect(driver).to receive(:preemptible?).and_return(true)
|
951
|
+
expect(driver.auto_migrate?).to eq(false)
|
952
|
+
end
|
953
|
+
|
954
|
+
it "returns the setting from the config if preemptible is false" do
|
955
|
+
expect(driver).to receive(:config).and_return(auto_migrate: "test_migrate")
|
956
|
+
expect(driver).to receive(:preemptible?).and_return(false)
|
957
|
+
expect(driver.auto_migrate?).to eq("test_migrate")
|
958
|
+
end
|
959
|
+
end
|
960
|
+
|
961
|
+
describe '#auto_restart?' do
|
962
|
+
it "returns false if the instance is preemptible" do
|
963
|
+
expect(driver).to receive(:preemptible?).and_return(true)
|
964
|
+
expect(driver.auto_restart?).to eq(false)
|
965
|
+
end
|
966
|
+
|
967
|
+
it "returns the setting from the config if preemptible is false" do
|
968
|
+
expect(driver).to receive(:config).and_return(auto_restart: "test_restart")
|
969
|
+
expect(driver).to receive(:preemptible?).and_return(false)
|
970
|
+
expect(driver.auto_restart?).to eq("test_restart")
|
971
|
+
end
|
972
|
+
end
|
973
|
+
|
778
974
|
describe '#migrate_setting' do
|
779
975
|
it "returns MIGRATE if auto_migrate is true" do
|
780
|
-
expect(driver).to receive(:
|
976
|
+
expect(driver).to receive(:auto_migrate?).and_return(true)
|
781
977
|
expect(driver.migrate_setting).to eq("MIGRATE")
|
782
978
|
end
|
783
979
|
|
784
980
|
it "returns TERMINATE if auto_migrate is false" do
|
785
|
-
expect(driver).to receive(:
|
981
|
+
expect(driver).to receive(:auto_migrate?).and_return(false)
|
786
982
|
expect(driver.migrate_setting).to eq("TERMINATE")
|
787
983
|
end
|
788
984
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kitchen-google
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Leonard
|
@@ -85,16 +85,16 @@ dependencies:
|
|
85
85
|
name: rake
|
86
86
|
requirement: !ruby/object:Gem::Requirement
|
87
87
|
requirements:
|
88
|
-
- - "
|
88
|
+
- - "~>"
|
89
89
|
- !ruby/object:Gem::Version
|
90
|
-
version: '
|
90
|
+
version: '10.5'
|
91
91
|
type: :development
|
92
92
|
prerelease: false
|
93
93
|
version_requirements: !ruby/object:Gem::Requirement
|
94
94
|
requirements:
|
95
|
-
- - "
|
95
|
+
- - "~>"
|
96
96
|
- !ruby/object:Gem::Version
|
97
|
-
version: '
|
97
|
+
version: '10.5'
|
98
98
|
- !ruby/object:Gem::Dependency
|
99
99
|
name: rspec
|
100
100
|
requirement: !ruby/object:Gem::Requirement
|