21
21
require "aws"
22
22
require "kitchen"
23
23
require "kitchen/driver/ec2_version"
24
- require_relative "client/ec2_client"
24
+ require_relative "ec2/client"
25
+ require_relative "ec2/instance_generator"
25
26
26
27
module Kitchen
27
28
@@ -52,9 +53,7 @@ class Ec2 < Kitchen::Driver::Base # rubocop:disable Metrics/ClassLength
52
53
default_config :retryable_sleep , 5
53
54
default_config :aws_access_key_id , nil
54
55
default_config :aws_secret_access_key , nil
55
- default_config :aws_ssh_key_id do |_driver |
56
- ENV [ "AWS_SSH_KEY_ID" ]
57
- end
56
+ default_config :aws_ssh_key_id , ENV [ "AWS_SSH_KEY_ID" ]
58
57
default_config :image_id do |driver |
59
58
driver . default_ami
60
59
end
@@ -230,14 +229,18 @@ def default_ami
230
229
private
231
230
232
231
def ec2
233
- @ec2 ||= Client :: Ec2Client . new (
232
+ @ec2 ||= Client . new (
234
233
config [ :region ] ,
235
234
config [ :shared_credentials_profile ] ,
236
235
config [ :aws_access_key_id ] ,
237
236
config [ :aws_secret_access_key ]
238
237
)
239
238
end
240
239
240
+ def instance_generator
241
+ @instance_generator ||= InstanceGenerator . new ( config , ec2 )
242
+ end
243
+
241
244
# This copies transport config from the current config object into the
242
245
# state. This relies on logic in the transport that merges the transport
243
246
# config with the current state object, so its a bad coupling. But we
@@ -267,7 +270,7 @@ def copy_deprecated_configs(state)
267
270
# Fog AWS helper for creating the instance
268
271
def submit_server
269
272
debug ( "Creating EC2 Instance.." )
270
- instance_data = ec2_instance_data
273
+ instance_data = instance_generator . ec2_instance_data
271
274
instance_data [ :min_count ] = 1
272
275
instance_data [ :max_count ] = 1
273
276
ec2 . create_instance ( instance_data )
@@ -277,7 +280,7 @@ def submit_spot(state) # rubocop:disable Metrics/AbcSize
277
280
debug ( "Creating EC2 Spot Instance.." )
278
281
request_data = { }
279
282
request_data [ :spot_price ] = config [ :price ] . to_s
280
- request_data [ :launch_specification ] = ec2_instance_data
283
+ request_data [ :launch_specification ] = instance_generator . ec2_instance_data
281
284
282
285
response = ec2 . client . request_spot_instances ( request_data )
283
286
spot_request_id = response [ :spot_instance_requests ] [ 0 ] [ :spot_instance_request_id ]
@@ -302,35 +305,7 @@ def tag_server(server)
302
305
server . create_tags ( { :tags => tags } )
303
306
end
304
307
305
- # Transform the provided config into the hash to send to AWS. Some fields
306
- # can be passed in null, others need to be ommitted if they are null
307
- def ec2_instance_data
308
- i = {
309
- :placement => {
310
- :availability_zone => config [ :availability_zone ] ,
311
- } ,
312
- :instance_type => config [ :instance_type ] ,
313
- :ebs_optimized => config [ :ebs_optimized ] ,
314
- :image_id => config [ :image_id ] ,
315
- :key_name => config [ :aws_ssh_key_id ] ,
316
- :subnet_id => config [ :subnet_id ] ,
317
- :private_ip_address => config [ :private_ip_address ] ,
318
- }
319
- i [ :block_device_mappings ] = block_device_mappings unless block_device_mappings . empty?
320
- i [ :security_group_ids ] = config [ :security_group_ids ] if config [ :security_group_ids ]
321
- i [ :user_data ] = prepared_user_data if prepared_user_data
322
- if config [ :iam_instance_profile ]
323
- i [ :iam_instance_profile ] = { :name => config [ :iam_profile_name ] }
324
- end
325
- if config . fetch ( :associate_public_ip_address , nil ) != nil
326
- i [ :network_interfaces ] =
327
- [ {
328
- :device_index => 0 ,
329
- :associate_public_ip_address => config [ :associate_public_ip_address ]
330
- } ]
331
- end
332
- i
333
- end
308
+
334
309
335
310
def amis
336
311
@amis ||= begin
@@ -371,73 +346,6 @@ def hostname(server, interface_type = nil)
371
346
end
372
347
end
373
348
374
- # Transforms the provided config into the appropriate hash for creating a BDM
375
- # in AWS
376
- def block_device_mappings # rubocop:disable all
377
- return @bdms if @bdms
378
- bdms = config [ :block_device_mappings ] || [ ]
379
- if bdms . nil? || bdms . empty?
380
- if config [ :ebs_volume_size ] || config . fetch ( :ebs_delete_on_termination , nil ) ||
381
- config [ :ebs_device_name ] || config [ :ebs_volume_type ]
382
- # If the user didn't supply block_device_mappings but did supply
383
- # the old configs, copy them into the block_device_mappings array correctly
384
- bdms << {
385
- :ebs_volume_size => config [ :ebs_volume_size ] || 8 ,
386
- :ebs_delete_on_termination => config . fetch ( :ebs_delete_on_termination , true ) ,
387
- :ebs_device_name => config [ :ebs_device_name ] || "/dev/sda1" ,
388
- :ebs_volume_type => config [ :ebs_volume_type ] || "standard"
389
- }
390
- end
391
- end
392
-
393
- # Convert the provided keys to what AWS expects
394
- bdms = bdms . map do |bdm |
395
- b = {
396
- :ebs => {
397
- :volume_size => bdm [ :ebs_volume_size ] ,
398
- :volume_type => bdm [ :ebs_volume_type ] ,
399
- :delete_on_termination => bdm [ :ebs_delete_on_termination ]
400
- } ,
401
- :device_name => bdm [ :ebs_device_name ]
402
- }
403
- b [ :ebs ] [ :snapshot_id ] = bdm [ :ebs_snapshot_id ] if bdm [ :ebs_snapshot_id ]
404
- b [ :virtual_name ] = bdm [ :ebs_virtual_name ] if bdm [ :ebs_virtual_name ]
405
- b
406
- end
407
-
408
- debug_if_root_device ( bdms )
409
-
410
- @bdms = bdms
411
- end
412
-
413
- # If the provided bdms match the root device in the AMI, emit log that
414
- # states this
415
- def debug_if_root_device ( bdms )
416
- image_id = config [ :image_id ]
417
- image = ec2 . resource . image ( image_id )
418
- begin
419
- root_device_name = image . root_device_name
420
- rescue ::Aws ::EC2 ::Errors ::InvalidAMIIDNotFound
421
- # Not raising here because AWS will give a more meaningful message
422
- # when we try to create the instance
423
- return
424
- end
425
- bdms . find { |bdm |
426
- if bdm [ :device_name ] == root_device_name
427
- info ( "Overriding root device [#{ root_device_name } ] from image [#{ image_id } ]" )
428
- end
429
- }
430
- end
431
-
432
- def prepared_user_data
433
- # If user_data is a file reference, lets read it as such
434
- @user_data ||= unless config [ :user_data ] . nil?
435
- if File . file? ( config [ :user_data ] )
436
- config [ :user_data ] = File . read ( config [ :user_data ] )
437
- end
438
- end
439
- end
440
-
441
349
def create_ec2_json ( state )
442
350
instance . transport . connection ( state ) . execute (
443
351
"sudo mkdir -p /etc/chef/ohai/hints;sudo touch /etc/chef/ohai/hints/ec2.json"
0 commit comments