krisr-amazon-ec2 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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