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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 76a9c3e0e6785ad0ce9e9a5f73eb41ffedd5ff13
4
- data.tar.gz: 345f185a9329e09575fbc5247b8818a62c65f4e8
3
+ metadata.gz: 82664c984b7db17f6d04c2844f382e18e87047d2
4
+ data.tar.gz: a47939f2f42029ee55400669a5daee07848023b6
5
5
  SHA512:
6
- metadata.gz: 427b6a8e6c0f9485e8072de9c6b68c5762a3f8fa991c747c88539a22242e6e76c64d2f98b8184b70f588c29632bdfcf69df4289610aca1f9149292530c557c28
7
- data.tar.gz: dc81a39c4cf56add4985c31ea750b4a55be452cc354659dcda30e84a47d073bcb419b6a40572b47f1ba861725fd1de33e5d1dd018dc36fde529f9da972af56d5
6
+ metadata.gz: 52267771b0165f69641258d29dd85603574e402b5c506dcae6a2c5e3b4a1332fce62cb31826ae6a22139e98d5792abcc5fccde5d14ff0be110cdb4964f44c7f8
7
+ data.tar.gz: 7ff9cb61420f0d29c4f71b0dfe4678f5a76d755efa5e0a4b80f12efb496189c962f3b275ae801927cc3c0680d2765282e76f56f295d6ba42536db4d2d7ca9873
@@ -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,
@@ -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
 
@@ -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
- block.call
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 = disk_image_url
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
- return image_url_for(config[:image_project], config[:image_name]) unless config[:image_project].nil?
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
- # no image project has been provided. We'll first check the user's project for the image.
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
- return url unless url.nil?
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 = config[:auto_restart].to_s
428
- scheduling.preemptible = config[:preemptible].to_s
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
- config[:auto_migrate] ? "MIGRATE" : "TERMINATE"
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 = block.call
564
+ item = yield
475
565
  current_status = item.status
476
566
 
477
567
  unless last_status == current_status
@@ -18,6 +18,6 @@
18
18
 
19
19
  module Kitchen
20
20
  module Driver
21
- GCE_VERSION = "1.0.0".freeze
21
+ GCE_VERSION = "1.1.0".freeze
22
22
  end
23
23
  end
@@ -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
- expect(driver).to receive(:config).and_return(region: "my_region")
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 exists in the user's project" do
620
- it "returns the image URL" do
621
- expect(driver).to receive(:image_url_for).with(project, "my_image").and_return("image_url")
622
- expect(driver.disk_image_url).to eq("image_url")
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 does not exist in the user's project" do
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(:image_url_for).with(project, "my_image").and_return(nil)
682
+ expect(driver).to receive(:image_alias_url).and_return(nil)
629
683
  end
630
684
 
631
- context "when the image matches a known public project" do
632
- it "returns the image URL from the public project" do
633
- expect(driver).to receive(:public_project_for_image).with("my_image").and_return("public_project")
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 match a known project" do
640
- it "returns nil" do
641
- expect(driver).to receive(:public_project_for_image).with("my_image").and_return(nil)
642
- expect(driver).not_to receive(:image_url_for)
643
- expect(driver.disk_image_url).to eq(nil)
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
- it "returns an array containing a properly-formatted interface" do
726
- interface = double("interface")
846
+ let(:interface) { double("interface") }
727
847
 
728
- expect(driver).to receive(:network_url).and_return("network_url")
729
- expect(driver).to receive(:interface_access_configs).and_return("access_configs")
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
- expect(driver.instance_network_interfaces).to eq([interface])
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
- allow(driver).to receive(:config).and_return(auto_restart: true, preemptible: false)
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("true")
772
- expect(scheduling).to receive(:preemptible=).with("false")
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(:config).and_return(auto_migrate: true)
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(:config).and_return(auto_migrate: false)
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.0.0
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: '0'
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: '0'
97
+ version: '10.5'
98
98
  - !ruby/object:Gem::Dependency
99
99
  name: rspec
100
100
  requirement: !ruby/object:Gem::Requirement