vagrant-google 2.4.0.rc0 → 2.7.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"))
@@ -82,6 +82,15 @@ module VagrantPlugins
82
82
  end
83
83
  end
84
84
 
85
+ # This action is called to setup the Windows user/password on the machine.
86
+ def self.action_setup_winrm_password
87
+ Vagrant::Action::Builder.new.tap do |b|
88
+ b.use ConfigValidate
89
+ b.use ConnectGoogle
90
+ b.use SetupWinrmPassword
91
+ end
92
+ end
93
+
85
94
  # This action is called to read the state of the machine. The
86
95
  # resulting state is expected to be put into the `:machine_state_id`
87
96
  # key.
@@ -182,6 +191,7 @@ module VagrantPlugins
182
191
  autoload :MessageNotCreated, action_root.join("message_not_created")
183
192
  autoload :MessageWillNotDestroy, action_root.join("message_will_not_destroy")
184
193
  autoload :ReadSSHInfo, action_root.join("read_ssh_info")
194
+ autoload :SetupWinrmPassword, action_root.join('setup_winrm_password')
185
195
  autoload :ReadState, action_root.join("read_state")
186
196
  autoload :RunInstance, action_root.join("run_instance")
187
197
  autoload :StartInstance, action_root.join("start_instance")
@@ -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
@@ -178,38 +178,74 @@ 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 a display enabled
197
+ #
198
+ # @return Boolean
199
+ attr_accessor :enable_display
200
+
201
+ # whether the instance has the vTPM enabled
202
+ #
203
+ # @return Boolean
204
+ attr_accessor :enable_vtpm
205
+
206
+ # whether the instance has integrity monitoring enabled
207
+ #
208
+ # @return Boolean
209
+ attr_accessor :enable_integrity_monitoring
210
+
181
211
  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 = []
212
+ @google_json_key_location = UNSET_VALUE
213
+ @google_project_id = UNSET_VALUE
214
+ @image = UNSET_VALUE
215
+ @image_family = UNSET_VALUE
216
+ @image_project_id = UNSET_VALUE
217
+ @instance_group = UNSET_VALUE
218
+ @machine_type = UNSET_VALUE
219
+ @disk_size = UNSET_VALUE
220
+ @disk_name = UNSET_VALUE
221
+ @disk_type = UNSET_VALUE
222
+ @metadata = {}
223
+ @name = UNSET_VALUE
224
+ @network = UNSET_VALUE
225
+ @network_project_id = UNSET_VALUE
226
+ @subnetwork = UNSET_VALUE
227
+ @tags = []
228
+ @labels = {}
229
+ @can_ip_forward = UNSET_VALUE
230
+ @external_ip = UNSET_VALUE
231
+ @network_ip = UNSET_VALUE
232
+ @use_private_ip = UNSET_VALUE
233
+ @autodelete_disk = UNSET_VALUE
234
+ @preemptible = UNSET_VALUE
235
+ @auto_restart = UNSET_VALUE
236
+ @on_host_maintenance = UNSET_VALUE
237
+ @instance_ready_timeout = UNSET_VALUE
238
+ @zone = UNSET_VALUE
239
+ @scopes = UNSET_VALUE
240
+ @service_accounts = UNSET_VALUE
241
+ @service_account = UNSET_VALUE
242
+ @additional_disks = []
243
+ @setup_winrm_password = UNSET_VALUE
244
+ @accelerators = []
245
+ @enable_secure_boot = UNSET_VALUE
246
+ @enable_display = UNSET_VALUE
247
+ @enable_vtpm = UNSET_VALUE
248
+ @enable_integrity_monitoring = UNSET_VALUE
213
249
 
214
250
  # Internal state (prefix with __ so they aren't automatically
215
251
  # merged)
@@ -275,12 +311,10 @@ module VagrantPlugins
275
311
  result.instance_variable_set(:@__zone_config, new_zone_config)
276
312
 
277
313
  # Merge in the metadata
278
- result.metadata.merge!(self.metadata)
279
- result.metadata.merge!(other.metadata)
314
+ result.metadata = self.metadata.merge(other.metadata)
280
315
 
281
316
  # Merge in the labels
282
- result.labels.merge!(self.labels)
283
- result.labels.merge!(other.labels)
317
+ result.labels = self.labels.merge(other.labels)
284
318
 
285
319
  # Merge in the tags
286
320
  result.tags |= self.tags
@@ -295,7 +329,6 @@ module VagrantPlugins
295
329
  def finalize! # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
296
330
  # Try to get access keys from standard Google environment variables; they
297
331
  # will default to nil if the environment variables are not present.
298
- @google_client_email = ENV['GOOGLE_CLIENT_EMAIL'] if @google_client_email == UNSET_VALUE
299
332
  @google_json_key_location = ENV['GOOGLE_JSON_KEY_LOCATION'] if @google_json_key_location == UNSET_VALUE
300
333
  @google_project_id = ENV['GOOGLE_PROJECT_ID'] if @google_project_id == UNSET_VALUE
301
334
 
@@ -356,6 +389,9 @@ module VagrantPlugins
356
389
  # external_ip defaults to nil
357
390
  @external_ip = nil if @external_ip == UNSET_VALUE
358
391
 
392
+ # network_ip defaults to nil
393
+ @network_ip = nil if @network_ip == UNSET_VALUE
394
+
359
395
  # use_private_ip defaults to false
360
396
  @use_private_ip = false if @use_private_ip == UNSET_VALUE
361
397
 
@@ -380,11 +416,26 @@ module VagrantPlugins
380
416
  # Default IAM service account
381
417
  @service_account = nil if @service_account == UNSET_VALUE
382
418
 
419
+ # Default Setup WinRM Password
420
+ @setup_winrm_password = nil if @setup_winrm_password == UNSET_VALUE
421
+
383
422
  # Config option service_accounts is deprecated
384
423
  if @service_accounts
385
424
  @scopes = @service_accounts
386
425
  end
387
426
 
427
+ # enable_secure_boot defaults to nil
428
+ @enable_secure_boot = false if @enable_secure_boot == UNSET_VALUE
429
+
430
+ # enable_display defaults to nil
431
+ @enable_display = false if @enable_display == UNSET_VALUE
432
+
433
+ # enable_vtpm defaults to nil
434
+ @enable_vtpm = false if @enable_vtpm == UNSET_VALUE
435
+
436
+ # enable_integrity_monitoring defaults to nil
437
+ @enable_integrity_monitoring = false if @enable_integrity_monitoring == UNSET_VALUE
438
+
388
439
  # Compile our zone specific configurations only within
389
440
  # NON-zone-SPECIFIC configurations.
390
441
  unless @__zone_specific
@@ -442,6 +493,11 @@ module VagrantPlugins
442
493
 
443
494
  errors << I18n.t("vagrant_google.config.image_required") if config.image.nil? && config.image_family.nil?
444
495
  errors << I18n.t("vagrant_google.config.name_required") if @name.nil?
496
+
497
+ if !config.accelerators.empty?
498
+ errors << I18n.t("vagrant_google.config.on_host_maintenance_invalid_with_accelerators") unless \
499
+ config.on_host_maintenance == "TERMINATE"
500
+ end
445
501
  end
446
502
 
447
503
  if @service_accounts
@@ -13,6 +13,6 @@
13
13
  # limitations under the License.
14
14
  module VagrantPlugins
15
15
  module Google
16
- VERSION = "2.4.0.rc0".freeze
16
+ VERSION = "2.7.0".freeze
17
17
  end
18
18
  end
data/locales/en.yml CHANGED
@@ -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
@@ -71,6 +71,9 @@ en:
71
71
  "image" must be unset when setting "image_family"
72
72
  service_accounts_deprecaated: |-
73
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
74
77
  #-------------------------------------------------------------------------------
75
78
  # Translations for exception classes
76
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
@@ -7,6 +7,8 @@ Vagrant.configure("2") do |config|
7
7
 
8
8
  google.zone_config "australia-southeast1-b" do |zone|
9
9
  zone.name = "vagrant-acceptance-preemptible-#{('a'..'z').to_a.sample(8).join}"
10
+ # Some images no longer fit into default 10GB disk size
11
+ zone.disk_size = 30
10
12
  zone.disk_type = "pd-ssd"
11
13
  zone.image_family = "centos-7"
12
14
  end