Class: KernelMappings

Inherits:
Object
  • Object
show all
Defined in:
lib/ec2/amitools/mapids.rb

Defined Under Namespace

Classes: MappingError

Constant Summary collapse

ENDPOINT =
"http://ec2.amazonaws.com"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(akid, secretkey, source_images, target_region, endpoint = nil) ⇒ KernelMappings

—————————————————————————-#



105
106
107
108
109
110
111
112
# File 'lib/ec2/amitools/mapids.rb', line 105

def initialize(akid, secretkey, source_images, target_region, endpoint=nil)
  @target_region = target_region
  @source_images = source_images
  create_ec2_connections(akid, secretkey, endpoint)
  unless @ec2conn.has_key?(target_region)
    raise MappingError.new("Invalid region: #{target_region}")
  end
end

Instance Attribute Details

#source_image_infoObject (readonly)

Returns the value of attribute source_image_info.



18
19
20
# File 'lib/ec2/amitools/mapids.rb', line 18

def source_image_info
  @source_image_info
end

#target_image_infoObject (readonly)

Returns the value of attribute target_image_info.



19
20
21
# File 'lib/ec2/amitools/mapids.rb', line 19

def target_image_info
  @target_image_info
end

Instance Method Details

#[](identifier) ⇒ Object

—————————————————————————-#

Raises:



136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/ec2/amitools/mapids.rb', line 136

def [](identifier)
  if @target_images_info.nil?
    get_source_images_info()
    get_target_candidates()
  end
  source_info = @source_images_info.find { |ii| ii['imageId'] == identifier }
  raise MappingError.new("'#{identifier}' not found.") if source_info.nil?
  source_match = matchable_image(source_info)
  target_info = @target_images_info.find { |ii| source_match == matchable_image(ii) }
  raise MappingError.new("Mapping for '#{identifier}' not found.") if target_info.nil?
  target_info['imageId']
end

#add_endpoint_from_env(endpoints) ⇒ Object

—————————————————————————-#



29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/ec2/amitools/mapids.rb', line 29

def add_endpoint_from_env(endpoints)
  str = ENV['AMITOOLS_EC2_REGION_ENDPOINT']
  if not str
    return
  end

  components = str.split('@').collect{|s| s.strip()}
  if components.size != 2
    return
  end
  
  endpoints[components[0]] = components[1]
end

#create_ec2_connections(akid, secretkey, endpoint = nil) ⇒ Object

—————————————————————————-#



60
61
62
63
64
65
66
# File 'lib/ec2/amitools/mapids.rb', line 60

def create_ec2_connections(akid, secretkey, endpoint=nil)
  @ec2conn = {}
  @endpoints = get_endpoints(akid, secretkey, endpoint)
  @endpoints.each do |region, endpoint|
    @ec2conn[region] = get_ec2_client(akid, secretkey, endpoint)
  end
end

#find_missing_targets(targets) ⇒ Object

—————————————————————————-#



125
126
127
128
129
130
131
132
# File 'lib/ec2/amitools/mapids.rb', line 125

def find_missing_targets(targets)
  @target_images_info.each { |ii| targets.delete(ii['imageId']) } unless @target_images_info.nil?
  return nil if targets.empty?
  lookups = parse_imageset(@ec2conn[@target_region].describe_images(targets))
  lookups.each { |ii| targets.delete(ii['imageId']) }
  return nil if targets.empty?
  targets
end

#get_ec2_client(akid, secretkey, endpoint = nil) ⇒ Object

—————————————————————————-#



23
24
25
# File 'lib/ec2/amitools/mapids.rb', line 23

def get_ec2_client(akid, secretkey, endpoint=nil)
  EC2::EC2Client.new(akid, secretkey, endpoint)
end

#get_endpoints(akid, secretkey, endpoint = nil) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/ec2/amitools/mapids.rb', line 43

def get_endpoints(akid, secretkey, endpoint=nil)
  endpoint ||= ENDPOINT
  endpoints = {}
  ec2conn = get_ec2_client(akid, secretkey, endpoint)
  resp_doc = ec2conn.describe_regions()
  REXML::XPath.each(resp_doc.root, '/DescribeRegionsResponse/regionInfo/item') do |region|
    region_name = REXML::XPath.first(region, 'regionName').text
    region_url = REXML::XPath.first(region, 'regionEndpoint').text
    region_url = 'https://'+region_url unless region_url =~ %r{^https?://}
    endpoints[region_name] = region_url
  end
  add_endpoint_from_env(endpoints)
  endpoints
end

#get_source_images_infoObject

—————————————————————————-#



70
71
72
73
74
75
76
77
78
79
# File 'lib/ec2/amitools/mapids.rb', line 70

def get_source_images_info()
  @ec2conn.each do |region, connection|
    $stderr.puts "Getting source data from #{region} #{@source_images.inspect}..." if @verbose
    resp_doc = connection.describe_images(@source_images)
    @source_images_info = parse_imageset(resp_doc)
    $stderr.puts "Found #{@source_images_info.size} images in #{region}." if @verbose
    # We assume all the images we're trying to map are in the same region.
    return if @source_images_info.size > 0
  end
end

#get_target_candidatesObject

—————————————————————————-#



83
84
85
86
87
88
89
# File 'lib/ec2/amitools/mapids.rb', line 83

def get_target_candidates()
  owners = @source_images_info.map { |ii| ii['imageOwnerId'] }
  $stderr.puts "Getting target data from #{region} #{owners.inspect}..." if @verbose
  resp_doc = @ec2conn[@target_region].describe_images([], :ownerIds => owners)
  @target_images_info = parse_imageset(resp_doc)
  $stderr.puts "Found #{@target_images_info.size} images in #{region}." if @verbose
end

#matchable_image(image) ⇒ Object

—————————————————————————-#



116
117
118
119
120
121
# File 'lib/ec2/amitools/mapids.rb', line 116

def matchable_image(image)
  summary = {}
  ['imageOwnerId', 'imageType'].each { |key| summary[key] = image[key] }
  summary[:s3key] = image['imageLocation'].sub(%r{^/*[^/]+/},'')
  summary
end

#parse_imageset(resp_doc) ⇒ Object

—————————————————————————-#



93
94
95
96
97
98
99
100
101
# File 'lib/ec2/amitools/mapids.rb', line 93

def parse_imageset(resp_doc)
  images_info = []
  resp_doc.each_element('DescribeImagesResponse/imagesSet/item') do |image|
    image_data = {}
    image.each_element() { |elem| image_data[elem.name] = elem.text }
    images_info << image_data
  end
  images_info
end