Permalink
Browse files

Merge new 3.0 into current branch

  • Loading branch information...
2 parents 6e63ad8 + 5ff01dd commit acc080b9b96a93fdfbf8e3a9023cc595fe41a7b4 @konstantin-dzreev konstantin-dzreev committed Nov 15, 2011
View
@@ -1,3 +1,5 @@
+source "http://rubygems.org"
+
gem 'right_http_connection', '1.2.5', :git => 'git@github.com:rightscale/right_http_connection.git'
gem 'libxml-ruby', '~> 0.5.2'
View
@@ -5,6 +5,7 @@ GIT
right_http_connection (1.2.5)
GEM
+ remote: http://rubygems.org/
specs:
libxml-ruby (0.5.2.0)
rake (0.8.7)
View
@@ -304,14 +304,26 @@ the source key.
- this gem requires right_http_connection 0bc3343232133bdb38c237d8285525d74495d3f5 or later
- "Raise On Timeout On Action" feature added to avoid duplicate resources creation if a timeout error occures and a retry is performed
-=== next
+=== 3.0.0
Release Notes:
- - Fixed:
+ - Fixed/Added:
+ - ClientToken (launch_instances, run_instances) is not used for Eucalyptus clouds
+ - VPC2, stage1. Next methods were updated:
+ - associate_address, modify_security_group, create_security_group, create_vpc, delete_security_group,
+ describe_addresses, describe_images, describe_instance_attribute, describe_regions, describe_reserved_instances_offerings,
+ describe_security_groups, describe_snapshots, describe_spot_instance_requests, describe_spot_price_history,
+ describe_vpcs, disassociate_address, modify_image_attribute, modify_snapshot_attribute, release_address,
+ request_spot_instances, stop_instances
- EC2: ClientToken (launch_instances, run_instances) is not used for Eucalyptus clouds
- RDS:
- RDS: API 2011-04-01
- Make :instance_class param more consistent: :db_instance_class --> :instance_class
- Issue 53: regression in latest master version of right_rds_interface
- Issue 73: Can't get list of instances with RdsInterface
- EBS: Issue 54: regression in right_ec2_ebs.rb
- - Add the port number with server name in the v2 signature string if it is not the RFC standard number (author: unakatsuo).
+ - Add the port number with server name in the v2 signature string if it is not the RFC standard number (author: unakatsuo).
+ - EMR (Elastic Map Reduce) support
+ - SNS (Simple Notification Service) support
+ - SDB: ConsistentRead support
+ - bunch of micro bugs
+
View
@@ -13,6 +13,7 @@ lib/ec2/right_ec2_spot_instances.rb
lib/ec2/right_ec2_ebs.rb
lib/ec2/right_ec2_reserved_instances.rb
lib/ec2/right_ec2_vpc.rb
+lib/ec2/right_ec2_vpc2.rb
lib/ec2/right_ec2_monitoring.rb
lib/ec2/right_ec2_placement_groups.rb
lib/ec2/right_ec2_windows_mobility.rb
View
@@ -2,7 +2,6 @@
require 'rubygems'
require "rake/testtask"
-require 'rcov/rcovtask'
require 'rake/gempackagetask'
require 'rake/clean'
$: << File.dirname(__FILE__)
@@ -13,7 +12,19 @@ begin
rescue LoadError => e
STDERR.puts("Bundler is not available, some rake tasks will not be defined: #{e.message}")
else
- Bundler::GemHelper.install_tasks
+ Bundler::GemHelper.install_tasks :name => 'right_aws'
+end
+
+begin
+ require 'rcov/rcovtask'
+rescue LoadError => e
+ STDERR.puts("RCov is not available, some rake tasks will not be defined: #{e.message}")
+else
+ desc "Analyze code coverage of the unit tests."
+ Rcov::RcovTask.new do |t|
+ t.test_files = FileList[testglobs]
+ #t.verbose = true # uncomment to see the executed command
+ end
end
# == Gem == #
@@ -28,12 +39,6 @@ directory gemtask.package_dir
CLEAN.include(gemtask.package_dir)
-desc "Analyze code coverage of the unit tests."
-Rcov::RcovTask.new do |t|
- t.test_files = FileList[testglobs]
- #t.verbose = true # uncomment to see the executed command
-end
-
desc "Test just the SQS interface"
task :testsqs do
require 'test/test_credentials'
@@ -101,4 +106,25 @@ task :testrds do
require 'test/rds/test_right_rds.rb'
end
+desc "Test just the SNS interface"
+task :testsns do
+ require 'test/test_credentials'
+ TestCredentials.get_credentials
+ require 'test/sns/test_right_sns.rb'
+end
+
+desc "Test Route 53 interface"
+task :testroute53 do
+ require 'test/test_credentials'
+ TestCredentials.get_credentials
+ require 'test/route_53/test_right_route_53'
+end
+
+desc "Test ELB interface"
+task :testelb do
+ require 'test/test_credentials'
+ TestCredentials.get_credentials
+ require 'test/elb/test_right_elb'
+end
+
# vim: syntax=Ruby
@@ -422,15 +422,15 @@ def get_connection(request) # :nodoc:
# ACF, AMS, EC2, LBS and SDB uses this guy
# SQS and S3 use their own methods
- def generate_request_impl(verb, action, options={}) #:nodoc:
+ def generate_request_impl(verb, action, options={}, custom_options={}) #:nodoc:
# Form a valid http verb: 'GET' or 'POST' (all the other are not supported now)
http_verb = verb.to_s.upcase
# remove empty keys from request options
options.delete_if { |key, value| value.nil? }
# prepare service data
service_hash = {"Action" => action,
"AWSAccessKeyId" => @aws_access_key_id,
- "Version" => @params[:api_version] }
+ "Version" => custom_options[:api_version] || @params[:api_version] }
service_hash.merge!(options)
# Sign request options
service_params = signed_service_params(@aws_secret_access_key, service_hash, http_verb, @params[:host_to_sign], @params[:service])
@@ -620,10 +620,11 @@ def incrementally_list_items(action, parser_class, params={}, &block) # :nodoc:
# "Filter.2.Value.2"=>"bb"}
def amazonize_list(masks, list, options={}) #:nodoc:
groups = {}
- Array(list).each_with_index do |list_item, i|
+ list_idx = options[:index] || 1
+ Array(list).each do |list_item|
Array(masks).each_with_index do |mask, mask_idx|
key = mask[/\?/] ? mask.dup : mask.dup + '.?'
- key.sub!('?', (i+1).to_s)
+ key.sub!('?', list_idx.to_s)
value = Array(list_item)[mask_idx]
if value.is_a?(Array)
groups.merge!(amazonize_list(key, value, options))
@@ -639,6 +640,7 @@ def amazonize_list(masks, list, options={}) #:nodoc:
groups[key] = value
end
end
+ list_idx += 1
end
groups
end
@@ -668,6 +670,162 @@ def amazonize_block_device_mappings(block_device_mappings, key = 'BlockDeviceMap
result
end
+ # Build API request keys set.
+ #
+ # Options is a hash, expectations is a set of keys [and rules] how to represent options.
+ # Mappings is an Array (may include hashes) or a Hash.
+ #
+ # Example:
+ #
+ # options = { :valid_from => Time.now - 10,
+ # :instance_count => 3,
+ # :image_id => 'ami-08f41161',
+ # :spot_price => 0.059,
+ # :instance_type => 'c1.medium',
+ # :instance_count => 1,
+ # :key_name => 'tim',
+ # :availability_zone => 'us-east-1a',
+ # :monitoring_enabled => true,
+ # :launch_group => 'lg1',
+ # :availability_zone_group => 'azg1',
+ # :groups => ['a', 'b', 'c'],
+ # :group_ids => 'sg-1',
+ # :user_data => 'konstantin',
+ # :block_device_mappings => [ { :device_name => '/dev/sdk',
+ # :ebs_snapshot_id => 'snap-145cbc7d',
+ # :ebs_delete_on_termination => true,
+ # :ebs_volume_size => 3,
+ # :virtual_name => 'ephemeral2' }]}
+ # mappings = { :spot_price,
+ # :availability_zone_group,
+ # :launch_group,
+ # :type,
+ # :instance_count,
+ # :image_id => 'LaunchSpecification.ImageId',
+ # :instance_type => 'LaunchSpecification.InstanceType',
+ # :key_name => 'LaunchSpecification.KeyName',
+ # :addressing_type => 'LaunchSpecification.AddressingType',
+ # :kernel_id => 'LaunchSpecification.KernelId',
+ # :ramdisk_id => 'LaunchSpecification.RamdiskId',
+ # :subnet_id => 'LaunchSpecification.SubnetId',
+ # :availability_zone => 'LaunchSpecification.Placement.AvailabilityZone',
+ # :monitoring_enabled => 'LaunchSpecification.Monitoring.Enabled',
+ # :valid_from => { :value => Proc.new { !options[:valid_from].right_blank? && AwsUtils::utc_iso8601(options[:valid_from]) }},
+ # :valid_until => { :value => Proc.new { !options[:valid_until].right_blank? && AwsUtils::utc_iso8601(options[:valid_until]) }},
+ # :user_data => { :name => 'LaunchSpecification.UserData',
+ # :value => Proc.new { !options[:user_data].right_blank? && Base64.encode64(options[:user_data]).delete("\n") }},
+ # :groups => { :amazonize_list => 'LaunchSpecification.SecurityGroup'},
+ # :group_ids => { :amazonize_list => 'LaunchSpecification.SecurityGroupId'},
+ # :block_device_mappings => { :amazonize_bdm => 'LaunchSpecification.BlockDeviceMapping'})
+ #
+ # map_api_keys_and_values( options, mappings) #=>
+ # {"LaunchSpecification.BlockDeviceMapping.1.Ebs.DeleteOnTermination" => true,
+ # "LaunchSpecification.BlockDeviceMapping.1.VirtualName" => "ephemeral2",
+ # "LaunchSpecification.BlockDeviceMapping.1.Ebs.VolumeSize" => 3,
+ # "LaunchSpecification.BlockDeviceMapping.1.Ebs.SnapshotId" => "snap-145cbc7d",
+ # "LaunchSpecification.BlockDeviceMapping.1.DeviceName" => "/dev/sdk",
+ # "LaunchSpecification.SecurityGroupId.1" => "sg-1",
+ # "LaunchSpecification.InstanceType" => "c1.medium",
+ # "LaunchSpecification.KeyName" => "tim",
+ # "LaunchSpecification.ImageId" => "ami-08f41161",
+ # "LaunchSpecification.SecurityGroup.1" => "a",
+ # "LaunchSpecification.SecurityGroup.2" => "b",
+ # "LaunchSpecification.SecurityGroup.3" => "c",
+ # "LaunchSpecification.Placement.AvailabilityZone" => "us-east-1a",
+ # "LaunchSpecification.Monitoring.Enabled" => true,
+ # "LaunchGroup" => "lg1",
+ # "InstanceCount" => 1,
+ # "SpotPrice" => 0.059,
+ # "AvailabilityZoneGroup" => "azg1",
+ # "ValidFrom" => "2011-06-30T08:06:30.000Z",
+ # "LaunchSpecification.UserData" => "a29uc3RhbnRpbg=="}
+ #
+ def map_api_keys_and_values(options, *mappings) # :nodoc:
+ result = {}
+ vars = {}
+ # Fix inputs and make them all to be hashes
+ mappings.flatten.each do |mapping|
+ unless mapping.is_a?(Hash)
+ # mapping is just a :key_name
+ mapping = { mapping => { :name => mapping.to_s.right_camelize, :value => options[mapping] }}
+ else
+ mapping.each do |local_key, api_opts|
+ unless api_opts.is_a?(Hash)
+ # mapping is a { :key_name => 'ApiKeyName' }
+ mapping[local_key] = { :name => api_opts.to_s, :value => options[local_key]}
+ else
+ # mapping is a { :key_name => { :name => 'ApiKeyName', :value => 'Value', ... etc} }
+ api_opts[:name] = local_key.to_s.right_camelize if (api_opts.keys & [:name, :amazonize_list, :amazonize_bdm]).right_blank?
+ api_opts[:value] = options[local_key] unless api_opts.has_key?(:value)
+ end
+ end
+ end
+ vars.merge! mapping
+ end
+ # Build API keys set
+ # vars now is a Hash:
+ # { :key1 => { :name => 'ApiKey1', :value => 'BlahBlah'},
+ # :key2 => { :amazonize_list => 'ApiKey2.?', :value => [1, ...] },
+ # :key3 => { :amazonize_bdm => 'BDM', :value => [{..}, ...] }, ... }
+ #
+ vars.each do |local_key, api_opts|
+ if api_opts[:amazonize_list]
+ result.merge!(amazonize_list( api_opts[:amazonize_list], api_opts[:value] )) unless api_opts[:value].right_blank?
+ elsif api_opts[:amazonize_bdm]
+ result.merge!(amazonize_block_device_mappings( api_opts[:value], api_opts[:amazonize_bdm] )) unless api_opts[:value].right_blank?
+ else
+ api_key = api_opts[:name]
+ value = api_opts[:value]
+ value = value.call if value.is_a?(Proc)
+ next if value.right_blank?
+ result[api_key] = value
+ end
+ end
+ #
+ result
+ end
+
+ # Transform a hash of parameters into a hash suitable for sending
+ # to Amazon using a key mapping.
+ #
+ # amazonize_hash_with_key_mapping('Group.Filter',
+ # {:some_param => 'SomeParam'},
+ # {:some_param => 'value'}) #=> {'Group.Filter.SomeParam' => 'value'}
+ #
+ def amazonize_hash_with_key_mapping(key, mapping, hash, options={})
+ result = {}
+ unless hash.right_blank?
+ mapping.each do |local_name, remote_name|
+ value = hash[local_name]
+ next if value.nil?
+ result["#{key}.#{remote_name}"] = value
+ end
+ end
+ result
+ end
+
+ # Transform a list of hashes of parameters into a hash suitable for sending
+ # to Amazon using a key mapping.
+ #
+ # amazonize_list_with_key_mapping('Group.Filter',
+ # [{:some_param => 'SomeParam'}, {:some_param => 'SomeParam'}],
+ # {:some_param => 'value'}) #=>
+ # {'Group.Filter.1.SomeParam' => 'value',
+ # 'Group.Filter.2.SomeParam' => 'value'}
+ #
+ def amazonize_list_with_key_mapping(key, mapping, list, options={})
+ result = {}
+ unless list.right_blank?
+ list.each_with_index do |item, index|
+ mapping.each do |local_name, remote_name|
+ value = item[local_name]
+ next if value.nil?
+ result["#{key}.#{index+1}.#{remote_name}"] = value
+ end
+ end
+ end
+ end
+
# Execute a block of code with custom set of settings for right_http_connection.
# Accepts next options (see Rightscale::HttpConnection for explanation):
# :raise_on_timeout
@@ -1,7 +1,7 @@
module RightAws #:nodoc:
module VERSION #:nodoc:
- MAJOR = 2 unless defined?(MAJOR)
- MINOR = 1 unless defined?(MINOR)
+ MAJOR = 3 unless defined?(MAJOR)
+ MINOR = 0 unless defined?(MINOR)
TINY = 0 unless defined?(TINY)
STRING = [MAJOR, MINOR, TINY].join('.') unless defined?(STRING)
Oops, something went wrong. Retry.

0 comments on commit acc080b

Please sign in to comment.