class AwsXRegionSync::Ec2AmiSync
Public Instance Methods
sync()
click to toggle source
# File lib/aws_xregion_sync/ec2_ami_sync.rb, line 4 def sync setup = pre_sync_setup sync_ec2_image_to_region setup[:destination_region], setup[:source_region], setup[:image] end
sync_ec2_image_to_region(destination_region, source_region, image)
click to toggle source
# File lib/aws_xregion_sync/ec2_ami_sync.rb, line 15 def sync_ec2_image_to_region destination_region, source_region, image destination_ami_id = nil if needs_sync?(destination_region, image) # At this point, we know the sync has not happened (or the destination image has been removed) # Initiate the image copy command (we're not using client_token to ensure indempotency since we're already just using the Sync- identifier tag to ensure we're not # copying the image multiple times to the destination region) results = destination_region.client.copy_image source_region: source_region.name, source_image_id: image.id, name: image.name destination_ami_id = results[:image_id] tag = create_sync_tag destination_region.name, destination_ami_id # We want to log the destination AMI-ID and the time we started the sync back to the source image image.tags[tag[:key]] = tag[:value] end destination_ami_id end
sync_required?()
click to toggle source
# File lib/aws_xregion_sync/ec2_ami_sync.rb, line 10 def sync_required? setup = pre_sync_setup needs_sync? setup[:destination_region], setup[:image] end
Private Instance Methods
ec2_client(aws_client_config)
click to toggle source
# File lib/aws_xregion_sync/ec2_ami_sync.rb, line 70 def ec2_client aws_client_config AWS::EC2.new(aws_client_config) end
find_destination_ami(tags, region)
click to toggle source
# File lib/aws_xregion_sync/ec2_ami_sync.rb, line 107 def find_destination_ami tags, region # We're expecting the tags to be like [["Key1", "Value1"], ["Key2", "Value2"]] # which is how to_a on a TagCollection object retutns the values key = create_sync_tag(region, nil)[:key] tag_value = parse_sync_tag_value(tags.detect(->(){[]}) {|tag| tag[0] == key}[1]) tag_value[:resource_identifier] end
image_exists(destination_region, ami_id)
click to toggle source
# File lib/aws_xregion_sync/ec2_ami_sync.rb, line 74 def image_exists destination_region, ami_id image = ami_id ? destination_region.images[ami_id] : nil !image.nil? && image.exists? rescue false end
needs_sync?(destination_region, image)
click to toggle source
# File lib/aws_xregion_sync/ec2_ami_sync.rb, line 62 def needs_sync? destination_region, image source_tags = image.tags.to_a # Look for a tag indicating the image has been synced to the destination region dest_ami_id = find_destination_ami source_tags, destination_region.name !image_exists(destination_region, dest_ami_id) end
parse_filters(sync_identifier, config_filters)
click to toggle source
# File lib/aws_xregion_sync/ec2_ami_sync.rb, line 81 def parse_filters sync_identifier, config_filters filters = [] filters << ["tag:#{sync_tag_indicator}-Identifier", sync_identifier] if sync_identifier && sync_identifier.length > 0 if config_filters && config_filters.length > 0 filters = filters + parse_config_filters(config_filters) end filters end
pre_sync_setup()
click to toggle source
# File lib/aws_xregion_sync/ec2_ami_sync.rb, line 36 def pre_sync_setup config = {'owner_id'=>'self'}.merge self.config filters = parse_filters config['sync_identifier'], config['filters'] ec2 = ec2_client aws_config source_region = validate_region ec2, config['source_region'] destination_region = validate_region ec2, config['destination_region'] # Assemble the filter criteria that should help us to find the specific image we're after ami_query = source_region.images ami_query = ami_query.with_owner(config['owner_id']) filters.each {|f| ami_query = ami_query.filter(f[0], f[1])} images = ami_query.to_a if images.size > 1 raise AwsXRegionSyncConfigError, "More than one EC2 Image was found with the filter settings for identifier '#{self.sync_name}': #{images.collect{|i| i.id}.join(", ")}." elsif images.size == 0 raise AwsXRegionSyncConfigError, "No EC2 Images were found using the filter settings for identifier '#{self.sync_name}'." end {destination_region: destination_region, source_region: source_region, image: images[0]} end
validate_region(ec2, region_id)
click to toggle source
# File lib/aws_xregion_sync/ec2_ami_sync.rb, line 90 def validate_region ec2, region_id region = ec2.regions[region_id] # AWS does an actual HTTP query to establish if the region exists, and then doesn't catch any socket errors # if it fails. Since the aws gem directly uses the value you pass for the region as part of the http host it # calls the gem ends up raising a naming exception when you used a bad region name instead of just returning # false that the region doesn't exist exists = false begin exists = region.exists? rescue end raise AwsXRegionSyncConfigError, "Invalid region code of '#{region_id}' found for identifier '#{self.sync_name}'. It either does not exist or the given credentials cannot access it." unless exists region end