krisr-amazon-ec2 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. data/.gitignore +6 -0
  2. data/ChangeLog +284 -0
  3. data/LICENSE +66 -0
  4. data/README.rdoc +329 -0
  5. data/Rakefile +101 -0
  6. data/VERSION +1 -0
  7. data/amazon-ec2.gemspec +123 -0
  8. data/bin/ec2-gem-example.rb +66 -0
  9. data/bin/ec2-gem-profile.rb +10 -0
  10. data/bin/ec2sh +62 -0
  11. data/bin/setup.rb +26 -0
  12. data/deps.rip +1 -0
  13. data/lib/AWS.rb +239 -0
  14. data/lib/AWS/EC2.rb +67 -0
  15. data/lib/AWS/EC2/availability_zones.rb +43 -0
  16. data/lib/AWS/EC2/console.rb +46 -0
  17. data/lib/AWS/EC2/elastic_ips.rb +154 -0
  18. data/lib/AWS/EC2/image_attributes.rb +168 -0
  19. data/lib/AWS/EC2/images.rb +136 -0
  20. data/lib/AWS/EC2/instances.rb +218 -0
  21. data/lib/AWS/EC2/keypairs.rb +96 -0
  22. data/lib/AWS/EC2/products.rb +45 -0
  23. data/lib/AWS/EC2/security_groups.rb +234 -0
  24. data/lib/AWS/EC2/snapshots.rb +96 -0
  25. data/lib/AWS/EC2/volumes.rb +172 -0
  26. data/lib/AWS/ELB.rb +57 -0
  27. data/lib/AWS/ELB/load_balancers.rb +201 -0
  28. data/lib/AWS/exceptions.rb +169 -0
  29. data/lib/AWS/responses.rb +61 -0
  30. data/lib/EC2.rb +31 -0
  31. data/perftools/ec2prof +0 -0
  32. data/perftools/ec2prof-results.dot +193 -0
  33. data/perftools/ec2prof-results.txt +126 -0
  34. data/perftools/ec2prof.symbols +129 -0
  35. data/test/test_EC2.rb +68 -0
  36. data/test/test_EC2_availability_zones.rb +49 -0
  37. data/test/test_EC2_console.rb +54 -0
  38. data/test/test_EC2_elastic_ips.rb +144 -0
  39. data/test/test_EC2_image_attributes.rb +238 -0
  40. data/test/test_EC2_images.rb +197 -0
  41. data/test/test_EC2_instances.rb +348 -0
  42. data/test/test_EC2_keypairs.rb +123 -0
  43. data/test/test_EC2_products.rb +48 -0
  44. data/test/test_EC2_responses.rb +52 -0
  45. data/test/test_EC2_s3_xmlsimple.rb +80 -0
  46. data/test/test_EC2_security_groups.rb +205 -0
  47. data/test/test_EC2_snapshots.rb +83 -0
  48. data/test/test_EC2_volumes.rb +142 -0
  49. data/test/test_ELB_load_balancers.rb +238 -0
  50. data/test/test_helper.rb +19 -0
  51. data/wsdl/2007-08-29.ec2.wsdl +1269 -0
  52. data/wsdl/2008-02-01.ec2.wsdl +1614 -0
  53. data/wsdl/2008-05-05.ec2.wsdl +2052 -0
  54. data/wsdl/2008-12-01.ec2.wsdl +2354 -0
  55. metadata +184 -0
@@ -0,0 +1,57 @@
1
+ # Require any lib files that we have bundled with this Ruby Gem in the lib/ELB directory.
2
+ # Parts of the EC2 module and Base class are broken out into separate
3
+ # files for maintainability and are organized by the functional groupings defined
4
+ # in the EC2 API developers guide.
5
+ Dir[File.join(File.dirname(__FILE__), 'ELB/**/*.rb')].sort.each { |lib| require lib }
6
+
7
+ module AWS
8
+ module ELB
9
+
10
+ # Which host FQDN will we connect to for all API calls to AWS?
11
+ # If ELB_URL is defined in the users ENV we can use that. It is
12
+ # expected that this var is set with something like:
13
+ # export ELB_URL='https://ec2.amazonaws.com'
14
+ #
15
+ if ENV['ELB_URL']
16
+ ELB_URL = ENV['ELB_URL']
17
+ VALID_HOSTS = ['elasticloadbalancing.amazonaws.com']
18
+ raise ArgumentError, "Invalid ELB_URL environment variable : #{ELB_URL}" unless VALID_HOSTS.include?(ELB_URL)
19
+ DEFAULT_HOST = URI.parse(ELB_URL).host
20
+ else
21
+ # default US host
22
+ DEFAULT_HOST = 'elasticloadbalancing.amazonaws.com'
23
+ end
24
+
25
+ # This is the version of the API as defined by Amazon Web Services
26
+ API_VERSION = '2009-05-15'
27
+
28
+ #Introduction:
29
+ #
30
+ # The library exposes one main interface class, 'AWS::ELB::Base'.
31
+ # This class provides all the methods for using the ELB service
32
+ # including the handling of header signing and other security issues .
33
+ # This class uses Net::HTTP to interface with the ELB Query API interface.
34
+ #
35
+ #Required Arguments:
36
+ #
37
+ # :access_key_id => String (default : "")
38
+ # :secret_access_key => String (default : "")
39
+ #
40
+ #Optional Arguments:
41
+ #
42
+ # :use_ssl => Boolean (default : true)
43
+ # :server => String (default : 'elasticloadbalancing.amazonaws.com')
44
+ # :proxy_server => String (default : nil)
45
+ #
46
+ class Base < AWS::Base
47
+ def api_version
48
+ API_VERSION
49
+ end
50
+
51
+ def default_host
52
+ DEFAULT_HOST
53
+ end
54
+ end
55
+
56
+ end
57
+ end
@@ -0,0 +1,201 @@
1
+ module AWS
2
+ module ELB
3
+ class Base < AWS::Base
4
+ # Amazon Developer Guide Docs:
5
+ #
6
+ # This API creates a new LoadBalancer. Once the call has completed
7
+ # successfully, a new LoadBalancer will be created, but it will not be
8
+ # usable until at least one instance has been registered. When the
9
+ # LoadBalancer creation is completed, you can check whether it is usable
10
+ # by using the DescribeInstanceHealth API. The LoadBalancer is usable as
11
+ # soon as any registered instance is InService.
12
+ #
13
+ # Required Arguments:
14
+ #
15
+ # :load_balancer_name => String
16
+ # :listeners => Array of Hashes (:protocol, :load_balancer_port, :instance_port)
17
+ # :availability_zones => Array of Strings
18
+ #
19
+ def create_load_balancer( options = {} )
20
+ raise ArgumentError, "No :availability_zones provided" if options[:availability_zones].nil? || options[:availability_zones].empty?
21
+ raise ArgumentError, "No :listeners provided" if options[:listeners].nil? || options[:listeners].empty?
22
+ raise ArgumentError, "No :load_balancer_name provided" if options[:load_balancer_name].nil? || options[:load_balancer_name].empty?
23
+
24
+ params = {}
25
+
26
+ params.merge!(pathlist('AvailabilityZones.member', [options[:availability_zones]].flatten))
27
+ params.merge!(pathhashlist('Listeners.member', [options[:listeners]].flatten, {
28
+ :protocol => 'Protocol',
29
+ :load_balancer_port => 'LoadBalancerPort',
30
+ :instance_port => 'InstancePort'
31
+ }))
32
+ params['LoadBalancerName'] = options[:load_balancer_name]
33
+
34
+ return response_generator(:action => "CreateLoadBalancer", :params => params)
35
+ end
36
+
37
+ # Amazon Developer Guide Docs:
38
+ #
39
+ # This API deletes the specified LoadBalancer. On deletion, all of the
40
+ # configured properties of the LoadBalancer will be deleted. If you
41
+ # attempt to recreate the LoadBalancer, you need to reconfigure all the
42
+ # settings. The DNS name associated with a deleted LoadBalancer is no
43
+ # longer be usable. Once deleted, the name and associated DNS record of
44
+ # the LoadBalancer no longer exist and traffic sent to any of its IP
45
+ # addresses will no longer be delivered to your instances. You will not
46
+ # get the same DNS name even if you create a new LoadBalancer with same
47
+ # LoadBalancerName.
48
+ #
49
+ # Required Arguments:
50
+ #
51
+ # :load_balancer_name => String
52
+ #
53
+ def delete_load_balancer( options = {} )
54
+ raise ArgumentError, "No :load_balancer_name provided" if options[:load_balancer_name].nil? || options[:load_balancer_name].empty?
55
+
56
+ params = { 'LoadBalancerName' => options[:load_balancer_name] }
57
+
58
+ return response_generator(:action => "DeleteLoadBalancer", :params => params)
59
+ end
60
+
61
+ # Amazon Developer Guide Docs:
62
+ #
63
+ # This API returns detailed configuration information for the specified
64
+ # LoadBalancers, or if no LoadBalancers are specified, then the API
65
+ # returns configuration information for all LoadBalancers created by the
66
+ # caller. For more information, please see LoadBalancer.
67
+ #
68
+ # You must have created the specified input LoadBalancers in order to
69
+ # retrieve this information. In other words, in order to successfully call
70
+ # this API, you must provide the same account credentials as those that
71
+ # were used to create the LoadBalancer.
72
+ #
73
+ # Optional Arguments:
74
+ #
75
+ # :load_balancer_names => String
76
+ #
77
+ def describe_load_balancers( options = {} )
78
+ options = { :load_balancer_names => [] }.merge(options)
79
+
80
+ params = pathlist("LoadBalancerName.member", options[:load_balancer_names])
81
+
82
+ return response_generator(:action => "DescribeLoadBalancers", :params => params)
83
+ end
84
+
85
+ # Amazon Developer Guide Docs:
86
+ #
87
+ # This API adds new instances to the LoadBalancer.
88
+ #
89
+ # Once the instance is registered, it starts receiving traffic and
90
+ # requests from the LoadBalancer. Any instance that is not in any of the
91
+ # Availability Zones registered for the LoadBalancer will be moved to
92
+ # the OutOfService state. It will move to the InService state when the
93
+ # Availability Zone is added to the LoadBalancer.
94
+ #
95
+ # You must have been the one who created the LoadBalancer. In other
96
+ # words, in order to successfully call this API, you must provide the
97
+ # same account credentials as those that were used to create the
98
+ # LoadBalancer.
99
+ #
100
+ # NOTE: Completion of this API does not guarantee that operation has
101
+ # completed. Rather, it means that the request has been registered and
102
+ # the changes will happen shortly.
103
+ #
104
+ # Required Arguments:
105
+ #
106
+ # :instances => Array of Strings
107
+ # :load_balancer_name => String
108
+ #
109
+ def register_instances_with_load_balancer( options = {} )
110
+ raise ArgumentError, "No :instances provided" if options[:instances].nil? || options[:instances].empty?
111
+ raise ArgumentError, "No :load_balancer_name provided" if options[:load_balancer_name].nil? || options[:load_balancer_name].empty?
112
+
113
+ params = {}
114
+
115
+ params.merge!(pathhashlist('Instances.member', [options[:instances]].flatten.map{|instance| {:instance_id => instance}}, {
116
+ :instance_id => 'InstanceId'
117
+ }))
118
+ params['LoadBalancerName'] = options[:load_balancer_name]
119
+
120
+ return response_generator(:action => "RegisterInstancesWithLoadBalancer", :params => params)
121
+ end
122
+
123
+ # Amazon Developer Guide Docs:
124
+ #
125
+ # This API deregisters instances from the LoadBalancer. Trying to
126
+ # deregister an instance that is not registered with the LoadBalancer
127
+ # does nothing.
128
+ #
129
+ # In order to successfully call this API, you must provide the same
130
+ # account credentials as those that were used to create the
131
+ # LoadBalancer.
132
+ #
133
+ # Once the instance is deregistered, it will stop receiving traffic from
134
+ # the LoadBalancer.
135
+ #
136
+ # Required Arguments:
137
+ #
138
+ # :instances => Array of Strings
139
+ # :load_balancer_name => String
140
+ #
141
+ def deregister_instances_from_load_balancer( options = {} )
142
+ raise ArgumentError, "No :instances provided" if options[:instances].nil? || options[:instances].empty?
143
+ raise ArgumentError, "No :load_balancer_name provided" if options[:load_balancer_name].nil? || options[:load_balancer_name].empty?
144
+
145
+ params = {}
146
+
147
+ params.merge!(pathhashlist('Instances.member', [options[:instances]].flatten.map{|instance| {:instance_id => instance}}, {
148
+ :instance_id => 'InstanceId'
149
+ }))
150
+ params['LoadBalancerName'] = options[:load_balancer_name]
151
+
152
+ return response_generator(:action => "DeregisterInstancesFromLoadBalancer", :params => params)
153
+ end
154
+
155
+ # Amazon Developer Guide Docs:
156
+ #
157
+ # This API enables you to define an application healthcheck for the
158
+ # instances.
159
+ #
160
+ # Note: Completion of this API does not guarantee that operation has completed. Rather, it means that the request has been registered and the changes will happen shortly.
161
+ #
162
+ # Required Arguments
163
+ #
164
+ # :health_check => Hash (:timeout, :interval, :unhealthy_threshold, :healthy_threshold)
165
+ # :load_balancer_name => String
166
+ #
167
+ def configure_health_check( options = {} )
168
+ raise ArgumentError, "No :health_check provided" if options[:health_check].nil? || options[:health_check].empty?
169
+ raise ArgumentError, "No :health_check => :target provided" if options[:health_check][:target].nil? || options[:health_check][:target].empty?
170
+ raise ArgumentError, "No :health_check => :timeout provided" if options[:health_check][:timeout].nil? || options[:health_check][:timeout].empty?
171
+ raise ArgumentError, "No :health_check => :interval provided" if options[:health_check][:interval].nil? || options[:health_check][:interval].empty?
172
+ raise ArgumentError, "No :health_check => :unhealthy_threshold provided" if options[:health_check][:unhealthy_threshold].nil? || options[:health_check][:unhealthy_threshold].empty?
173
+ raise ArgumentError, "No :health_check => :healthy_threshold provided" if options[:health_check][:healthy_threshold].nil? || options[:health_check][:healthy_threshold].empty?
174
+ raise ArgumentError, "No :load_balancer_name provided" if options[:load_balancer_name].nil? || options[:load_balancer_name].empty?
175
+
176
+ params = {}
177
+
178
+ params['LoadBalancerName'] = options[:load_balancer_name]
179
+ params['HealthCheck.Target'] = options[:health_check][:target]
180
+ params['HealthCheck.Timeout'] = options[:health_check][:timeout]
181
+ params['HealthCheck.Interval'] = options[:health_check][:interval]
182
+ params['HealthCheck.UnhealthyThreshold'] = options[:health_check][:unhealthy_threshold]
183
+ params['HealthCheck.HealthyThreshold'] = options[:health_check][:healthy_threshold]
184
+
185
+ return response_generator(:action => "ConfigureHealthCheck", :params => params)
186
+ end
187
+
188
+ def describe_intance_health( options = {} )
189
+ raise "Not yet implemented"
190
+ end
191
+
192
+ def disable_availability_zones_for_load_balancer( options = {} )
193
+ raise "Not yet implemented"
194
+ end
195
+
196
+ def enable_availability_zones_for_load_balancer( options = {} )
197
+ raise "Not yet implemented"
198
+ end
199
+ end
200
+ end
201
+ end
@@ -0,0 +1,169 @@
1
+ #--
2
+ # Amazon Web Services EC2 Query API Ruby library
3
+ #
4
+ # Ruby Gem Name:: amazon-ec2
5
+ # Author:: Glenn Rempe (mailto:glenn@rempe.us)
6
+ # Copyright:: Copyright (c) 2007-2008 Glenn Rempe
7
+ # License:: Distributes under the same terms as Ruby
8
+ # Home:: http://github.com/grempe/amazon-ec2/tree/master
9
+ #++
10
+
11
+ module AWS
12
+ # OUR CUSTOM ERROR CODES
13
+
14
+ # All of our errors are superclassed by Error < RuntimeError
15
+ class Error < RuntimeError #:nodoc:
16
+ end
17
+
18
+ # A client side only argument error
19
+ class ArgumentError < Error #:nodoc:
20
+ end
21
+
22
+
23
+ # AWS EC2 CLIENT ERROR CODES
24
+
25
+ # AWS EC2 can throw error exceptions that contain a '.' in them.
26
+ # since we can't name an exception class with that '.' I compressed
27
+ # each class name into the non-dot version. This allows us to retain
28
+ # the granularity of the exception.
29
+
30
+ # User not authorized.
31
+ class AuthFailure < Error #:nodoc:
32
+ end
33
+
34
+ # Invalid AWS Account
35
+ class InvalidClientTokenId < Error #:nodoc:
36
+ end
37
+
38
+ # Invalid Parameters for Value
39
+ class InvalidParameterValue < Error #:nodoc:
40
+ end
41
+
42
+ # Specified AMI has an unparsable manifest.
43
+ class InvalidManifest < Error #:nodoc:
44
+ end
45
+
46
+ # Specified AMI ID is not valid.
47
+ class InvalidAMIIDMalformed < Error #:nodoc:
48
+ end
49
+
50
+ # Specified AMI ID does not exist.
51
+ class InvalidAMIIDNotFound < Error #:nodoc:
52
+ end
53
+
54
+ # Specified AMI ID has been deregistered and is no longer available.
55
+ class InvalidAMIIDUnavailable < Error #:nodoc:
56
+ end
57
+
58
+ # Specified instance ID is not valid.
59
+ class InvalidInstanceIDMalformed < Error #:nodoc:
60
+ end
61
+
62
+ # Specified instance ID does not exist.
63
+ class InvalidInstanceIDNotFound < Error #:nodoc:
64
+ end
65
+
66
+ # Specified keypair name does not exist.
67
+ class InvalidKeyPairNotFound < Error #:nodoc:
68
+ end
69
+
70
+ # Attempt to create a duplicate keypair.
71
+ class InvalidKeyPairDuplicate < Error #:nodoc:
72
+ end
73
+
74
+ # Specified group name does not exist.
75
+ class InvalidGroupNotFound < Error #:nodoc:
76
+ end
77
+
78
+ # Attempt to create a duplicate group.
79
+ class InvalidGroupDuplicate < Error #:nodoc:
80
+ end
81
+
82
+ # Specified group can not be deleted because it is in use.
83
+ class InvalidGroupInUse < Error #:nodoc:
84
+ end
85
+
86
+ # Specified group name is a reserved name.
87
+ class InvalidGroupReserved < Error #:nodoc:
88
+ end
89
+
90
+ # Attempt to authorize a permission that has already been authorized.
91
+ class InvalidPermissionDuplicate < Error #:nodoc:
92
+ end
93
+
94
+ # Specified permission is invalid.
95
+ class InvalidPermissionMalformed < Error #:nodoc:
96
+ end
97
+
98
+ # Specified reservation ID is invalid.
99
+ class InvalidReservationIDMalformed < Error #:nodoc:
100
+ end
101
+
102
+ # Specified reservation ID does not exist.
103
+ class InvalidReservationIDNotFound < Error #:nodoc:
104
+ end
105
+
106
+ # User has reached max allowed concurrent running instances.
107
+ class InstanceLimitExceeded < Error #:nodoc:
108
+ end
109
+
110
+ # An invalid set of parameters were passed as arguments
111
+ # e.g. RunInstances was called with minCount and maxCount set to 0 or minCount > maxCount.
112
+ class InvalidParameterCombination < Error #:nodoc:
113
+ end
114
+
115
+ # An unknown parameter was passed as an argument
116
+ class UnknownParameter < Error #:nodoc:
117
+ end
118
+
119
+ # The user ID is neither in the form of an AWS account ID or one
120
+ # of the special values accepted by the owner or executableBy flags
121
+ # in the DescribeImages call.
122
+ class InvalidUserIDMalformed < Error #:nodoc:
123
+ end
124
+
125
+ # The value of an item added to, or removed from, an image attribute is invalid.
126
+ class InvalidAMIAttributeItemValue < Error #:nodoc:
127
+ end
128
+
129
+ class MalformedInput < Error #:nodoc:
130
+ end
131
+
132
+ # ELB ERRORS
133
+
134
+ class LoadBalancerNotFound < Error #:nodoc:
135
+ end
136
+
137
+ class ValidationError < Error #:nodoc:
138
+ end
139
+
140
+ class DuplicateLoadBalancerName < Error #:nodoc:
141
+ end
142
+
143
+ class TooManyLoadBalancers < Error #:nodoc:
144
+ end
145
+
146
+ class InvalidInstance < Error #:nodoc:
147
+ end
148
+
149
+ class InvalidConfigurationRequest < Error #:nodoc:
150
+ end
151
+
152
+ # AWS EC2 SERVER ERROR CODES
153
+
154
+ # Internal AWS EC2 Error.
155
+ class InternalError < Error #:nodoc:
156
+ end
157
+
158
+ # There are not enough available instances to satify your minimum request.
159
+ class InsufficientInstanceCapacity < Error #:nodoc:
160
+ end
161
+
162
+ # The server is overloaded and cannot handle request.
163
+ class Unavailable < Error #:nodoc:
164
+ end
165
+
166
+ class SignatureDoesNotMatch < Error #:nodoc:
167
+ end
168
+
169
+ end
@@ -0,0 +1,61 @@
1
+ #--
2
+ # Amazon Web Services EC2 Query API Ruby library
3
+ #
4
+ # Ruby Gem Name:: amazon-ec2
5
+ # Author:: Glenn Rempe (mailto:glenn@rempe.us)
6
+ # Copyright:: Copyright (c) 2007-2008 Glenn Rempe
7
+ # License:: Distributes under the same terms as Ruby
8
+ # Home:: http://github.com/grempe/amazon-ec2/tree/master
9
+ #++
10
+
11
+ # This allows us to access hash values as if they were methods
12
+ # e.g. foo[:bar] can be accessed as foo.bar
13
+
14
+ class Hash
15
+ def method_missing(meth, *args, &block)
16
+ if args.size == 0
17
+ self[meth.to_s] || self[meth.to_sym]
18
+ end
19
+ end
20
+ end
21
+
22
+ module AWS
23
+
24
+ # The make_request() and aws_error? methods, which are shared by all, will raise any
25
+ # exceptions encountered along the way as it converses with EC2.
26
+ #
27
+ # Exception Handling: If for some reason an error occurrs when executing a method
28
+ # (e.g. its arguments were incorrect, or it simply failed) then an exception will
29
+ # be thrown. The exceptions are defined in exceptions.rb as individual classes and should
30
+ # match the exceptions that Amazon has defined for EC2. If the exception raised cannot be
31
+ # identified then a more generic exception class will be thrown.
32
+ #
33
+ # The implication of this is that you need to be prepared to handle any exceptions that
34
+ # may be raised by this library in YOUR code with a 'rescue' clauses. It is up to you
35
+ # how gracefully you want to handle these exceptions that are raised.
36
+
37
+ begin
38
+ require 'xmlsimple' unless defined? XmlSimple
39
+ rescue Exception => e
40
+ require 'xml-simple' unless defined? XmlSimple
41
+ end
42
+
43
+ class Response
44
+
45
+ def self.parse(options = {})
46
+ options = {
47
+ :xml => "",
48
+ :parse_options => { 'forcearray' => ['item', 'member'], 'suppressempty' => nil, 'keeproot' => false }
49
+ }.merge(options)
50
+
51
+ # NOTE: Parsing the response as a nested set of Response objects was extremely
52
+ # memory intensive and appeared to leak (the memory was not freed on subsequent requests).
53
+ # It was changed to return the raw XmlSimple response.
54
+ response = XmlSimple.xml_in(options[:xml], options[:parse_options])
55
+
56
+ return response
57
+ end
58
+
59
+ end # class Response
60
+
61
+ end # module AWS