kitchen-google 1.0.0 → 1.1.0
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/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
|