right_aws 2.1.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,7 +4,7 @@ Initial release.
4
4
  == 1.2.0 2007-09-12
5
5
 
6
6
  * r1718, todd, 2007-09-12 15:34:37
7
- * # 458, Extensive documentation review, rework, and expansion. Also added
7
+ * # 458, Extensive documentation review, rework, and expansion. Also added
8
8
  coverage analysis to the test suite using RCov.
9
9
 
10
10
  * r1690, todd, 2007-09-07 15:23:11
@@ -39,7 +39,7 @@ Initial release.
39
39
  * # 487, # 488, Consolidate a lot of code that was repeated in three places.
40
40
  Fix error handling path when using streaming GET interfaces with S3.
41
41
  Also add a stub for RightHttpConnection which allows more control over the
42
- unit tests. Expand the unit tests and coverage tests.
42
+ unit tests. Expand the unit tests and coverage tests.
43
43
 
44
44
  * r1755, todd, 2007-09-19 14:29:19
45
45
  * # 487, RDoc fixes after code consolidation
@@ -59,13 +59,13 @@ Initial release.
59
59
  * # 524, blocks added to ec2_describe_xxx to support aws_cache
60
60
 
61
61
  * r1924, konstantin, 2007-10-12 11:35:06
62
- * # 536, user_data bug fix
62
+ * # 536, user_data bug fix
63
63
 
64
64
  * r1929, tve, 2007-10-15 00:00:11
65
65
  * Fix libxml/rexml selection bug
66
66
 
67
67
  * r1938, konstantin, 2007-10-16 10:53:56
68
- * instance type support is set to default
68
+ * instance type support is set to default
69
69
 
70
70
  == 1.4.3 2007-10-25
71
71
 
@@ -82,11 +82,11 @@ Initial release.
82
82
  * r2001, konstantin, 2007-11-01 12:03:13 +0300
83
83
  * Fixed multiple permissions assignment on Grantee#grant/revoke
84
84
  * Fixed new grantee permissions set ingnore (Grantee#apply)
85
- * S3::Grantee#exists? method added
85
+ * S3::Grantee#exists? method added
86
86
 
87
87
  * r2109, konstantin, 2007-11-12 21:49:36 +0300
88
88
  * RightAwsBaseInterface: caching implemented.
89
- (The Ec2 functions are being cached: describe_images, describe_instances,
89
+ (The Ec2 functions are being cached: describe_images, describe_instances,
90
90
  describe_security_groups and describe_key_pairs)
91
91
 
92
92
  == 1.4.5 - 1.4.6
@@ -107,7 +107,7 @@ Initial release.
107
107
  == 1.5.0
108
108
  * r 2688, konstantin, 02-30-08 15:42:00 +0300
109
109
  * SDB support added.
110
- * RightAws::S3::bucket and RightAws::S3::Bucket.create methods behaviour
110
+ * RightAws::S3::bucket and RightAws::S3::Bucket.create methods behaviour
111
111
  changed: param +create+ is set to +false+ by default.
112
112
 
113
113
  == 1.6.0
@@ -151,7 +151,7 @@ Initial release.
151
151
  == 1.7.2
152
152
 
153
153
  Release Notes:
154
-
154
+
155
155
  RightAws includes some new features, including:
156
156
  - Support in RightAws::S3 and RightAws::S3Interface for S3 key copy, move, and rename
157
157
  - Support for signature version 0 request authentication to EC2, SQS, and SDB
@@ -165,7 +165,7 @@ Initial release.
165
165
  We now reset the seek pointer of the streaming IO object to its initial position.
166
166
  - Removal of an accidental dependency on ActiveSupport in RightAws::S3Interface.get_link().
167
167
  - Monkey-patch of the Ruby File class on Windows platforms to correct a problem in lstat.
168
- The lstat bug was causing failure of very large file uploads on Windows [ Contributed by Benjamin Allfree ]
168
+ The lstat bug was causing failure of very large file uploads on Windows [ Contributed by Benjamin Allfree ]
169
169
  - Fixed parsing of the ETag field for S3 objects
170
170
 
171
171
  == 1.7.3
@@ -174,7 +174,7 @@ Initial release.
174
174
 
175
175
  - Removed the 1.7.2 monkey-patch of the Ruby File class on Windows. This patch broke Rails 2.0.
176
176
  The patch is now included in the README for anyone to use at their own risk.
177
-
177
+
178
178
  == 1.8.0
179
179
 
180
180
  Release Notes:
@@ -186,7 +186,7 @@ Initial release.
186
186
 
187
187
  Bug fixes include correction of RightAws::S3 copy's failure to url-encode
188
188
  the source key.
189
-
189
+
190
190
  == 1.8.1
191
191
 
192
192
  Release Notes:
@@ -197,7 +197,7 @@ the source key.
197
197
  result sorting and attributes auto loading
198
198
  - RightAws::ActiveSdb::Base#find_all_by_ and find_by_ helpers improved to support
199
199
  :order, :auto_load, :limit and :next_token options
200
- - RightAws::SdbInterface#delete_attributes bug fixed
200
+ - RightAws::SdbInterface#delete_attributes bug fixed
201
201
  - SdbInterface allows specification of a string value to use for
202
202
  representing Ruby nil in SDB.
203
203
  - Sdb tests fixed and improved
@@ -215,7 +215,7 @@ the source key.
215
215
  - Ec::cancel_bundle_task
216
216
 
217
217
  - Full Amazon CloudFront support added with RightAws::AcfInterface
218
- - Bug fixes to S3Interface::store_object_and_verify and
218
+ - Bug fixes to S3Interface::store_object_and_verify and
219
219
  S3Interface::retrieve_object_and_verify (thanks to numerous user reports)
220
220
  - Updates to caching for Ec2::describe_images_by methods
221
221
  - Ec2 now has Ec2::last_request_id
@@ -228,7 +228,7 @@ the source key.
228
228
  - CloudFront: docs fixes
229
229
  - SDB: added: SQL-like query, select and query_with_attributes support
230
230
  - SDB: fixed no method error when searching for id that doesn't exist
231
-
231
+
232
232
  === 1.11.0
233
233
 
234
234
  Release Notes:
@@ -303,3 +303,27 @@ the source key.
303
303
  - SDB: uuid gem dependency
304
304
  - this gem requires right_http_connection 0bc3343232133bdb38c237d8285525d74495d3f5 or later
305
305
  - "Raise On Timeout On Action" feature added to avoid duplicate resources creation if a timeout error occures and a retry is performed
306
+
307
+ === 3.0.0
308
+ Release Notes:
309
+ - Fixed/Added:
310
+ - ClientToken (launch_instances, run_instances) is not used for Eucalyptus clouds
311
+ - VPC2, stage1. Next methods were updated:
312
+ - associate_address, modify_security_group, create_security_group, create_vpc, delete_security_group,
313
+ describe_addresses, describe_images, describe_instance_attribute, describe_regions, describe_reserved_instances_offerings,
314
+ describe_security_groups, describe_snapshots, describe_spot_instance_requests, describe_spot_price_history,
315
+ describe_vpcs, disassociate_address, modify_image_attribute, modify_snapshot_attribute, release_address,
316
+ request_spot_instances, stop_instances
317
+ - EC2: ClientToken (launch_instances, run_instances) is not used for Eucalyptus clouds
318
+ - RDS:
319
+ - RDS: API 2011-04-01
320
+ - Make :instance_class param more consistent: :db_instance_class --> :instance_class
321
+ - Issue 53: regression in latest master version of right_rds_interface
322
+ - Issue 73: Can't get list of instances with RdsInterface
323
+ - EBS: Issue 54: regression in right_ec2_ebs.rb
324
+ - Add the port number with server name in the v2 signature string if it is not the RFC standard number (author: unakatsuo).
325
+ - EMR (Elastic Map Reduce) support
326
+ - SNS (Simple Notification Service) support
327
+ - SDB: ConsistentRead support
328
+ - bunch of micro bugs
329
+
@@ -13,6 +13,7 @@ lib/ec2/right_ec2_spot_instances.rb
13
13
  lib/ec2/right_ec2_ebs.rb
14
14
  lib/ec2/right_ec2_reserved_instances.rb
15
15
  lib/ec2/right_ec2_vpc.rb
16
+ lib/ec2/right_ec2_vpc2.rb
16
17
  lib/ec2/right_ec2_monitoring.rb
17
18
  lib/ec2/right_ec2_placement_groups.rb
18
19
  lib/ec2/right_ec2_windows_mobility.rb
data/Rakefile CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  require 'rubygems'
4
4
  require "rake/testtask"
5
- require 'rcov/rcovtask'
6
5
  require 'rake/gempackagetask'
7
6
  require 'rake/clean'
8
7
  $: << File.dirname(__FILE__)
@@ -13,7 +12,19 @@ begin
13
12
  rescue LoadError => e
14
13
  STDERR.puts("Bundler is not available, some rake tasks will not be defined: #{e.message}")
15
14
  else
16
- Bundler::GemHelper.install_tasks
15
+ Bundler::GemHelper.install_tasks :name => 'right_aws'
16
+ end
17
+
18
+ begin
19
+ require 'rcov/rcovtask'
20
+ rescue LoadError => e
21
+ STDERR.puts("RCov is not available, some rake tasks will not be defined: #{e.message}")
22
+ else
23
+ desc "Analyze code coverage of the unit tests."
24
+ Rcov::RcovTask.new do |t|
25
+ t.test_files = FileList[testglobs]
26
+ #t.verbose = true # uncomment to see the executed command
27
+ end
17
28
  end
18
29
 
19
30
  # == Gem == #
@@ -28,12 +39,6 @@ directory gemtask.package_dir
28
39
 
29
40
  CLEAN.include(gemtask.package_dir)
30
41
 
31
- desc "Analyze code coverage of the unit tests."
32
- Rcov::RcovTask.new do |t|
33
- t.test_files = FileList[testglobs]
34
- #t.verbose = true # uncomment to see the executed command
35
- end
36
-
37
42
  desc "Test just the SQS interface"
38
43
  task :testsqs do
39
44
  require 'test/test_credentials'
@@ -101,4 +106,25 @@ task :testrds do
101
106
  require 'test/rds/test_right_rds.rb'
102
107
  end
103
108
 
109
+ desc "Test just the SNS interface"
110
+ task :testsns do
111
+ require 'test/test_credentials'
112
+ TestCredentials.get_credentials
113
+ require 'test/sns/test_right_sns.rb'
114
+ end
115
+
116
+ desc "Test Route 53 interface"
117
+ task :testroute53 do
118
+ require 'test/test_credentials'
119
+ TestCredentials.get_credentials
120
+ require 'test/route_53/test_right_route_53'
121
+ end
122
+
123
+ desc "Test ELB interface"
124
+ task :testelb do
125
+ require 'test/test_credentials'
126
+ TestCredentials.get_credentials
127
+ require 'test/elb/test_right_elb'
128
+ end
129
+
104
130
  # vim: syntax=Ruby
@@ -24,7 +24,6 @@
24
24
  # Test
25
25
  module RightAws
26
26
  require 'digest/md5'
27
- require 'pp'
28
27
 
29
28
  class AwsUtils #:nodoc:
30
29
  @@digest1 = OpenSSL::Digest::Digest.new("sha1")
@@ -274,20 +273,26 @@ module RightAws
274
273
  @aws_secret_access_key = aws_secret_access_key
275
274
  # if the endpoint was explicitly defined - then use it
276
275
  if @params[:endpoint_url]
277
- @params[:server] = URI.parse(@params[:endpoint_url]).host
278
- @params[:port] = URI.parse(@params[:endpoint_url]).port
279
- @params[:service] = URI.parse(@params[:endpoint_url]).path
276
+ uri = URI.parse(@params[:endpoint_url])
277
+ @params[:server] = uri.host
278
+ @params[:port] = uri.port
279
+ @params[:service] = uri.path
280
+ @params[:protocol] = uri.scheme
280
281
  # make sure the 'service' path is not empty
281
282
  @params[:service] = service_info[:default_service] if @params[:service].right_blank?
282
- @params[:protocol] = URI.parse(@params[:endpoint_url]).scheme
283
283
  @params[:region] = nil
284
+ default_port = uri.default_port
284
285
  else
285
286
  @params[:server] ||= service_info[:default_host]
286
287
  @params[:server] = "#{@params[:region]}.#{@params[:server]}" if @params[:region]
287
288
  @params[:port] ||= service_info[:default_port]
288
289
  @params[:service] ||= service_info[:default_service]
289
290
  @params[:protocol] ||= service_info[:default_protocol]
291
+ default_port = @params[:protocol] == 'https' ? 443 : 80
290
292
  end
293
+ # build a host name to sign
294
+ @params[:host_to_sign] = @params[:server].dup
295
+ @params[:host_to_sign] << ":#{@params[:port]}" unless default_port == @params[:port].to_i
291
296
  # a set of options to be passed to RightHttpConnection object
292
297
  @params[:connection_options] = {} unless @params[:connection_options].is_a?(Hash)
293
298
  @with_connection_options = {}
@@ -331,7 +336,8 @@ module RightAws
331
336
  # get rid of requestId (this bad boy was added for API 2008-08-08+ and it is uniq for every response)
332
337
  # feb 04, 2009 (load balancer uses 'RequestId' hence use 'i' modifier to hit it also)
333
338
  response = response.sub(%r{<requestId>.+?</requestId>}i, '')
334
- response_md5 = MD5.md5(response).to_s
339
+ # this should work for both ruby 1.8.x and 1.9.x
340
+ response_md5 = Digest::MD5::new.update(response).to_s
335
341
  # check for changes
336
342
  unless @cache[function] && @cache[function][:response_md5] == response_md5
337
343
  # well, the response is new, reset cache data
@@ -416,7 +422,7 @@ module RightAws
416
422
 
417
423
  # ACF, AMS, EC2, LBS and SDB uses this guy
418
424
  # SQS and S3 use their own methods
419
- def generate_request_impl(verb, action, options={}) #:nodoc:
425
+ def generate_request_impl(verb, action, options={}, custom_options={}) #:nodoc:
420
426
  # Form a valid http verb: 'GET' or 'POST' (all the other are not supported now)
421
427
  http_verb = verb.to_s.upcase
422
428
  # remove empty keys from request options
@@ -424,16 +430,16 @@ module RightAws
424
430
  # prepare service data
425
431
  service_hash = {"Action" => action,
426
432
  "AWSAccessKeyId" => @aws_access_key_id,
427
- "Version" => @params[:api_version] }
433
+ "Version" => custom_options[:api_version] || @params[:api_version] }
428
434
  service_hash.merge!(options)
429
435
  # Sign request options
430
- service_params = signed_service_params(@aws_secret_access_key, service_hash, http_verb, @params[:server], @params[:service])
436
+ service_params = signed_service_params(@aws_secret_access_key, service_hash, http_verb, @params[:host_to_sign], @params[:service])
431
437
  # Use POST if the length of the query string is too large
432
438
  # see http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/MakingRESTRequests.html
433
439
  if http_verb != 'POST' && service_params.size > 2000
434
440
  http_verb = 'POST'
435
441
  if signature_version == '2'
436
- service_params = signed_service_params(@aws_secret_access_key, service_hash, http_verb, @params[:server], @params[:service])
442
+ service_params = signed_service_params(@aws_secret_access_key, service_hash, http_verb, @params[:host_to_sign], @params[:service])
437
443
  end
438
444
  end
439
445
  # create a request
@@ -614,10 +620,11 @@ module RightAws
614
620
  # "Filter.2.Value.2"=>"bb"}
615
621
  def amazonize_list(masks, list, options={}) #:nodoc:
616
622
  groups = {}
617
- Array(list).each_with_index do |list_item, i|
623
+ list_idx = options[:index] || 1
624
+ Array(list).each do |list_item|
618
625
  Array(masks).each_with_index do |mask, mask_idx|
619
626
  key = mask[/\?/] ? mask.dup : mask.dup + '.?'
620
- key.sub!('?', (i+1).to_s)
627
+ key.sub!('?', list_idx.to_s)
621
628
  value = Array(list_item)[mask_idx]
622
629
  if value.is_a?(Array)
623
630
  groups.merge!(amazonize_list(key, value, options))
@@ -633,6 +640,7 @@ module RightAws
633
640
  groups[key] = value
634
641
  end
635
642
  end
643
+ list_idx += 1
636
644
  end
637
645
  groups
638
646
  end
@@ -662,6 +670,162 @@ module RightAws
662
670
  result
663
671
  end
664
672
 
673
+ # Build API request keys set.
674
+ #
675
+ # Options is a hash, expectations is a set of keys [and rules] how to represent options.
676
+ # Mappings is an Array (may include hashes) or a Hash.
677
+ #
678
+ # Example:
679
+ #
680
+ # options = { :valid_from => Time.now - 10,
681
+ # :instance_count => 3,
682
+ # :image_id => 'ami-08f41161',
683
+ # :spot_price => 0.059,
684
+ # :instance_type => 'c1.medium',
685
+ # :instance_count => 1,
686
+ # :key_name => 'tim',
687
+ # :availability_zone => 'us-east-1a',
688
+ # :monitoring_enabled => true,
689
+ # :launch_group => 'lg1',
690
+ # :availability_zone_group => 'azg1',
691
+ # :groups => ['a', 'b', 'c'],
692
+ # :group_ids => 'sg-1',
693
+ # :user_data => 'konstantin',
694
+ # :block_device_mappings => [ { :device_name => '/dev/sdk',
695
+ # :ebs_snapshot_id => 'snap-145cbc7d',
696
+ # :ebs_delete_on_termination => true,
697
+ # :ebs_volume_size => 3,
698
+ # :virtual_name => 'ephemeral2' }]}
699
+ # mappings = { :spot_price,
700
+ # :availability_zone_group,
701
+ # :launch_group,
702
+ # :type,
703
+ # :instance_count,
704
+ # :image_id => 'LaunchSpecification.ImageId',
705
+ # :instance_type => 'LaunchSpecification.InstanceType',
706
+ # :key_name => 'LaunchSpecification.KeyName',
707
+ # :addressing_type => 'LaunchSpecification.AddressingType',
708
+ # :kernel_id => 'LaunchSpecification.KernelId',
709
+ # :ramdisk_id => 'LaunchSpecification.RamdiskId',
710
+ # :subnet_id => 'LaunchSpecification.SubnetId',
711
+ # :availability_zone => 'LaunchSpecification.Placement.AvailabilityZone',
712
+ # :monitoring_enabled => 'LaunchSpecification.Monitoring.Enabled',
713
+ # :valid_from => { :value => Proc.new { !options[:valid_from].right_blank? && AwsUtils::utc_iso8601(options[:valid_from]) }},
714
+ # :valid_until => { :value => Proc.new { !options[:valid_until].right_blank? && AwsUtils::utc_iso8601(options[:valid_until]) }},
715
+ # :user_data => { :name => 'LaunchSpecification.UserData',
716
+ # :value => Proc.new { !options[:user_data].right_blank? && Base64.encode64(options[:user_data]).delete("\n") }},
717
+ # :groups => { :amazonize_list => 'LaunchSpecification.SecurityGroup'},
718
+ # :group_ids => { :amazonize_list => 'LaunchSpecification.SecurityGroupId'},
719
+ # :block_device_mappings => { :amazonize_bdm => 'LaunchSpecification.BlockDeviceMapping'})
720
+ #
721
+ # map_api_keys_and_values( options, mappings) #=>
722
+ # {"LaunchSpecification.BlockDeviceMapping.1.Ebs.DeleteOnTermination" => true,
723
+ # "LaunchSpecification.BlockDeviceMapping.1.VirtualName" => "ephemeral2",
724
+ # "LaunchSpecification.BlockDeviceMapping.1.Ebs.VolumeSize" => 3,
725
+ # "LaunchSpecification.BlockDeviceMapping.1.Ebs.SnapshotId" => "snap-145cbc7d",
726
+ # "LaunchSpecification.BlockDeviceMapping.1.DeviceName" => "/dev/sdk",
727
+ # "LaunchSpecification.SecurityGroupId.1" => "sg-1",
728
+ # "LaunchSpecification.InstanceType" => "c1.medium",
729
+ # "LaunchSpecification.KeyName" => "tim",
730
+ # "LaunchSpecification.ImageId" => "ami-08f41161",
731
+ # "LaunchSpecification.SecurityGroup.1" => "a",
732
+ # "LaunchSpecification.SecurityGroup.2" => "b",
733
+ # "LaunchSpecification.SecurityGroup.3" => "c",
734
+ # "LaunchSpecification.Placement.AvailabilityZone" => "us-east-1a",
735
+ # "LaunchSpecification.Monitoring.Enabled" => true,
736
+ # "LaunchGroup" => "lg1",
737
+ # "InstanceCount" => 1,
738
+ # "SpotPrice" => 0.059,
739
+ # "AvailabilityZoneGroup" => "azg1",
740
+ # "ValidFrom" => "2011-06-30T08:06:30.000Z",
741
+ # "LaunchSpecification.UserData" => "a29uc3RhbnRpbg=="}
742
+ #
743
+ def map_api_keys_and_values(options, *mappings) # :nodoc:
744
+ result = {}
745
+ vars = {}
746
+ # Fix inputs and make them all to be hashes
747
+ mappings.flatten.each do |mapping|
748
+ unless mapping.is_a?(Hash)
749
+ # mapping is just a :key_name
750
+ mapping = { mapping => { :name => mapping.to_s.right_camelize, :value => options[mapping] }}
751
+ else
752
+ mapping.each do |local_key, api_opts|
753
+ unless api_opts.is_a?(Hash)
754
+ # mapping is a { :key_name => 'ApiKeyName' }
755
+ mapping[local_key] = { :name => api_opts.to_s, :value => options[local_key]}
756
+ else
757
+ # mapping is a { :key_name => { :name => 'ApiKeyName', :value => 'Value', ... etc} }
758
+ api_opts[:name] = local_key.to_s.right_camelize if (api_opts.keys & [:name, :amazonize_list, :amazonize_bdm]).right_blank?
759
+ api_opts[:value] = options[local_key] unless api_opts.has_key?(:value)
760
+ end
761
+ end
762
+ end
763
+ vars.merge! mapping
764
+ end
765
+ # Build API keys set
766
+ # vars now is a Hash:
767
+ # { :key1 => { :name => 'ApiKey1', :value => 'BlahBlah'},
768
+ # :key2 => { :amazonize_list => 'ApiKey2.?', :value => [1, ...] },
769
+ # :key3 => { :amazonize_bdm => 'BDM', :value => [{..}, ...] }, ... }
770
+ #
771
+ vars.each do |local_key, api_opts|
772
+ if api_opts[:amazonize_list]
773
+ result.merge!(amazonize_list( api_opts[:amazonize_list], api_opts[:value] )) unless api_opts[:value].right_blank?
774
+ elsif api_opts[:amazonize_bdm]
775
+ result.merge!(amazonize_block_device_mappings( api_opts[:value], api_opts[:amazonize_bdm] )) unless api_opts[:value].right_blank?
776
+ else
777
+ api_key = api_opts[:name]
778
+ value = api_opts[:value]
779
+ value = value.call if value.is_a?(Proc)
780
+ next if value.right_blank?
781
+ result[api_key] = value
782
+ end
783
+ end
784
+ #
785
+ result
786
+ end
787
+
788
+ # Transform a hash of parameters into a hash suitable for sending
789
+ # to Amazon using a key mapping.
790
+ #
791
+ # amazonize_hash_with_key_mapping('Group.Filter',
792
+ # {:some_param => 'SomeParam'},
793
+ # {:some_param => 'value'}) #=> {'Group.Filter.SomeParam' => 'value'}
794
+ #
795
+ def amazonize_hash_with_key_mapping(key, mapping, hash, options={})
796
+ result = {}
797
+ unless hash.right_blank?
798
+ mapping.each do |local_name, remote_name|
799
+ value = hash[local_name]
800
+ next if value.nil?
801
+ result["#{key}.#{remote_name}"] = value
802
+ end
803
+ end
804
+ result
805
+ end
806
+
807
+ # Transform a list of hashes of parameters into a hash suitable for sending
808
+ # to Amazon using a key mapping.
809
+ #
810
+ # amazonize_list_with_key_mapping('Group.Filter',
811
+ # [{:some_param => 'SomeParam'}, {:some_param => 'SomeParam'}],
812
+ # {:some_param => 'value'}) #=>
813
+ # {'Group.Filter.1.SomeParam' => 'value',
814
+ # 'Group.Filter.2.SomeParam' => 'value'}
815
+ #
816
+ def amazonize_list_with_key_mapping(key, mapping, list, options={})
817
+ result = {}
818
+ unless list.right_blank?
819
+ list.each_with_index do |item, index|
820
+ mapping.each do |local_name, remote_name|
821
+ value = item[local_name]
822
+ next if value.nil?
823
+ result["#{key}.#{index+1}.#{remote_name}"] = value
824
+ end
825
+ end
826
+ end
827
+ end
828
+
665
829
  # Execute a block of code with custom set of settings for right_http_connection.
666
830
  # Accepts next options (see Rightscale::HttpConnection for explanation):
667
831
  # :raise_on_timeout