vagrant-mcs 0.6.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.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.rspec +1 -0
  4. data/CHANGELOG.md +92 -0
  5. data/Gemfile +12 -0
  6. data/LICENSE +8 -0
  7. data/README.md +292 -0
  8. data/Rakefile +21 -0
  9. data/dummy.box +0 -0
  10. data/example_box/README.md +13 -0
  11. data/example_box/mcs.box +0 -0
  12. data/example_box/metadata.json +3 -0
  13. data/lib/vagrant-mcs/action/connect_mcs.rb +51 -0
  14. data/lib/vagrant-mcs/action/elb_deregister_instance.rb +24 -0
  15. data/lib/vagrant-mcs/action/elb_register_instance.rb +24 -0
  16. data/lib/vagrant-mcs/action/is_created.rb +18 -0
  17. data/lib/vagrant-mcs/action/is_stopped.rb +18 -0
  18. data/lib/vagrant-mcs/action/message_already_created.rb +16 -0
  19. data/lib/vagrant-mcs/action/message_not_created.rb +16 -0
  20. data/lib/vagrant-mcs/action/message_will_not_destroy.rb +16 -0
  21. data/lib/vagrant-mcs/action/package_instance.rb +192 -0
  22. data/lib/vagrant-mcs/action/read_ssh_info.rb +53 -0
  23. data/lib/vagrant-mcs/action/read_state.rb +38 -0
  24. data/lib/vagrant-mcs/action/run_instance.rb +274 -0
  25. data/lib/vagrant-mcs/action/start_instance.rb +81 -0
  26. data/lib/vagrant-mcs/action/stop_instance.rb +28 -0
  27. data/lib/vagrant-mcs/action/terminate_instance.rb +51 -0
  28. data/lib/vagrant-mcs/action/timed_provision.rb +21 -0
  29. data/lib/vagrant-mcs/action/wait_for_state.rb +41 -0
  30. data/lib/vagrant-mcs/action/warn_networks.rb +19 -0
  31. data/lib/vagrant-mcs/action.rb +210 -0
  32. data/lib/vagrant-mcs/config.rb +405 -0
  33. data/lib/vagrant-mcs/errors.rb +43 -0
  34. data/lib/vagrant-mcs/plugin.rb +73 -0
  35. data/lib/vagrant-mcs/provider.rb +50 -0
  36. data/lib/vagrant-mcs/util/elb.rb +56 -0
  37. data/lib/vagrant-mcs/util/timer.rb +17 -0
  38. data/lib/vagrant-mcs/version.rb +5 -0
  39. data/lib/vagrant-mcs.rb +18 -0
  40. data/locales/en.yml +153 -0
  41. data/mcs.box +0 -0
  42. data/spec/spec_helper.rb +1 -0
  43. data/spec/vagrant-aws/config_spec.rb +225 -0
  44. data/templates/metadata.json.erb +3 -0
  45. data/templates/vagrant-aws_package_Vagrantfile.erb +5 -0
  46. data/vagrant-mcs.gemspec +60 -0
  47. metadata +172 -0
@@ -0,0 +1,21 @@
1
+ require "vagrant-mcs/util/timer"
2
+
3
+ module VagrantPlugins
4
+ module MCS
5
+ module Action
6
+ # This is the same as the builtin provision except it times the
7
+ # provisioner runs.
8
+ class TimedProvision < Vagrant::Action::Builtin::Provision
9
+ def run_provisioner(env, name, p)
10
+ timer = Util::Timer.time do
11
+ super
12
+ end
13
+
14
+ env[:metrics] ||= {}
15
+ env[:metrics]["provisioner_times"] ||= []
16
+ env[:metrics]["provisioner_times"] << [name, timer]
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,41 @@
1
+ require "log4r"
2
+ require "timeout"
3
+
4
+ module VagrantPlugins
5
+ module MCS
6
+ module Action
7
+ # This action will wait for a machine to reach a specific state or quit by timeout
8
+ class WaitForState
9
+ # env[:result] will be false in case of timeout.
10
+ # @param [Symbol] state Target machine state.
11
+ # @param [Number] timeout Timeout in seconds.
12
+ def initialize(app, env, state, timeout)
13
+ @app = app
14
+ @logger = Log4r::Logger.new("vagrant_mcs::action::wait_for_state")
15
+ @state = state
16
+ @timeout = timeout
17
+ end
18
+
19
+ def call(env)
20
+ env[:result] = true
21
+ if env[:machine].state.id == @state
22
+ @logger.info(I18n.t("vagrant_mcs.already_status", :status => @state))
23
+ else
24
+ @logger.info("Waiting for machine to reach state #{@state}")
25
+ begin
26
+ Timeout.timeout(@timeout) do
27
+ until env[:machine].state.id == @state
28
+ sleep 2
29
+ end
30
+ end
31
+ rescue Timeout::Error
32
+ env[:result] = false # couldn't reach state in time
33
+ end
34
+ end
35
+
36
+ @app.call(env)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,19 @@
1
+ module VagrantPlugins
2
+ module MCS
3
+ module Action
4
+ class WarnNetworks
5
+ def initialize(app, env)
6
+ @app = app
7
+ end
8
+
9
+ def call(env)
10
+ if env[:machine].config.vm.networks.length > 0
11
+ env[:ui].warn(I18n.t("vagrant_mcs.warn_networks"))
12
+ end
13
+
14
+ @app.call(env)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,210 @@
1
+ require "pathname"
2
+
3
+ require "vagrant/action/builder"
4
+
5
+ module VagrantPlugins
6
+ module MCS
7
+ module Action
8
+ # Include the built-in modules so we can use them as top-level things.
9
+ include Vagrant::Action::Builtin
10
+
11
+ def self.action_package
12
+ Vagrant::Action::Builder.new.tap do |b|
13
+ b.use Call, IsCreated do |env, b2|
14
+ if !env[:result]
15
+ b2.use MessageNotCreated
16
+ next
17
+ end
18
+
19
+ # Connect to MCS and then Create a package from the server instance
20
+ b2.use ConnectMCS
21
+ b2.use PackageInstance
22
+ end
23
+ end
24
+ end
25
+
26
+ # This action is called to halt the remote machine.
27
+ def self.action_halt
28
+ Vagrant::Action::Builder.new.tap do |b|
29
+ b.use ConfigValidate
30
+ b.use Call, IsCreated do |env, b2|
31
+ if !env[:result]
32
+ b2.use MessageNotCreated
33
+ next
34
+ end
35
+
36
+ b2.use ConnectMCS
37
+ b2.use StopInstance
38
+ end
39
+ end
40
+ end
41
+
42
+ # This action is called to terminate the remote machine.
43
+ def self.action_destroy
44
+ Vagrant::Action::Builder.new.tap do |b|
45
+ b.use Call, DestroyConfirm do |env, b2|
46
+ if env[:result]
47
+ b2.use ConfigValidate
48
+ b2.use Call, IsCreated do |env2, b3|
49
+ if !env2[:result]
50
+ b3.use MessageNotCreated
51
+ next
52
+ end
53
+ b3.use ConnectMCS
54
+ b3.use ElbDeregisterInstance
55
+ b3.use TerminateInstance
56
+ b3.use ProvisionerCleanup if defined?(ProvisionerCleanup)
57
+ end
58
+ else
59
+ b2.use MessageWillNotDestroy
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ # This action is called when `vagrant provision` is called.
66
+ def self.action_provision
67
+ Vagrant::Action::Builder.new.tap do |b|
68
+ b.use ConfigValidate
69
+ b.use Call, IsCreated do |env, b2|
70
+ if !env[:result]
71
+ b2.use MessageNotCreated
72
+ next
73
+ end
74
+
75
+ b2.use Provision
76
+ b2.use SyncedFolders
77
+ end
78
+ end
79
+ end
80
+
81
+ # This action is called to read the SSH info of the machine. The
82
+ # resulting state is expected to be put into the `:machine_ssh_info`
83
+ # key.
84
+ def self.action_read_ssh_info
85
+ Vagrant::Action::Builder.new.tap do |b|
86
+ b.use ConfigValidate
87
+ b.use ConnectMCS
88
+ b.use ReadSSHInfo
89
+ end
90
+ end
91
+
92
+ # This action is called to read the state of the machine. The
93
+ # resulting state is expected to be put into the `:machine_state_id`
94
+ # key.
95
+ def self.action_read_state
96
+ Vagrant::Action::Builder.new.tap do |b|
97
+ b.use ConfigValidate
98
+ b.use ConnectMCS
99
+ b.use ReadState
100
+ end
101
+ end
102
+
103
+ # This action is called to SSH into the machine.
104
+ def self.action_ssh
105
+ Vagrant::Action::Builder.new.tap do |b|
106
+ b.use ConfigValidate
107
+ b.use Call, IsCreated do |env, b2|
108
+ if !env[:result]
109
+ b2.use MessageNotCreated
110
+ next
111
+ end
112
+
113
+ b2.use SSHExec
114
+ end
115
+ end
116
+ end
117
+
118
+ def self.action_ssh_run
119
+ Vagrant::Action::Builder.new.tap do |b|
120
+ b.use ConfigValidate
121
+ b.use Call, IsCreated do |env, b2|
122
+ if !env[:result]
123
+ b2.use MessageNotCreated
124
+ next
125
+ end
126
+
127
+ b2.use SSHRun
128
+ end
129
+ end
130
+ end
131
+
132
+ def self.action_prepare_boot
133
+ Vagrant::Action::Builder.new.tap do |b|
134
+ b.use Provision
135
+ b.use SyncedFolders
136
+ b.use WarnNetworks
137
+ b.use ElbRegisterInstance
138
+ end
139
+ end
140
+
141
+ # This action is called to bring the box up from nothing.
142
+ def self.action_up
143
+ Vagrant::Action::Builder.new.tap do |b|
144
+ b.use HandleBox
145
+ b.use ConfigValidate
146
+ b.use BoxCheckOutdated
147
+ b.use ConnectMCS
148
+ b.use Call, IsCreated do |env1, b1|
149
+ if env1[:result]
150
+ b1.use Call, IsStopped do |env2, b2|
151
+ if env2[:result]
152
+ b2.use action_prepare_boot
153
+ b2.use StartInstance # restart this instance
154
+ else
155
+ b2.use MessageAlreadyCreated # TODO write a better message
156
+ end
157
+ end
158
+ else
159
+ b1.use action_prepare_boot
160
+ b1.use RunInstance # launch a new instance
161
+ end
162
+ end
163
+ end
164
+ end
165
+
166
+ def self.action_reload
167
+ Vagrant::Action::Builder.new.tap do |b|
168
+ b.use ConfigValidate
169
+ b.use ConnectMCS
170
+ b.use Call, IsCreated do |env, b2|
171
+ if !env[:result]
172
+ b2.use MessageNotCreated
173
+ next
174
+ end
175
+
176
+ b2.use action_halt
177
+ b2.use Call, WaitForState, :stopped, 120 do |env2, b3|
178
+ if env2[:result]
179
+ b3.use action_up
180
+ else
181
+ # TODO we couldn't reach :stopped, what now?
182
+ end
183
+ end
184
+ end
185
+ end
186
+ end
187
+
188
+ # The autoload farm
189
+ action_root = Pathname.new(File.expand_path("../action", __FILE__))
190
+ autoload :ConnectMCS, action_root.join("connect_mcs")
191
+ autoload :IsCreated, action_root.join("is_created")
192
+ autoload :IsStopped, action_root.join("is_stopped")
193
+ autoload :MessageAlreadyCreated, action_root.join("message_already_created")
194
+ autoload :MessageNotCreated, action_root.join("message_not_created")
195
+ autoload :MessageWillNotDestroy, action_root.join("message_will_not_destroy")
196
+ autoload :PackageInstance, action_root.join("package_instance")
197
+ autoload :ReadSSHInfo, action_root.join("read_ssh_info")
198
+ autoload :ReadState, action_root.join("read_state")
199
+ autoload :RunInstance, action_root.join("run_instance")
200
+ autoload :StartInstance, action_root.join("start_instance")
201
+ autoload :StopInstance, action_root.join("stop_instance")
202
+ autoload :TerminateInstance, action_root.join("terminate_instance")
203
+ autoload :TimedProvision, action_root.join("timed_provision") # some plugins now expect this action to exist
204
+ autoload :WaitForState, action_root.join("wait_for_state")
205
+ autoload :WarnNetworks, action_root.join("warn_networks")
206
+ autoload :ElbRegisterInstance, action_root.join("elb_register_instance")
207
+ autoload :ElbDeregisterInstance, action_root.join("elb_deregister_instance")
208
+ end
209
+ end
210
+ end
@@ -0,0 +1,405 @@
1
+ require "vagrant"
2
+
3
+ module VagrantPlugins
4
+ module MCS
5
+ class Config < Vagrant.plugin("2", :config)
6
+ # The access key ID for accessing MCS.
7
+ #
8
+ # @return [String]
9
+ attr_accessor :access_key_id
10
+
11
+ # The ID of the AMI to use.
12
+ #
13
+ # @return [String]
14
+ attr_accessor :ami
15
+
16
+ # The availability zone to launch the instance into. If nil, it will
17
+ # use the default for your account.
18
+ #
19
+ # @return [String]
20
+ attr_accessor :availability_zone
21
+
22
+ # The timeout to wait for an instance to become ready.
23
+ #
24
+ # @return [Fixnum]
25
+ attr_accessor :instance_ready_timeout
26
+
27
+ # The timeout to wait for an instance to successfully burn into an AMI.
28
+ #
29
+ # @return [Fixnum]
30
+ attr_accessor :instance_package_timeout
31
+
32
+ # The type of instance to launch, such as "m3.medium"
33
+ #
34
+ # @return [String]
35
+ attr_accessor :instance_type
36
+
37
+ # The name of the keypair to use.
38
+ #
39
+ # @return [String]
40
+ attr_accessor :keypair_name
41
+
42
+ # The private IP address to give this machine (VPC).
43
+ #
44
+ # @return [String]
45
+ attr_accessor :private_ip_address
46
+
47
+ # If true, acquire and attach an elastic IP address.
48
+ # If set to an IP address, assign to the instance.
49
+ #
50
+ # @return [String]
51
+ attr_accessor :elastic_ip
52
+
53
+ # The name of the MCS region in which to create the instance.
54
+ #
55
+ # @return [String]
56
+ attr_accessor :region
57
+
58
+ # The EC2 endpoint to connect to
59
+ #
60
+ # @return [String]
61
+ attr_accessor :endpoint
62
+
63
+ # The version of the MCS api to use
64
+ #
65
+ # @return [String]
66
+ attr_accessor :version
67
+
68
+ # The secret access key for accessing MCS.
69
+ #
70
+ # @return [String]
71
+ attr_accessor :secret_access_key
72
+
73
+ # The secret access url for accessing MCS.
74
+ #
75
+ # @return [String]
76
+ attr_accessor :secret_access_url
77
+
78
+ # The token associated with the key for accessing MCS.
79
+ #
80
+ # @return [String]
81
+ attr_accessor :session_token
82
+
83
+ # The security groups to set on the instance. For VPC this must
84
+ # be a list of IDs. For EC2, it can be either.
85
+ #
86
+ # @return [Array<String>]
87
+ attr_reader :security_groups
88
+
89
+ # The Amazon resource name (ARN) of the IAM Instance Profile
90
+ # to associate with the instance.
91
+ #
92
+ # @return [String]
93
+ attr_accessor :iam_instance_profile_arn
94
+
95
+ # The name of the IAM Instance Profile to associate with
96
+ # the instance.
97
+ #
98
+ # @return [String]
99
+ attr_accessor :iam_instance_profile_name
100
+
101
+ # The subnet ID to launch the machine into (VPC).
102
+ #
103
+ # @return [String]
104
+ attr_accessor :subnet_id
105
+
106
+ # The tags for the machine.
107
+ #
108
+ # @return [Hash<String, String>]
109
+ attr_accessor :tags
110
+
111
+ # Use IAM Instance Role for authentication to MCS instead of an
112
+ # explicit access_id and secret_access_key
113
+ #
114
+ # @return [Boolean]
115
+ attr_accessor :use_iam_profile
116
+
117
+ # The user data string
118
+ #
119
+ # @return [String]
120
+ attr_accessor :user_data
121
+
122
+ # Block device mappings
123
+ #
124
+ # @return [Array<Hash>]
125
+ attr_accessor :block_device_mapping
126
+
127
+ # Indicates whether an instance stops or terminates when you initiate shutdown from the instance
128
+ #
129
+ # @return [bool]
130
+ attr_accessor :terminate_on_shutdown
131
+
132
+ # Specifies which address to connect to with ssh
133
+ # Must be one of:
134
+ # - :public_ip_address
135
+ # - :dns_name
136
+ # - :private_ip_address
137
+ # This attribute also accepts an array of symbols
138
+ #
139
+ # @return [Symbol]
140
+ attr_accessor :ssh_host_attribute
141
+
142
+ # Enables Monitoring
143
+ #
144
+ # @return [Boolean]
145
+ attr_accessor :monitoring
146
+
147
+ # EBS optimized instance
148
+ #
149
+ # @return [Boolean]
150
+ attr_accessor :ebs_optimized
151
+
152
+ # Assigning a public IP address in a VPC
153
+ #
154
+ # @return [Boolean]
155
+ attr_accessor :associate_public_ip
156
+
157
+ # The name of ELB, which an instance should be
158
+ # attached to
159
+ #
160
+ # @return [String]
161
+ attr_accessor :elb
162
+
163
+ def initialize(region_specific=false)
164
+ @access_key_id = UNSET_VALUE
165
+ @ami = UNSET_VALUE
166
+ @availability_zone = UNSET_VALUE
167
+ @instance_ready_timeout = UNSET_VALUE
168
+ @instance_package_timeout = UNSET_VALUE
169
+ @instance_type = UNSET_VALUE
170
+ @keypair_name = UNSET_VALUE
171
+ @private_ip_address = UNSET_VALUE
172
+ @region = UNSET_VALUE
173
+ @endpoint = UNSET_VALUE
174
+ @version = UNSET_VALUE
175
+ @secret_access_key = UNSET_VALUE
176
+ @secret_access_url = UNSET_VALUE
177
+ @session_token = UNSET_VALUE
178
+ @security_groups = UNSET_VALUE
179
+ @subnet_id = UNSET_VALUE
180
+ @tags = {}
181
+ @user_data = UNSET_VALUE
182
+ @use_iam_profile = UNSET_VALUE
183
+ @block_device_mapping = []
184
+ @elastic_ip = UNSET_VALUE
185
+ @iam_instance_profile_arn = UNSET_VALUE
186
+ @iam_instance_profile_name = UNSET_VALUE
187
+ @terminate_on_shutdown = UNSET_VALUE
188
+ @ssh_host_attribute = UNSET_VALUE
189
+ @monitoring = UNSET_VALUE
190
+ @ebs_optimized = UNSET_VALUE
191
+ @associate_public_ip = UNSET_VALUE
192
+ @elb = UNSET_VALUE
193
+
194
+ # Internal state (prefix with __ so they aren't automatically
195
+ # merged)
196
+ @__compiled_region_configs = {}
197
+ @__finalized = false
198
+ @__region_config = {}
199
+ @__region_specific = region_specific
200
+ end
201
+
202
+ # set security_groups
203
+ def security_groups=(value)
204
+ # convert value to array if necessary
205
+ @security_groups = value.is_a?(Array) ? value : [value]
206
+ end
207
+
208
+ # Allows region-specific overrides of any of the settings on this
209
+ # configuration object. This allows the user to override things like
210
+ # AMI and keypair name for regions. Example:
211
+ #
212
+ # mcs.region_config "us-east-1" do |region|
213
+ # region.ami = "ami-12345678"
214
+ # region.keypair_name = "company-east"
215
+ # end
216
+ #
217
+ # @param [String] region The region name to configure.
218
+ # @param [Hash] attributes Direct attributes to set on the configuration
219
+ # as a shortcut instead of specifying a full block.
220
+ # @yield [config] Yields a new MCS configuration.
221
+ def region_config(region, attributes=nil, &block)
222
+ # Append the block to the list of region configs for that region.
223
+ # We'll evaluate these upon finalization.
224
+ @__region_config[region] ||= []
225
+
226
+ # Append a block that sets attributes if we got one
227
+ if attributes
228
+ attr_block = lambda do |config|
229
+ config.set_options(attributes)
230
+ end
231
+
232
+ @__region_config[region] << attr_block
233
+ end
234
+
235
+ # Append a block if we got one
236
+ @__region_config[region] << block if block_given?
237
+ end
238
+
239
+ #-------------------------------------------------------------------
240
+ # Internal methods.
241
+ #-------------------------------------------------------------------
242
+
243
+ def merge(other)
244
+ super.tap do |result|
245
+ # Copy over the region specific flag. "True" is retained if either
246
+ # has it.
247
+ new_region_specific = other.instance_variable_get(:@__region_specific)
248
+ result.instance_variable_set(
249
+ :@__region_specific, new_region_specific || @__region_specific)
250
+
251
+ # Go through all the region configs and prepend ours onto
252
+ # theirs.
253
+ new_region_config = other.instance_variable_get(:@__region_config)
254
+ @__region_config.each do |key, value|
255
+ new_region_config[key] ||= []
256
+ new_region_config[key] = value + new_region_config[key]
257
+ end
258
+
259
+ # Set it
260
+ result.instance_variable_set(:@__region_config, new_region_config)
261
+
262
+ # Merge in the tags
263
+ result.tags.merge!(self.tags)
264
+ result.tags.merge!(other.tags)
265
+
266
+ # Merge block_device_mapping
267
+ result.block_device_mapping |= self.block_device_mapping
268
+ result.block_device_mapping |= other.block_device_mapping
269
+ end
270
+ end
271
+
272
+ def finalize!
273
+ # Try to get access keys from standard MCS environment variables; they
274
+ # will default to nil if the environment variables are not present.
275
+ @access_key_id = ENV['MCS_ACCESS_KEY'] if @access_key_id == UNSET_VALUE
276
+ @secret_access_key = ENV['MCS_SECRET_KEY'] if @secret_access_key == UNSET_VALUE
277
+ @session_token = ENV['MCS_SESSION_TOKEN'] if @session_token == UNSET_VALUE
278
+
279
+ # AMI must be nil, since we can't default that
280
+ @ami = nil if @ami == UNSET_VALUE
281
+
282
+ # Set the default timeout for waiting for an instance to be ready
283
+ @instance_ready_timeout = 120 if @instance_ready_timeout == UNSET_VALUE
284
+
285
+ # Set the default timeout for waiting for an instance to burn into and ami
286
+ @instance_package_timeout = 600 if @instance_package_timeout == UNSET_VALUE
287
+
288
+ # Default instance type is an m3.medium
289
+ #@instance_type = "m3.medium" if @instance_type == UNSET_VALUE
290
+ @instance_type = "C1_M2" if @instance_type == UNSET_VALUE
291
+ # Keypair defaults to nil
292
+ @keypair_name = nil if @keypair_name == UNSET_VALUE
293
+
294
+ # Default the private IP to nil since VPC is not default
295
+ @private_ip_address = nil if @private_ip_address == UNSET_VALUE
296
+
297
+ # Acquire an elastic IP if requested
298
+ @elastic_ip = nil if @elastic_ip == UNSET_VALUE
299
+
300
+ # Default region is us-east-1. This is sensible because MCS
301
+ # generally defaults to this as well.
302
+ @region = "us-east-1" if @region == UNSET_VALUE
303
+ @availability_zone = nil if @availability_zone == UNSET_VALUE
304
+ @endpoint = nil if @endpoint == UNSET_VALUE
305
+ @version = nil if @version == UNSET_VALUE
306
+
307
+ # The security groups are empty by default.
308
+ @security_groups = [] if @security_groups == UNSET_VALUE
309
+
310
+ # Subnet is nil by default otherwise we'd launch into VPC.
311
+ @subnet_id = nil if @subnet_id == UNSET_VALUE
312
+
313
+ # IAM Instance profile arn/name is nil by default.
314
+ @iam_instance_profile_arn = nil if @iam_instance_profile_arn == UNSET_VALUE
315
+ @iam_instance_profile_name = nil if @iam_instance_profile_name == UNSET_VALUE
316
+
317
+ # By default we don't use an IAM profile
318
+ @use_iam_profile = false if @use_iam_profile == UNSET_VALUE
319
+
320
+ # User Data is nil by default
321
+ @user_data = nil if @user_data == UNSET_VALUE
322
+
323
+ # default false
324
+ @terminate_on_shutdown = false if @terminate_on_shutdown == UNSET_VALUE
325
+
326
+ # default to nil
327
+ @ssh_host_attribute = nil if @ssh_host_attribute == UNSET_VALUE
328
+
329
+ # default false
330
+ @monitoring = false if @monitoring == UNSET_VALUE
331
+
332
+ # default false
333
+ @ebs_optimized = false if @ebs_optimized == UNSET_VALUE
334
+
335
+ # default false
336
+ @associate_public_ip = false if @associate_public_ip == UNSET_VALUE
337
+
338
+ # Don't attach instance to any ELB by default
339
+ @elb = nil if @elb == UNSET_VALUE
340
+
341
+ # Compile our region specific configurations only within
342
+ # NON-REGION-SPECIFIC configurations.
343
+ if !@__region_specific
344
+ @__region_config.each do |region, blocks|
345
+ config = self.class.new(true).merge(self)
346
+
347
+ # Execute the configuration for each block
348
+ blocks.each { |b| b.call(config) }
349
+
350
+ # The region name of the configuration always equals the
351
+ # region config name:
352
+ config.region = region
353
+
354
+ # Finalize the configuration
355
+ config.finalize!
356
+
357
+ # Store it for retrieval
358
+ @__compiled_region_configs[region] = config
359
+ end
360
+ end
361
+
362
+ # Mark that we finalized
363
+ @__finalized = true
364
+ end
365
+
366
+ def validate(machine)
367
+ errors = _detected_errors
368
+
369
+ errors << I18n.t("vagrant_mcs.config.region_required") if @region.nil?
370
+
371
+ if @region
372
+ # Get the configuration for the region we're using and validate only
373
+ # that region.
374
+ config = get_region_config(@region)
375
+
376
+ if !config.use_iam_profile
377
+ errors << I18n.t("vagrant_mcs.config.access_key_id_required") if \
378
+ config.access_key_id.nil?
379
+ errors << I18n.t("vagrant_mcs.config.secret_access_key_required") if \
380
+ config.secret_access_key.nil?
381
+ end
382
+
383
+ if config.associate_public_ip && !config.subnet_id
384
+ errors << I18n.t("vagrant_mcs.config.subnet_id_required_with_public_ip")
385
+ end
386
+
387
+ errors << I18n.interpolate("vagrant_mcs.config.ami_required", :region => @region) if config.ami.nil?
388
+ end
389
+
390
+ { "MCS Provider" => errors }
391
+ end
392
+
393
+ # This gets the configuration for a specific region. It shouldn't
394
+ # be called by the general public and is only used internally.
395
+ def get_region_config(name)
396
+ if !@__finalized
397
+ raise "Configuration must be finalized before calling this method."
398
+ end
399
+
400
+ # Return the compiled region config
401
+ @__compiled_region_configs[name] || self
402
+ end
403
+ end
404
+ end
405
+ end