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}"