vagrant-google 2.3.0.rc0 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,72 @@
1
+ # Copyright 2015 Google Inc. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ #
15
+ # Changes:
16
+ # April 2019: Modified example found here:
17
+ # https://github.com/GoogleCloudPlatform/compute-image-windows/blob/master/examples/windows_auth_python_sample.py
18
+ # to enable WinRM with vagrant.
19
+
20
+ module VagrantPlugins
21
+ module Google
22
+ module Action
23
+ # Sets up a temporary WinRM password using Google's method for
24
+ # establishing a new password over encrypted channels.
25
+ class SetupWinrmPassword
26
+ def initialize(app, env)
27
+ @app = app
28
+ @logger = Log4r::Logger.new("vagrant_google::action::setup_winrm_password")
29
+ end
30
+
31
+ def setup_password(env, instance, zone, user)
32
+ # Setup
33
+ compute = env[:google_compute]
34
+ server = compute.servers.get(instance, zone)
35
+ password = server.reset_windows_password(user)
36
+
37
+ env[:ui].info("Temp Password: #{password}")
38
+
39
+ password
40
+ end
41
+
42
+ def call(env)
43
+ # Get the configs
44
+ zone = env[:machine].provider_config.zone
45
+ zone_config = env[:machine].provider_config.get_zone_config(zone)
46
+
47
+ instance = zone_config.name
48
+ user = env[:machine].config.winrm.username
49
+ pass = env[:machine].config.winrm.password
50
+
51
+ # Get Temporary Password, set WinRM password
52
+ temp_pass = setup_password(env, instance, zone, user)
53
+ env[:machine].config.winrm.password = temp_pass
54
+
55
+ # Wait for WinRM To be Ready
56
+ env[:ui].info("Waiting for WinRM To be ready")
57
+ env[:machine].communicate.wait_for_ready(60)
58
+
59
+ # Use WinRM to Change Password to one in Vagrantfile
60
+ env[:ui].info("Changing password from temporary to winrm password")
61
+ winrmcomm = VagrantPlugins::CommunicatorWinRM::Communicator.new(env[:machine])
62
+ cmd = "net user #{user} #{pass}"
63
+ opts = { elevated: true }
64
+ winrmcomm.test(cmd, opts)
65
+
66
+ # Update WinRM password to reflect updated one
67
+ env[:machine].config.winrm.password = pass
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -65,9 +65,9 @@ module VagrantPlugins
65
65
  @logger.info("Time to instance ready: #{env[:metrics]["instance_ready_time"]}")
66
66
 
67
67
  unless env[:interrupted]
68
- env[:metrics]["instance_ssh_time"] = Util::Timer.time do
69
- # Wait for SSH to be ready.
70
- env[:ui].info(I18n.t("vagrant_google.waiting_for_ssh"))
68
+ env[:metrics]["instance_comm_time"] = Util::Timer.time do
69
+ # Wait for Comms to be ready.
70
+ env[:ui].info(I18n.t("vagrant_google.waiting_for_comm"))
71
71
  while true
72
72
  # If we're interrupted then just back out
73
73
  break if env[:interrupted]
@@ -76,7 +76,7 @@ module VagrantPlugins
76
76
  end
77
77
  end
78
78
 
79
- @logger.info("Time for SSH ready: #{env[:metrics]["instance_ssh_time"]}")
79
+ @logger.info("Time for Comms ready: #{env[:metrics]["instance_comm_time"]}")
80
80
 
81
81
  # Ready and booted!
82
82
  env[:ui].info(I18n.t("vagrant_google.ready"))
@@ -17,11 +17,6 @@ require "securerandom"
17
17
  module VagrantPlugins
18
18
  module Google
19
19
  class Config < Vagrant.plugin("2", :config) # rubocop:disable Metrics/ClassLength
20
- # The Service Account Client ID Email address
21
- #
22
- # @return [String]
23
- attr_accessor :google_client_email
24
-
25
20
  # The path to the Service Account json-formatted private key
26
21
  #
27
22
  # @return [String]
@@ -117,6 +112,11 @@ module VagrantPlugins
117
112
  # @return String
118
113
  attr_accessor :external_ip
119
114
 
115
+ # The network IP Address to use
116
+ #
117
+ # @return String
118
+ attr_accessor :network_ip
119
+
120
120
  # Use private ip address
121
121
  #
122
122
  # @return Boolean
@@ -152,8 +152,8 @@ module VagrantPlugins
152
152
  # @return [Int]
153
153
  attr_accessor :instance_ready_timeout
154
154
 
155
- # The zone to launch the instance into. If nil, it will
156
- # use the default us-central1-f.
155
+ # The zone to launch the instance into.
156
+ # If nil and the "default" network is set use the default us-central1-f.
157
157
  #
158
158
  # @return [String]
159
159
  attr_accessor :zone
@@ -178,38 +178,68 @@ module VagrantPlugins
178
178
  # @return [Array<Hash>]
179
179
  attr_accessor :additional_disks
180
180
 
181
+ # (Optional - Override default WinRM setup before for Public Windows images)
182
+ #
183
+ # @return [Boolean]
184
+ attr_accessor :setup_winrm_password
185
+
186
+ # Accelerators
187
+ #
188
+ # @return [Array<Hash>]
189
+ attr_accessor :accelerators
190
+
191
+ # whether the instance has Secure Boot enabled
192
+ #
193
+ # @return Boolean
194
+ attr_accessor :enable_secure_boot
195
+
196
+ # whether the instance has the vTPM enabled
197
+ #
198
+ # @return Boolean
199
+ attr_accessor :enable_vtpm
200
+
201
+ # whether the instance has integrity monitoring enabled
202
+ #
203
+ # @return Boolean
204
+ attr_accessor :enable_integrity_monitoring
205
+
181
206
  def initialize(zone_specific=false)
182
- @google_client_email = UNSET_VALUE
183
- @google_json_key_location = UNSET_VALUE
184
- @google_project_id = UNSET_VALUE
185
- @image = UNSET_VALUE
186
- @image_family = UNSET_VALUE
187
- @image_project_id = UNSET_VALUE
188
- @instance_group = UNSET_VALUE
189
- @machine_type = UNSET_VALUE
190
- @disk_size = UNSET_VALUE
191
- @disk_name = UNSET_VALUE
192
- @disk_type = UNSET_VALUE
193
- @metadata = {}
194
- @name = UNSET_VALUE
195
- @network = UNSET_VALUE
196
- @network_project_id = UNSET_VALUE
197
- @subnetwork = UNSET_VALUE
198
- @tags = []
199
- @labels = {}
200
- @can_ip_forward = UNSET_VALUE
201
- @external_ip = UNSET_VALUE
202
- @use_private_ip = UNSET_VALUE
203
- @autodelete_disk = UNSET_VALUE
204
- @preemptible = UNSET_VALUE
205
- @auto_restart = UNSET_VALUE
206
- @on_host_maintenance = UNSET_VALUE
207
- @instance_ready_timeout = UNSET_VALUE
208
- @zone = UNSET_VALUE
209
- @scopes = UNSET_VALUE
210
- @service_accounts = UNSET_VALUE
211
- @service_account = UNSET_VALUE
212
- @additional_disks = []
207
+ @google_json_key_location = UNSET_VALUE
208
+ @google_project_id = UNSET_VALUE
209
+ @image = UNSET_VALUE
210
+ @image_family = UNSET_VALUE
211
+ @image_project_id = UNSET_VALUE
212
+ @instance_group = UNSET_VALUE
213
+ @machine_type = UNSET_VALUE
214
+ @disk_size = UNSET_VALUE
215
+ @disk_name = UNSET_VALUE
216
+ @disk_type = UNSET_VALUE
217
+ @metadata = {}
218
+ @name = UNSET_VALUE
219
+ @network = UNSET_VALUE
220
+ @network_project_id = UNSET_VALUE
221
+ @subnetwork = UNSET_VALUE
222
+ @tags = []
223
+ @labels = {}
224
+ @can_ip_forward = UNSET_VALUE
225
+ @external_ip = UNSET_VALUE
226
+ @network_ip = UNSET_VALUE
227
+ @use_private_ip = UNSET_VALUE
228
+ @autodelete_disk = UNSET_VALUE
229
+ @preemptible = UNSET_VALUE
230
+ @auto_restart = UNSET_VALUE
231
+ @on_host_maintenance = UNSET_VALUE
232
+ @instance_ready_timeout = UNSET_VALUE
233
+ @zone = UNSET_VALUE
234
+ @scopes = UNSET_VALUE
235
+ @service_accounts = UNSET_VALUE
236
+ @service_account = UNSET_VALUE
237
+ @additional_disks = []
238
+ @setup_winrm_password = UNSET_VALUE
239
+ @accelerators = []
240
+ @enable_secure_boot = UNSET_VALUE
241
+ @enable_vtpm = UNSET_VALUE
242
+ @enable_integrity_monitoring = UNSET_VALUE
213
243
 
214
244
  # Internal state (prefix with __ so they aren't automatically
215
245
  # merged)
@@ -275,15 +305,24 @@ module VagrantPlugins
275
305
  result.instance_variable_set(:@__zone_config, new_zone_config)
276
306
 
277
307
  # Merge in the metadata
278
- result.metadata.merge!(self.metadata)
279
- result.metadata.merge!(other.metadata)
308
+ result.metadata = self.metadata.merge(other.metadata)
309
+
310
+ # Merge in the labels
311
+ result.labels = self.labels.merge(other.labels)
312
+
313
+ # Merge in the tags
314
+ result.tags |= self.tags
315
+ result.tags |= other.tags
316
+
317
+ # Merge in the additional disks
318
+ result.additional_disks |= self.additional_disks
319
+ result.additional_disks |= other.additional_disks
280
320
  end
281
321
  end
282
322
 
283
323
  def finalize! # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
284
324
  # Try to get access keys from standard Google environment variables; they
285
325
  # will default to nil if the environment variables are not present.
286
- @google_client_email = ENV['GOOGLE_CLIENT_EMAIL'] if @google_client_email == UNSET_VALUE
287
326
  @google_json_key_location = ENV['GOOGLE_JSON_KEY_LOCATION'] if @google_json_key_location == UNSET_VALUE
288
327
  @google_project_id = ENV['GOOGLE_PROJECT_ID'] if @google_project_id == UNSET_VALUE
289
328
 
@@ -317,6 +356,7 @@ module VagrantPlugins
317
356
  t = Time.now
318
357
  @name = "i-#{t.strftime("%Y%m%d%H")}-" + SecureRandom.hex(4)
319
358
  end
359
+
320
360
  # Network defaults to 'default'
321
361
  @network = "default" if @network == UNSET_VALUE
322
362
 
@@ -326,8 +366,13 @@ module VagrantPlugins
326
366
  # Subnetwork defaults to nil
327
367
  @subnetwork = nil if @subnetwork == UNSET_VALUE
328
368
 
329
- # Default zone is us-central1-f.
330
- @zone = "us-central1-f" if @zone == UNSET_VALUE
369
+ # Default zone is us-central1-f if using the default network
370
+ if @zone == UNSET_VALUE
371
+ @zone = nil
372
+ if @network == "default"
373
+ @zone = "us-central1-f"
374
+ end
375
+ end
331
376
 
332
377
  # autodelete_disk defaults to true
333
378
  @autodelete_disk = true if @autodelete_disk == UNSET_VALUE
@@ -338,6 +383,9 @@ module VagrantPlugins
338
383
  # external_ip defaults to nil
339
384
  @external_ip = nil if @external_ip == UNSET_VALUE
340
385
 
386
+ # network_ip defaults to nil
387
+ @network_ip = nil if @network_ip == UNSET_VALUE
388
+
341
389
  # use_private_ip defaults to false
342
390
  @use_private_ip = false if @use_private_ip == UNSET_VALUE
343
391
 
@@ -362,11 +410,23 @@ module VagrantPlugins
362
410
  # Default IAM service account
363
411
  @service_account = nil if @service_account == UNSET_VALUE
364
412
 
413
+ # Default Setup WinRM Password
414
+ @setup_winrm_password = nil if @setup_winrm_password == UNSET_VALUE
415
+
365
416
  # Config option service_accounts is deprecated
366
417
  if @service_accounts
367
418
  @scopes = @service_accounts
368
419
  end
369
420
 
421
+ # enable_secure_boot defaults to nil
422
+ @enable_secure_boot = false if @enable_secure_boot == UNSET_VALUE
423
+
424
+ # enable_vtpm defaults to nil
425
+ @enable_vtpm = false if @enable_vtpm == UNSET_VALUE
426
+
427
+ # enable_integrity_monitoring defaults to nil
428
+ @enable_integrity_monitoring = false if @enable_integrity_monitoring == UNSET_VALUE
429
+
370
430
  # Compile our zone specific configurations only within
371
431
  # NON-zone-SPECIFIC configurations.
372
432
  unless @__zone_specific
@@ -403,13 +463,12 @@ module VagrantPlugins
403
463
  # TODO: Check why provider-level settings are validated in the zone config
404
464
  errors << I18n.t("vagrant_google.config.google_project_id_required") if \
405
465
  config.google_project_id.nil?
406
- errors << I18n.t("vagrant_google.config.google_client_email_required") if \
407
- config.google_client_email.nil?
408
- errors << I18n.t("vagrant_google.config.google_key_location_required") if \
409
- config.google_json_key_location.nil?
410
- errors << I18n.t("vagrant_google.config.private_key_missing") unless \
411
- File.exist?(File.expand_path(config.google_json_key_location.to_s)) or
412
- File.exist?(File.expand_path(config.google_json_key_location.to_s, machine.env.root_path))
466
+
467
+ if config.google_json_key_location
468
+ errors << I18n.t("vagrant_google.config.private_key_missing") unless \
469
+ File.exist?(File.expand_path(config.google_json_key_location.to_s)) or
470
+ File.exist?(File.expand_path(config.google_json_key_location.to_s, machine.env.root_path))
471
+ end
413
472
 
414
473
  if config.preemptible
415
474
  errors << I18n.t("vagrant_google.config.auto_restart_invalid_on_preemptible") if \
@@ -422,10 +481,15 @@ module VagrantPlugins
422
481
  errors << I18n.t("vagrant_google.config.image_and_image_family_set") if \
423
482
  config.image
424
483
  end
425
- end
426
484
 
427
- errors << I18n.t("vagrant_google.config.image_required") if config.image.nil? && config.image_family.nil?
428
- errors << I18n.t("vagrant_google.config.name_required") if @name.nil?
485
+ errors << I18n.t("vagrant_google.config.image_required") if config.image.nil? && config.image_family.nil?
486
+ errors << I18n.t("vagrant_google.config.name_required") if @name.nil?
487
+
488
+ if !config.accelerators.empty?
489
+ errors << I18n.t("vagrant_google.config.on_host_maintenance_invalid_with_accelerators") unless \
490
+ config.on_host_maintenance == "TERMINATE"
491
+ end
492
+ end
429
493
 
430
494
  if @service_accounts
431
495
  machine.env.ui.warn(I18n.t("vagrant_google.config.service_accounts_deprecaated"))
@@ -13,6 +13,6 @@
13
13
  # limitations under the License.
14
14
  module VagrantPlugins
15
15
  module Google
16
- VERSION = "2.3.0.rc0".freeze
16
+ VERSION = "2.6.0".freeze
17
17
  end
18
18
  end
@@ -14,8 +14,8 @@ en:
14
14
  Instance is not created. Please run `vagrant up` first.
15
15
  ready: |-
16
16
  Machine is booted and ready for use!
17
- ready_ssh: |-
18
- Machine is ready for SSH access!
17
+ ready_comm: |-
18
+ Machine is ready for Communicator access!
19
19
  rsync_not_found_warning: |-
20
20
  Warning! Folder sync disabled because the rsync binary is missing.
21
21
  Make sure rsync is installed and the binary can be found in the PATH.
@@ -31,8 +31,8 @@ en:
31
31
  Waiting for GCP operation '%{name}' to finish...
32
32
  waiting_for_ready: |-
33
33
  Waiting for instance to become "ready"...
34
- waiting_for_ssh: |-
35
- Waiting for SSH to become available...
34
+ waiting_for_comm: |-
35
+ Waiting for Communicator to become available...
36
36
  warn_networks: |-
37
37
  Warning! The Google provider doesn't support any of the Vagrant
38
38
  high-level network configurations (`config.vm.network`). They
@@ -52,9 +52,6 @@ en:
52
52
  # Translations for config validation errors
53
53
  #-------------------------------------------------------------------------------
54
54
  config:
55
- google_client_email_required: |-
56
- A Google Service Account client email is required via
57
- "google_client_email".
58
55
  private_key_missing: |-
59
56
  Private key for Google could not be found in the specified location.
60
57
  zone_required: |-
@@ -63,9 +60,6 @@ en:
63
60
  An instance name must be specified via "name" option.
64
61
  image_required: |-
65
62
  An image must be specified via "image" or "image_family" option.
66
- google_key_location_required: |-
67
- A private key pathname is required via:
68
- "google_json_key_location" (for JSON keys)
69
63
  google_project_id_required: |-
70
64
  A Google Cloud Project ID is required via "google_project_id".
71
65
  auto_restart_invalid_on_preemptible: |-
@@ -77,6 +71,9 @@ en:
77
71
  "image" must be unset when setting "image_family"
78
72
  service_accounts_deprecaated: |-
79
73
  "service_accounts is deprecated. Please use scopes instead"
74
+ on_host_maintenance_invalid_with_accelerators: |-
75
+ "on_host_maintenance" option must be set to "TERMINATE" for instances
76
+ with accelerators
80
77
  #-------------------------------------------------------------------------------
81
78
  # Translations for exception classes
82
79
  #-------------------------------------------------------------------------------
@@ -37,10 +37,6 @@ namespace :acceptance do
37
37
  abort "Environment variable GOOGLE_PROJECT_ID is not set. Aborting."
38
38
  end
39
39
 
40
- unless ENV["GOOGLE_CLIENT_EMAIL"]
41
- abort "Environment variable GOOGLE_CLIENT_EMAIL is not set. Aborting."
42
- end
43
-
44
40
  unless ENV["GOOGLE_SSH_USER"]
45
41
  yellow "WARNING: GOOGLE_SSH_USER variable is not set. Will try to start tests using insecure Vagrant private key."
46
42
  end
@@ -70,7 +66,6 @@ namespace :acceptance do
70
66
  image_family
71
67
  synced_folder/rsync
72
68
  provisioner/shell
73
- provisioner/chef-solo
74
69
  ).map{ |s| "provider/google/#{s}" }
75
70
 
76
71
  command = "vagrant-spec test --components=#{components.join(" ")}"
@@ -0,0 +1,40 @@
1
+ require "fileutils"
2
+
3
+ # Helper method to insert text after a line that matches the regex
4
+ def insert_after_line(file, insert, regex = /^## Next/)
5
+ tempfile = File.open("#{file}.tmp", "w")
6
+ f = File.new(file)
7
+ f.each do |line|
8
+ tempfile << line
9
+ next unless line =~ regex
10
+
11
+ tempfile << "\n"
12
+ tempfile << insert
13
+ tempfile << "\n"
14
+ end
15
+ f.close
16
+ tempfile.close
17
+
18
+ FileUtils.mv("#{file}.tmp", file)
19
+ end
20
+
21
+ # Extracts all changes that have been made after the latest pushed tag
22
+ def changes_since_last_tag
23
+ `git --no-pager log $(git describe --tags --abbrev=0)..HEAD --grep="Merge" --pretty=format:"%t - %s%n%b%n"`
24
+ end
25
+
26
+ # Extracts all github users contributed since last tag
27
+ def users_since_last_tag
28
+ `git --no-pager log $(git describe --tags --abbrev=0)..HEAD --grep="Merge" --pretty=format:"%s" | cut -d' ' -f 6 | cut -d/ -f1 | sort | uniq`
29
+ end
30
+
31
+ namespace :changelog do
32
+ task :generate do
33
+ insert_after_line("CHANGELOG.md", changes_since_last_tag, /^## Next/)
34
+ printf("Users contributed since last release:\n")
35
+ contributors = users_since_last_tag.split("\n").map { |name| "@" + name }
36
+ printf("Huge thanks to all our contributors 🎆\n")
37
+ printf("Special thanks to: " + contributors.join(" ") + "\n")
38
+ printf("\nI'll merge this and release the gem once all tests pass.\n")
39
+ end
40
+ end