tcr-vagrant-google 0.1.4

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.
@@ -0,0 +1,59 @@
1
+ # Copyright 2013 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
+ require "log4r"
15
+
16
+ module VagrantPlugins
17
+ module Google
18
+ module Action
19
+ # This action reads the state of the machine and puts it in the
20
+ # `:machine_state_id` key in the environment.
21
+ class ReadState
22
+ def initialize(app, env)
23
+ @app = app
24
+ @logger = Log4r::Logger.new("vagrant_google::action::read_state")
25
+ end
26
+
27
+ def call(env)
28
+ env[:machine_state_id] = read_state(env[:google_compute], env[:machine])
29
+
30
+ @app.call(env)
31
+ end
32
+
33
+ def read_state(google, machine)
34
+ return :not_created if machine.id.nil?
35
+
36
+ # Find the machine
37
+ zone = machine.provider_config.zone
38
+ # TODO(erjohnso): not sure why this is necessary, 'server' should be nil
39
+ begin
40
+ server = google.servers.get(machine.id, zone)
41
+ rescue Exception => e
42
+ @logger.info("TODO: this shouldn't be happening. Call should return nil")
43
+ @logger.info(e.message)
44
+ server = nil
45
+ end
46
+ if server.nil? || [:"shutting-down", :terminated].include?(server.state.to_sym)
47
+ # The machine can't be found
48
+ @logger.info("Machine '#{zone}:#{machine.id}' not found or terminated, assuming it got destroyed.")
49
+ machine.id = nil
50
+ return :not_created
51
+ end
52
+
53
+ # Return the state
54
+ return server.state.to_sym
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,145 @@
1
+ # Copyright 2013 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
+ require "log4r"
15
+ require 'vagrant/util/retryable'
16
+ require 'vagrant-google/util/timer'
17
+
18
+ module VagrantPlugins
19
+ module Google
20
+ module Action
21
+ # This runs the configured instance.
22
+ class RunInstance
23
+ include Vagrant::Util::Retryable
24
+
25
+ def initialize(app, env)
26
+ @app = app
27
+ @logger = Log4r::Logger.new("vagrant_google::action::run_instance")
28
+ end
29
+
30
+ def call(env)
31
+ # Initialize metrics if they haven't been
32
+ env[:metrics] ||= {}
33
+
34
+ # Get the zone we're going to booting up in
35
+ zone = env[:machine].provider_config.zone
36
+
37
+ # Get the configs
38
+ zone_config = env[:machine].provider_config.get_zone_config(zone)
39
+ image = zone_config.image
40
+ name = zone_config.name
41
+ machine_type = zone_config.machine_type
42
+ disk_size = zone_config.disk_size
43
+ network = zone_config.network
44
+ metadata = zone_config.metadata
45
+ tags = zone_config.tags
46
+ service_accounts = zone_config.service_accounts
47
+
48
+ # Launch!
49
+ env[:ui].info(I18n.t("vagrant_google.launching_instance"))
50
+ env[:ui].info(" -- Name: #{name}")
51
+ env[:ui].info(" -- Type: #{machine_type}")
52
+ env[:ui].info(" -- Disk size: #{disk_size} GB")
53
+ env[:ui].info(" -- Image: #{image}")
54
+ env[:ui].info(" -- Zone: #{zone}") if zone
55
+ env[:ui].info(" -- Network: #{network}") if network
56
+ env[:ui].info(" -- Metadata: '#{metadata}'")
57
+ env[:ui].info(" -- Tags: '#{tags}'")
58
+ env[:ui].info(" -- Scopes: #{service_accounts}")
59
+ begin
60
+ request_start_time = Time.now().to_i
61
+ disk = env[:google_compute].disks.create(
62
+ name: name,
63
+ size_gb: disk_size,
64
+ zone_name: zone,
65
+ source_image: image
66
+ )
67
+ disk.wait_for { disk.ready? }
68
+
69
+ defaults = {
70
+ :name => name,
71
+ :zone_name => zone,
72
+ :machine_type => machine_type,
73
+ :disk_size => disk_size,
74
+ :image => image,
75
+ :network => network,
76
+ :metadata => metadata,
77
+ :tags => tags,
78
+ # Second arg to get_as_boot_disk is 'autodelete_disk', defaulting
79
+ # to true
80
+ :disks => [disk.get_as_boot_disk(true, true)],
81
+ :service_accounts => service_accounts,
82
+ }
83
+ server = env[:google_compute].servers.create(defaults)
84
+ @logger.info("Machine '#{zone}:#{name}' created.")
85
+ rescue Fog::Compute::Google::NotFound => e
86
+ raise
87
+ rescue Fog::Compute::Google::Error => e
88
+ raise Errors::FogError, :message => e.message
89
+ end
90
+
91
+ # Immediately save the name since the instance has been created
92
+ env[:machine].id = server.name
93
+ server.reload
94
+
95
+ env[:ui].info(I18n.t("vagrant_google.waiting_for_ready"))
96
+ begin
97
+ server.wait_for { ready? }
98
+ env[:metrics]["instance_ready_time"] = Time.now().to_i - request_start_time
99
+ @logger.info("Time for instance ready: #{env[:metrics]["instance_ready_time"]}")
100
+ env[:ui].info(I18n.t("vagrant_google.ready"))
101
+ rescue
102
+ env[:interrupted] = true
103
+ end
104
+
105
+ if !env[:terminated]
106
+ env[:metrics]["instance_ssh_time"] = Util::Timer.time do
107
+ # Wait for SSH to be ready.
108
+ env[:ui].info(I18n.t("vagrant_google.waiting_for_ssh"))
109
+ while true
110
+ # If we're interrupted just back out
111
+ break if env[:interrupted]
112
+ break if env[:machine].communicate.ready?
113
+ sleep 2
114
+ end
115
+ end
116
+ @logger.info("Time for SSH ready: #{env[:metrics]["instance_ssh_time"]}")
117
+ env[:ui].info(I18n.t("vagrant_google.ready_ssh"))
118
+ end
119
+
120
+ # Terminate the instance if we were interrupted
121
+ terminate(env) if env[:interrupted]
122
+
123
+ @app.call(env)
124
+ end
125
+
126
+ def recover(env)
127
+ return if env["vagrant.error"].is_a?(Vagrant::Errors::VagrantError)
128
+
129
+ if env[:machine].provider.state.id != :not_created
130
+ # Undo the import
131
+ terminate(env)
132
+ end
133
+ end
134
+
135
+ def terminate(env)
136
+ destroy_env = env.dup
137
+ destroy_env.delete(:interrupted)
138
+ destroy_env[:config_validate] = false
139
+ destroy_env[:force_confirm_destroy] = true
140
+ env[:action_runner].run(Action.action_destroy, destroy_env)
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,87 @@
1
+ # Copyright 2013 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
+ require "log4r"
15
+ require "vagrant/util/subprocess"
16
+ require "vagrant/util/scoped_hash_override"
17
+
18
+ module VagrantPlugins
19
+ module Google
20
+ module Action
21
+ # This middleware uses `rsync` to sync the folders over to the
22
+ # Google instance.
23
+ class SyncFolders
24
+ include Vagrant::Util::ScopedHashOverride
25
+
26
+ def initialize(app, env)
27
+ @app = app
28
+ @logger = Log4r::Logger.new("vagrant_google::action::sync_folders")
29
+ end
30
+
31
+ def call(env)
32
+ @app.call(env)
33
+
34
+ ssh_info = env[:machine].ssh_info
35
+
36
+ env[:machine].config.vm.synced_folders.each do |id, data|
37
+ data = scoped_hash_override(data, :google)
38
+
39
+ # Ignore disabled shared folders
40
+ next if data[:disabled]
41
+
42
+ hostpath = File.expand_path(data[:hostpath], env[:root_path])
43
+ guestpath = data[:guestpath]
44
+
45
+ # Make sure there is a trailing slash on the host path to
46
+ # avoid creating an additional directory with rsync
47
+ hostpath = "#{hostpath}/" if hostpath !~ /\/$/
48
+
49
+ env[:ui].info(I18n.t("vagrant_google.rsync_folder",
50
+ :hostpath => hostpath,
51
+ :guestpath => guestpath))
52
+
53
+ # Create the guest path
54
+ env[:machine].communicate.sudo("mkdir -p '#{guestpath}'")
55
+ env[:machine].communicate.sudo(
56
+ "chown #{ssh_info[:username]} '#{guestpath}'")
57
+
58
+ # patch from https://github.com/tmatilai/vagrant-aws/commit/4a043a96076c332220ec4ec19470c4af5597dd51
59
+ def ssh_key_options(ssh_info)
60
+ # Ensure that `private_key_path` is an Array (for Vagrant < 1.4)
61
+ Array(ssh_info[:private_key_path]).map { |path| "-i '#{path}' " }.join
62
+ end
63
+
64
+ #collect rsync excludes specified :rsync__excludes=>['path1',...] in synced_folder options
65
+ excludes = ['.vagrant/', *Array(data[:rsync__excludes])]
66
+
67
+ # Rsync over to the guest path using the SSH info
68
+ command = [
69
+ "rsync", "--verbose", "--archive", "-z",
70
+ *excludes.map{|e|['--exclude', e]}.flatten,
71
+ "-e", "ssh -p #{ssh_info[:port]} -o StrictHostKeyChecking=no #{ssh_key_options(ssh_info)}",
72
+ hostpath,
73
+ "#{ssh_info[:username]}@#{ssh_info[:host]}:#{guestpath}"]
74
+
75
+ r = Vagrant::Util::Subprocess.execute(*command)
76
+ if r.exit_code != 0
77
+ raise Errors::RsyncError,
78
+ :guestpath => guestpath,
79
+ :hostpath => hostpath,
80
+ :stderr => r.stderr
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,40 @@
1
+ # Copyright 2013 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
+ require "log4r"
15
+
16
+ module VagrantPlugins
17
+ module Google
18
+ module Action
19
+ # This terminates the running instance.
20
+ class TerminateInstance
21
+ def initialize(app, env)
22
+ @app = app
23
+ @logger = Log4r::Logger.new("vagrant_google::action::terminate_instance")
24
+ end
25
+
26
+ def call(env)
27
+ server = env[:google_compute].servers.get(env[:machine].id, env[:machine].provider_config.zone)
28
+
29
+ # Destroy the server and remove the tracking ID
30
+ env[:ui].info(I18n.t("vagrant_google.terminating"))
31
+ server.destroy if not server.nil?
32
+ server.wait_for { not ready? }
33
+ env[:machine].id = nil
34
+
35
+ @app.call(env)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,34 @@
1
+ # Copyright 2013 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
+ require "vagrant-google/util/timer"
15
+
16
+ module VagrantPlugins
17
+ module Google
18
+ module Action
19
+ # This is the same as the builtin provision except it times the
20
+ # provisioner runs.
21
+ class TimedProvision < Vagrant::Action::Builtin::Provision
22
+ def run_provisioner(env, name, p)
23
+ timer = Util::Timer.time do
24
+ super
25
+ end
26
+
27
+ env[:metrics] ||= {}
28
+ env[:metrics]["provisioner_times"] ||= []
29
+ env[:metrics]["provisioner_times"] << [name, timer]
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,32 @@
1
+ # Copyright 2013 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
+ module VagrantPlugins
15
+ module Google
16
+ module Action
17
+ class WarnNetworks
18
+ def initialize(app, env)
19
+ @app = app
20
+ end
21
+
22
+ def call(env)
23
+ if env[:machine].config.vm.networks.length > 0
24
+ env[:ui].warn(I18n.t("vagrant_google.warn_networks"))
25
+ end
26
+
27
+ @app.call(env)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,265 @@
1
+ # Copyright 2013 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
+ require "vagrant"
15
+
16
+ module VagrantPlugins
17
+ module Google
18
+ class Config < Vagrant.plugin("2", :config)
19
+ # The Service Account Client ID Email address
20
+ #
21
+ # @return [String]
22
+ attr_accessor :google_client_email
23
+
24
+ # The path to the Service Account private key
25
+ #
26
+ # @return [String]
27
+ attr_accessor :google_key_location
28
+
29
+ # The Google Cloud Project ID (not name or number)
30
+ #
31
+ # @return [String]
32
+ attr_accessor :google_project_id
33
+
34
+ # The image name of the instance to use.
35
+ #
36
+ # @return [String]
37
+ attr_accessor :image
38
+
39
+ # The type of machine to launch, such as "n1-standard-1"
40
+ #
41
+ # @return [String]
42
+ attr_accessor :machine_type
43
+
44
+ # The size of disk in GB
45
+ #
46
+ # @return [Int]
47
+ attr_accessor :disk_size
48
+
49
+ # The user metadata string
50
+ #
51
+ # @return [Hash<String, String>]
52
+ attr_accessor :metadata
53
+
54
+ # The name of the instance
55
+ #
56
+ # @return [String]
57
+ attr_accessor :name
58
+
59
+ # The name of the network
60
+ #
61
+ # @return [String]
62
+ attr_accessor :network
63
+
64
+ # Tags to apply to the instance
65
+ #
66
+ # @return [Array]
67
+ attr_accessor :tags
68
+
69
+ # The timeout value waiting for instance ready
70
+ #
71
+ # @return [Int]
72
+ attr_accessor :instance_ready_timeout
73
+
74
+ # The tags for the machine.
75
+ # TODO(erjohnso): not supported in fog
76
+ #
77
+ # @return [Hash<String, String>]
78
+ #attr_accessor :tags
79
+
80
+ # The zone to launch the instance into. If nil, it will
81
+ # use the default us-central1-f.
82
+ #
83
+ # @return [String]
84
+ attr_accessor :zone
85
+
86
+ # The list of access controls for service accounts.
87
+ #
88
+ # @return [Array]
89
+ attr_accessor :service_accounts
90
+
91
+ def initialize(zone_specific=false)
92
+ @google_client_email = UNSET_VALUE
93
+ @google_key_location = UNSET_VALUE
94
+ @google_project_id = UNSET_VALUE
95
+ @image = UNSET_VALUE
96
+ @machine_type = UNSET_VALUE
97
+ @disk_size = UNSET_VALUE
98
+ @metadata = {}
99
+ @name = UNSET_VALUE
100
+ @network = UNSET_VALUE
101
+ @tags = []
102
+ @instance_ready_timeout = UNSET_VALUE
103
+ @zone = UNSET_VALUE
104
+ @service_accounts = UNSET_VALUE
105
+
106
+ # Internal state (prefix with __ so they aren't automatically
107
+ # merged)
108
+ @__compiled_zone_configs = {}
109
+ @__finalized = false
110
+ @__zone_config = {}
111
+ @__zone_specific = zone_specific
112
+ end
113
+
114
+ # Allows zone-specific overrides of any of the settings on this
115
+ # configuration object. This allows the user to override things like
116
+ # image and machine type name for zones. Example:
117
+ #
118
+ # google.zone_config "us-central1-f" do |zone|
119
+ # zone.image = "debian-7-wheezy-v20140926"
120
+ # zone.machine_type = "n1-standard-4"
121
+ # end
122
+ #
123
+ # @param [String] zone The zone name to configure.
124
+ # @param [Hash] attributes Direct attributes to set on the configuration
125
+ # as a shortcut instead of specifying a full block.
126
+ # @yield [config] Yields a new Google configuration.
127
+ def zone_config(zone, attributes=nil, &block)
128
+ # Append the block to the list of zone configs for that zone.
129
+ # We'll evaluate these upon finalization.
130
+ @__zone_config[zone] ||= []
131
+
132
+ # Append a block that sets attributes if we got one
133
+ if attributes
134
+ attr_block = lambda do |config|
135
+ config.set_options(attributes)
136
+ end
137
+
138
+ @__zone_config[zone] << attr_block
139
+ end
140
+
141
+ # Append a block if we got one
142
+ @__zone_config[zone] << block if block_given?
143
+ end
144
+
145
+ #-------------------------------------------------------------------
146
+ # Internal methods.
147
+ #-------------------------------------------------------------------
148
+
149
+ def merge(other)
150
+ super.tap do |result|
151
+ # Copy over the zone specific flag. "True" is retained if either
152
+ # has it.
153
+ new_zone_specific = other.instance_variable_get(:@__zone_specific)
154
+ result.instance_variable_set(
155
+ :@__zone_specific, new_zone_specific || @__zone_specific)
156
+
157
+ # Go through all the zone configs and prepend ours onto
158
+ # theirs.
159
+ new_zone_config = other.instance_variable_get(:@__zone_config)
160
+ @__zone_config.each do |key, value|
161
+ new_zone_config[key] ||= []
162
+ new_zone_config[key] = value + new_zone_config[key]
163
+ end
164
+
165
+ # Set it
166
+ result.instance_variable_set(:@__zone_config, new_zone_config)
167
+
168
+ # Merge in the metadata
169
+ result.metadata.merge!(self.metadata)
170
+ result.metadata.merge!(other.metadata)
171
+ end
172
+ end
173
+
174
+ def finalize!
175
+ # Try to get access keys from standard Google environment variables; they
176
+ # will default to nil if the environment variables are not present.
177
+ @google_client_email = ENV['GOOGLE_CLIENT_EMAIL'] if @google_client_email == UNSET_VALUE
178
+ @google_key_location = ENV['GOOGLE_KEY_LOCATION'] if @google_key_location == UNSET_VALUE
179
+ @google_project_id = ENV['GOOGLE_PROJECT_ID'] if @google_project_id == UNSET_VALUE
180
+
181
+ # Image must be nil, since we can't default that
182
+ @image = "debian-7-wheezy-v20140926" if @image == UNSET_VALUE
183
+
184
+ # Default instance type is an n1-standard-1
185
+ @machine_type = "n1-standard-1" if @machine_type == UNSET_VALUE
186
+
187
+ # Default disk size is 10 GB
188
+ @disk_size = 10 if @disk_size == UNSET_VALUE
189
+
190
+ # Instance name defaults to a new datetime value (hour granularity)
191
+ t = Time.now
192
+ @name = "i-#{t.year}#{t.month.to_s.rjust(2,'0')}#{t.day.to_s.rjust(2,'0')}#{t.hour.to_s.rjust(2,'0')}" if @name == UNSET_VALUE
193
+
194
+ # Network defaults to 'default'
195
+ @network = "default" if @network == UNSET_VALUE
196
+
197
+ # Default zone is us-central1-f.
198
+ @zone = "us-central1-f" if @zone == UNSET_VALUE
199
+
200
+ # Default instance_ready_timeout
201
+ @instance_ready_timeout = 20 if @instance_ready_timeout == UNSET_VALUE
202
+
203
+ # Default service_accounts
204
+ @service_accounts = nil if @service_accounts == UNSET_VALUE
205
+
206
+ # Compile our zone specific configurations only within
207
+ # NON-zone-SPECIFIC configurations.
208
+ if !@__zone_specific
209
+ @__zone_config.each do |zone, blocks|
210
+ config = self.class.new(true).merge(self)
211
+
212
+ # Execute the configuration for each block
213
+ blocks.each { |b| b.call(config) }
214
+
215
+ # The zone name of the configuration always equals the
216
+ # zone config name:
217
+ config.zone = zone
218
+
219
+ # Finalize the configuration
220
+ config.finalize!
221
+
222
+ # Store it for retrieval
223
+ @__compiled_zone_configs[zone] = config
224
+ end
225
+ end
226
+
227
+ # Mark that we finalized
228
+ @__finalized = true
229
+ end
230
+
231
+ def validate(machine)
232
+ errors = _detected_errors
233
+
234
+ errors << I18n.t("vagrant_google.config.zone_required") if @zone.nil?
235
+
236
+ if @zone
237
+ config = get_zone_config(@zone)
238
+
239
+ errors << I18n.t("vagrant_google.config.google_project_id_required") if \
240
+ config.google_project_id.nil?
241
+ errors << I18n.t("vagrant_google.config.google_client_email_required") if \
242
+ config.google_client_email.nil?
243
+ errors << I18n.t("vagrant_google.config.google_key_location_required") if \
244
+ config.google_key_location.nil?
245
+ end
246
+
247
+ errors << I18n.t("vagrant_google.config.image_required") if config.image.nil?
248
+ errors << I18n.t("vagrant_google.config.name_required") if @name.nil?
249
+
250
+ { "Google Provider" => errors }
251
+ end
252
+
253
+ # This gets the configuration for a specific zone. It shouldn't
254
+ # be called by the general public and is only used internally.
255
+ def get_zone_config(name)
256
+ if !@__finalized
257
+ raise "Configuration must be finalized before calling this method."
258
+ end
259
+
260
+ # Return the compiled zone config
261
+ @__compiled_zone_configs[name] || self
262
+ end
263
+ end
264
+ end
265
+ end