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 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