lib/cloud_providers/ec2/ec2.rb in poolparty-1.4.7 vs lib/cloud_providers/ec2/ec2.rb in poolparty-1.4.8
- old
+ new
@@ -60,16 +60,16 @@
# Load credentials from file
def self.load_keys_from_credential_file(filename=default_credential_file, caching=true)
return {:access_key => @access_key, :secret_access_key => @secret_access_key} if @access_key and @secret_access_key
return {} if filename.nil? or not File.exists?(filename)
puts("Reading keys from file: #{filename}")
- File.open(filename).each_line {|line|
- if line =~ /AWSAccessKeyId=([a-zA-Z0-9]+)$/
- @access_key=$1.chomp
- elsif line =~ /AWSSecretKey=([^ ]+)$/
- @secret_access_key=$1.chomp
- end
+ File.open(filename).each_line { |line|
+ if line =~ /AWSAccessKeyId=([a-zA-Z0-9]+)$/
+ @access_key=$1.chomp
+ elsif line =~ /AWSSecretKey=([^ ]+)$/
+ @secret_access_key=$1.chomp
+ end
}
return {:access_key => @access_key, :secret_access_key => @secret_access_key}
end
@@ -90,12 +90,11 @@
:max_count => 1,
:user_data => '',
:addressing_type => nil,
:kernel_id => nil,
:ramdisk_id => nil,
- :block_device_mappings => nil,
- :ebs_volumes => [] # The volume id of an ebs volume # TODO: ensure this is consistent with :block_device_mappings
+ :block_device_mapping => [{}]
)
# Called when the create command is called on the cloud
def create!
[:security_groups, :load_balancers, :rds_instances].each do |type|
@@ -172,10 +171,12 @@
accessible_count == running_nodes.size
end
end
assign_elastic_ips
+ puts "Attaching EBS volumes"
+ assign_ebs_volumes # Assign EBS volumes
end
def teardown
puts "------ Tearing down and cleaning up #{cloud.name} cloud"
unless autoscalers.empty?
@@ -192,11 +193,12 @@
:security_groups => security_groups,
:user_data => decoded_user_data,
:instance_type => instance_type,
:availability_zone => availability_zones.first,
:base64_encoded => true,
- :cloud => cloud
+ :cloud => cloud,
+ :block_device_mapping => block_device_mapping
})
progress_bar_until("Waiting for node to launch...") do
wait_for_node(e)
end
all_nodes.detect {|n| n.instance_id == e.instance_id }
@@ -281,12 +283,12 @@
end
# Describe instances
# Describe the instances that are available on this cloud
# @params id (optional) if present, details about the instance
- # with the id given will be returned
- # if not given, details for all instances will be returned
+ # with the id given will be returned
+ # if not given, details for all instances will be returned
def describe_instances(id=nil)
begin
@describe_instances = ec2.describe_instances.reservationSet.item.map do |r|
r.instancesSet.item.map do |i|
inst_options = i.merge(r.merge(:cloud => cloud)).merge(cloud.cloud_provider.dsl_options)
@@ -301,10 +303,14 @@
end
end
# Extras!
+ def block_device_mapping(o=[], given_name=cloud.proper_name )
+ @mappings ||= o
+ end
+
def load_balancer(given_name=cloud.proper_name, o={}, &block)
load_balancers << ElasticLoadBalancer.new(given_name, sub_opts.merge(o || {}), &block)
end
def autoscale(given_name=cloud.proper_name, o={}, &block)
autoscalers << ElasticAutoScaler.new(given_name, sub_opts.merge(o || {}), &block)
@@ -360,24 +366,61 @@
end
def elastic_ips
@elastic_ips ||= []
end
+ def ebs_volume_groups
+ @ebs_volume_groups ||= []
+ end
+
+ # dsl method for EBS volumes. E.G.:
+ # ebs_volumes do
+ # volumes "vol-001248ff", "vol-01ff4b85" # use existing volumes, not mandatory
+ # device "/dev/sdf"
+ # snapshot_id "snap-602030dd"
+ # size 200
+ # end
+ def ebs_volumes(name=nil, &block)
+ ebs_volume_groups << ElasticBlockStoreGroup.new(sub_opts,&block)
+ end
+
+ def assign_ebs_volumes
+ ebs_volume_groups.each{|ebs_volume_group| ebs_volume_group.attach(nodes)}
+ end
+
def rds_instances
@rds_instances ||= []
end
# Clear the cache
def reset!
@nodes = @describe_instances = nil
end
+ # Get existing volumes on EC2. filters is a hash of filters, either single valued or multivalued (value is an array of possible values).
+ # The function will return volumes matching *all* filters. A volume is a filter match if *any* one of the filter values equals the volume parameter value.
+ def list_ec2_volumes(filters=nil)
+ @volumes_on_ec2=ec2.describe_volumes.volumeSet.item unless @volumes_on_ec2
+ return @volumes_on_ec2 if filters.nil? # no filter to check, so return at once
+ @volumes_on_ec2.select{|vol| # select volumes for which no filter failed
+ not filters.map {|filter_key, filter_val|
+ filter_key=filter_key.to_s if filter_key.is_a?(Symbol) # filter_key may be given as a symbol
+ raise ArgumentError, "Filter key #{filter_key} is invalid" unless vol.has_key?(filter_key)
+ if filter_val.is_a?(Array) # Deal with multiple filter values
+ filter_val.map{|val| val.is_a?(String) ? val : val.to_s}.member?(vol[filter_key]) # make sure fiter_val array values are Strings before checking for match
+ else
+ filter_val.is_a?(String) ? filter_val : filter_val.to_s==vol[filter_key] # make sure fiter_val is a String before comparing
+ end
+ }.member?(false) # Check if a filter failed, the 'not' statement at the beginning of the map block negates this so 'select' will choose only when no filter failed
+ }.compact # remove nil results from volume set.
+ end
+
# Read credentials from credential_file if one exists
def credential_file(file=nil)
unless file.nil?
- dsl_options[:credential_file]=file
- dsl_options.merge((Ec2.load_keys_from_credential_file(file)))
+ dsl_options[:credential_file]=file
+ dsl_options.merge((Ec2.load_keys_from_credential_file(file)))
else
fetch(:credential_file)
end
end
@@ -408,10 +451,12 @@
require "#{File.dirname(__FILE__)}/ec2_instance"
require "#{File.dirname(__FILE__)}/helpers/ec2_helper"
%w( security_group
authorize
elastic_auto_scaler
+ elastic_block_device_mapping
elastic_block_store
+ elastic_block_store_group
elastic_load_balancer
elastic_ip
rds_instance
revoke).each do |lib|
require "#{File.dirname(__FILE__)}/helpers/#{lib}"