amazon-ec2 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,139 +1,231 @@
1
- # Amazon Web Services EC2 Query API Ruby Library
2
- # This library has been packaged as a Ruby Gem
3
- # by Glenn Rempe ( grempe @nospam@ rubyforge.org ).
4
- #
5
- # Source code and gem hosted on RubyForge
6
- # under the Ruby License as of 12/14/2006:
7
- # http://amazon-ec2.rubyforge.org
1
+ #--
2
+ # Amazon Web Services EC2 Query API Ruby library
3
+ #
4
+ # Ruby Gem Name:: amazon-ec2
5
+ # Author:: Glenn Rempe (mailto:glenn@elasticworkbench.com)
6
+ # Copyright:: Copyright (c) 2007 Glenn Rempe
7
+ # License:: Distributes under the same terms as Ruby
8
+ # Home:: http://amazon-ec2.rubyforge.org
9
+ #++
8
10
 
9
11
  module EC2
10
12
 
11
- class AWSAuthConnection
13
+ class Base
12
14
 
13
- # The CreateSecurityGroup operation creates a new security group.
14
- #
15
- # Every instance is launched in a security group. If none is specified
16
- # as part of the launch request then instances are launched in the
17
- # default security group. Instances within the same security group
18
- # have unrestricted network access to one another. Instances will reject
19
- # network access attempts from other instances in a different security
20
- # group. As the owner of instances you may grant or revoke specific
21
- # permissions using the AuthorizeSecurityGroupIngress and
22
- # RevokeSecurityGroupIngress operations.
23
- def create_security_group(groupName, groupDescription)
15
+
16
+ #Amazon Developer Guide Docs:
17
+ #
18
+ # The CreateSecurityGroup operation creates a new security group. Every instance is launched
19
+ # in a security group. If none is specified as part of the launch request then instances
20
+ # are launched in the default security group. Instances within the same security group have
21
+ # unrestricted network access to one another. Instances will reject network access attempts from other
22
+ # instances in a different security group. As the owner of instances you may grant or revoke specific
23
+ # permissions using the AuthorizeSecurityGroupIngress and RevokeSecurityGroupIngress operations.
24
+ #
25
+ #Required Arguments:
26
+ #
27
+ # :group_name => String (default : "")
28
+ # :group_description => String (default : "")
29
+ #
30
+ #Optional Arguments:
31
+ #
32
+ # none
33
+ #
34
+ def create_security_group( options = {} )
35
+
36
+ options = {:group_name => "",
37
+ :group_description => ""
38
+ }.merge(options)
39
+
40
+ raise ArgumentError, "No :group_name provided" if options[:group_name].nil? || options[:group_name].empty?
41
+ raise ArgumentError, "No :group_description provided" if options[:group_description].nil? || options[:group_description].empty?
42
+
24
43
  params = {
25
- "GroupName" => groupName,
26
- "GroupDescription" => groupDescription
44
+ "GroupName" => options[:group_name],
45
+ "GroupDescription" => options[:group_description]
27
46
  }
28
- CreateSecurityGroupResponse.new(make_request("CreateSecurityGroup", params))
29
- end
30
-
31
- # Maintain backward compatibility. Changed method name from create_securitygroup
32
- # to more consistent name.
33
- alias create_securitygroup create_security_group
34
-
35
- # The DescribeSecurityGroups operation returns information about security
36
- # groups owned by the user making the request.
37
- #
38
- # An optional list of security group names may be provided to request
39
- # information for those security groups only. If no security group
40
- # names are provided, information of all security groups will be returned.
41
- # If a group is specified that does not exist a fault is returned.
42
- def describe_security_groups(groupNames=[])
43
- params = pathlist("GroupName", groupNames)
44
- DescribeSecurityGroupsResponse.new(make_request("DescribeSecurityGroups", params))
47
+
48
+ return response_generator(:action => "CreateSecurityGroup", :params => params)
49
+
45
50
  end
46
51
 
47
- # Maintain backward compatibility. Changed method name from describe_securitygroups
48
- # to more consistent name.
49
- alias describe_securitygroups describe_security_groups
50
52
 
51
- # The DeleteSecurityGroup operation deletes a security group.
52
- #
53
- # If an attempt is made to delete a security group and any
54
- # instances exist that are members of that group a fault is
55
- # returned.
56
- def delete_security_group(groupName)
57
- params = { "GroupName" => groupName }
58
- DeleteSecurityGroupResponse.new(make_request("DeleteSecurityGroup", params))
53
+ #Amazon Developer Guide Docs:
54
+ #
55
+ # The DescribeSecurityGroups operation returns information about security groups owned by the
56
+ # user making the request.
57
+ #
58
+ # An optional list of security group names may be provided to request information for those security
59
+ # groups only. If no security group names are provided, information of all security groups will be
60
+ # returned. If a group is specified that does not exist a fault is returned.
61
+ #
62
+ #Required Arguments:
63
+ #
64
+ # none
65
+ #
66
+ #Optional Arguments:
67
+ #
68
+ # :group_name => Array (default : [])
69
+ #
70
+ def describe_security_groups( options = {} )
71
+
72
+ options = { :group_name => [] }.merge(options)
73
+
74
+ params = pathlist("GroupName", options[:group_name] )
75
+
76
+ return response_generator(:action => "DescribeSecurityGroups", :params => params)
77
+
59
78
  end
60
79
 
61
- # Maintain backward compatibility. Changed method name from delete_securitygroup
62
- # to more consistent name.
63
- alias delete_securitygroup delete_security_group
64
80
 
65
- # The AuthorizeSecurityGroupIngress operation adds permissions to a security
66
- # group.
67
- #
68
- # Permissions are specified in terms of the IP protocol (TCP, UDP or ICMP),
69
- # the source of the request (by IP range or an Amazon EC2 user-group pair),
70
- # source and destination port ranges (for TCP and UDP), and ICMP codes and
71
- # types (for ICMP). When authorizing ICMP, -1 may be used as a wildcard in
72
- # the type and code fields.
73
- #
74
- # Permission changes are propagated to instances within the security group
75
- # being modified as quickly as possible. However, a small delay is likely,
76
- # depending on the number of instances that are members of the indicated group.
77
- #
78
- # When authorizing a user/group pair permission, GroupName,
79
- # SourceSecurityGroupName and SourceSecurityGroupOwnerId must be specified.
80
- # When authorizing a CIDR IP permission, GroupName, IpProtocol, FromPort,
81
- # ToPort and CidrIp must be specified. Mixing these two types of parameters
82
- # is not allowed.
83
- def authorize_security_group_ingress(*args)
84
- params = auth_revoke_impl(*args)
85
- AuthorizeSecurityGroupIngressResponse.new(make_request("AuthorizeSecurityGroupIngress", params))
81
+ #Amazon Developer Guide Docs:
82
+ #
83
+ # The DeleteSecurityGroup operation deletes a security group.
84
+ #
85
+ # If an attempt is made to delete a security group and any instances exist that are members of that group a
86
+ # fault is returned.
87
+ #
88
+ #Required Arguments:
89
+ #
90
+ # :group_name => String (default : "")
91
+ #
92
+ #Optional Arguments:
93
+ #
94
+ # none
95
+ #
96
+ def delete_security_group( options = {} )
97
+
98
+ options = { :group_name => "" }.merge(options)
99
+
100
+ raise ArgumentError, "No :group_name provided" if options[:group_name].nil? || options[:group_name].empty?
101
+
102
+ params = { "GroupName" => options[:group_name] }
103
+
104
+ return response_generator(:action => "DeleteSecurityGroup", :params => params)
105
+
86
106
  end
87
107
 
88
- # Maintain backward compatibility. Changed method name from authorize
89
- # to more consistent name.
90
- alias authorize authorize_security_group_ingress
91
108
 
92
- # The RevokeSecurityGroupIngress operation revokes existing permissions
93
- # that were previously granted to a security group. The permissions to
94
- # revoke must be specified using the same values originally used to grant
95
- # the permission.
96
- #
97
- # Permissions are specified in terms of the IP protocol (TCP, UDP or ICMP),
98
- # the source of the request (by IP range or an Amazon EC2 user-group pair),
99
- # source and destination port ranges (for TCP and UDP), and ICMP codes and
100
- # types (for ICMP). When authorizing ICMP, -1 may be used as a wildcard
101
- # in the type and code fields.
102
- #
103
- # Permission changes are propagated to instances within the security group
104
- # being modified as quickly as possible. However, a small delay is likely,
105
- # depending on the number of instances that are members of the indicated group.
106
- #
107
- # When revoking a user/group pair permission, GroupName, SourceSecurityGroupName
108
- # and SourceSecurityGroupOwnerId must be specified. When authorizing a CIDR IP
109
- # permission, GroupName, IpProtocol, FromPort, ToPort and CidrIp must be
110
- # specified. Mixing these two types of parameters is not allowed.
111
- def revoke_security_group_ingress(*args)
112
- params = auth_revoke_impl(*args)
113
- RevokeSecurityGroupIngressResponse.new(make_request("RevokeSecurityGroupIngress", params))
109
+ #Amazon Developer Guide Docs:
110
+ #
111
+ # The AuthorizeSecurityGroupIngress operation adds permissions to a security group.
112
+ #
113
+ # Permissions are specified in terms of the IP protocol (TCP, UDP or ICMP), the source of the request (by
114
+ # IP range or an Amazon EC2 user-group pair), source and destination port ranges (for TCP and UDP),
115
+ # and ICMP codes and types (for ICMP). When authorizing ICMP, -1 may be used as a wildcard in the
116
+ # type and code fields.
117
+ #
118
+ # Permission changes are propagated to instances within the security group being modified as quickly as
119
+ # possible. However, a small delay is likely, depending on the number of instances that are members of
120
+ # the indicated group.
121
+ #
122
+ # When authorizing a user/group pair permission, GroupName, SourceSecurityGroupName and
123
+ # SourceSecurityGroupOwnerId must be specified. When authorizing a CIDR IP permission,
124
+ # GroupName, IpProtocol, FromPort, ToPort and CidrIp must be specified. Mixing these two types
125
+ # of parameters is not allowed.
126
+ #
127
+ #Required Arguments:
128
+ #
129
+ # :group_name => String (default : "")
130
+ #
131
+ #Optional Arguments:
132
+ #
133
+ # :ip_protocol => String (default : nil) : Required when authorizing CIDR IP permission
134
+ # :from_port => Integer (default : nil) : Required when authorizing CIDR IP permission
135
+ # :to_port => Integer (default : nil) : Required when authorizing CIDR IP permission
136
+ # :cidr_ip => String (default : nil): Required when authorizing CIDR IP permission
137
+ # :source_security_group_name => String (default : nil) : Required when authorizing user group pair permissions
138
+ # :source_security_group_owner_id => String (default : nil) : Required when authorizing user group pair permissions
139
+ #
140
+ def authorize_security_group_ingress( options = {} )
141
+
142
+ # defaults
143
+ options = { :group_name => nil,
144
+ :ip_protocol => nil,
145
+ :from_port => nil,
146
+ :to_port => nil,
147
+ :cidr_ip => nil,
148
+ :source_security_group_name => nil,
149
+ :source_security_group_owner_id => nil }.merge(options)
150
+
151
+ # lets not validate the rest of the possible permutations of required params and instead let
152
+ # EC2 sort it out on the server side. We'll only require :group_name as that is always needed.
153
+ raise ArgumentError, "No :group_name provided" if options[:group_name].nil? || options[:group_name].empty?
154
+
155
+ params = { "GroupName" => options[:group_name],
156
+ "IpProtocol" => options[:ip_protocol],
157
+ "FromPort" => options[:from_port].to_s,
158
+ "ToPort" => options[:to_port].to_s,
159
+ "CidrIp" => options[:cidr_ip],
160
+ "SourceSecurityGroupName" => options[:source_security_group_name],
161
+ "SourceSecurityGroupOwnerId" => options[:source_security_group_owner_id]
162
+ }
163
+
164
+ return response_generator(:action => "AuthorizeSecurityGroupIngress", :params => params)
165
+
114
166
  end
115
167
 
116
- # Maintain backward compatibility. Changed method name from revoke
117
- # to more consistent name.
118
- alias revoke revoke_security_group_ingress
119
168
 
120
- private
169
+ #Amazon Developer Guide Docs:
170
+ #
171
+ # The RevokeSecurityGroupIngress operation revokes existing permissions that were previously
172
+ # granted to a security group. The permissions to revoke must be specified using the same values
173
+ # originally used to grant the permission.
174
+ #
175
+ # Permissions are specified in terms of the IP protocol (TCP, UDP or ICMP), the source of the request (by
176
+ # IP range or an Amazon EC2 user-group pair), source and destination port ranges (for TCP and UDP),
177
+ # and ICMP codes and types (for ICMP). When authorizing ICMP, -1 may be used as a wildcard in the
178
+ # type and code fields.
179
+ #
180
+ # Permission changes are propagated to instances within the security group being modified as quickly as
181
+ # possible. However, a small delay is likely, depending on the number of instances that are members of
182
+ # the indicated group.
183
+ #
184
+ # When revoking a user/group pair permission, GroupName, SourceSecurityGroupName and
185
+ # SourceSecurityGroupOwnerId must be specified. When authorizing a CIDR IP permission,
186
+ # GroupName, IpProtocol, FromPort, ToPort and CidrIp must be specified. Mixing these two types
187
+ # of parameters is not allowed.
188
+ #
189
+ #Required Arguments:
190
+ #
191
+ # :group_name => String (default : "")
192
+ #
193
+ #Optional Arguments:
194
+ #
195
+ # :ip_protocol => String (default : nil) : Required when revoking CIDR IP permission
196
+ # :from_port => Integer (default : nil) : Required when revoking CIDR IP permission
197
+ # :to_port => Integer (default : nil) : Required when revoking CIDR IP permission
198
+ # :cidr_ip => String (default : nil): Required when revoking CIDR IP permission
199
+ # :source_security_group_name => String (default : nil) : Required when revoking user group pair permissions
200
+ # :source_security_group_owner_id => String (default : nil) : Required when revoking user group pair permissions
201
+ #
202
+ def revoke_security_group_ingress( options = {} )
121
203
 
122
- def auth_revoke_impl(groupName, kwargs={})
123
- in_params = { :ipProtocol=>nil, :fromPort=>nil, :toPort=>nil, :cidrIp=>nil, :sourceSecurityGroupName=>nil,
124
- :sourceSecurityGroupOwnerId=>nil}
125
- in_params.merge! kwargs
126
-
127
- { "GroupName" => in_params[:groupName] ,
128
- "IpProtocol" => in_params[:ipProtocol],
129
- "FromPort" => in_params[:fromPort].to_s,
130
- "ToPort" => in_params[:toPort].to_s,
131
- "CidrIp" => in_params[:cidrIp],
132
- "SourceSecurityGroupName" => in_params[:sourceSecurityGroupName],
133
- "SourceSecurityGroupOwnerId" => in_params[:sourceSecurityGroupOwnerId],
134
- }.reject { |key, value| value.nil? or value.empty?}
135
-
136
- end
204
+ # defaults
205
+ options = { :group_name => nil,
206
+ :ip_protocol => nil,
207
+ :from_port => nil,
208
+ :to_port => nil,
209
+ :cidr_ip => nil,
210
+ :source_security_group_name => nil,
211
+ :source_security_group_owner_id => nil }.merge(options)
212
+
213
+ # lets not validate the rest of the possible permutations of required params and instead let
214
+ # EC2 sort it out on the server side. We'll only require :group_name as that is always needed.
215
+ raise ArgumentError, "No :group_name provided" if options[:group_name].nil? || options[:group_name].empty?
216
+
217
+ params = { "GroupName" => options[:group_name],
218
+ "IpProtocol" => options[:ip_protocol],
219
+ "FromPort" => options[:from_port].to_s,
220
+ "ToPort" => options[:to_port].to_s,
221
+ "CidrIp" => options[:cidr_ip],
222
+ "SourceSecurityGroupName" => options[:source_security_group_name],
223
+ "SourceSecurityGroupOwnerId" => options[:source_security_group_owner_id]
224
+ }
225
+
226
+ return response_generator(:action => "RevokeSecurityGroupIngress", :params => params)
227
+
228
+ end
137
229
 
138
230
  end
139
231
 
data/lib/EC2/version.rb CHANGED
@@ -1,9 +1,18 @@
1
+ #--
2
+ # Amazon Web Services EC2 Query API Ruby library
3
+ #
4
+ # Ruby Gem Name:: amazon-ec2
5
+ # Author:: Glenn Rempe (mailto:glenn@elasticworkbench.com)
6
+ # Copyright:: Copyright (c) 2007 Glenn Rempe
7
+ # License:: Distributes under the same terms as Ruby
8
+ # Home:: http://amazon-ec2.rubyforge.org
9
+ #++
10
+
1
11
  module EC2 #:nodoc:
2
12
  module VERSION #:nodoc:
3
13
  MAJOR = 0
4
- MINOR = 1
14
+ MINOR = 2
5
15
  TINY = 0
6
-
7
16
  STRING = [MAJOR, MINOR, TINY].join('.')
8
17
  end
9
18
  end
data/test/test_EC2.rb CHANGED
@@ -1,21 +1,52 @@
1
+ #--
2
+ # Amazon Web Services EC2 Query API Ruby library
3
+ #
4
+ # Ruby Gem Name:: amazon-ec2
5
+ # Author:: Glenn Rempe (mailto:glenn@elasticworkbench.com)
6
+ # Copyright:: Copyright (c) 2007 Glenn Rempe
7
+ # License:: Distributes under the same terms as Ruby
8
+ # Home:: http://amazon-ec2.rubyforge.org
9
+ #++
10
+
1
11
  require File.dirname(__FILE__) + '/test_helper.rb'
2
12
 
3
- class TestEC2 < Test::Unit::TestCase
13
+ context "The EC2 method " do
4
14
 
5
- def setup
6
- @conn = EC2::AWSAuthConnection.new('not a key', 'not a secret')
15
+ setup do
7
16
  end
8
17
 
9
- def test_reboot_instances
10
- body = <<-RESPONSE
11
- <RebootInstancesResponse xmlns="http://ec2.amazonaws.com/doc/2007-01-03/">
12
- <return>true</return>
13
- </RebootInstancesResponse>
14
- RESPONSE
18
+ specify "EC2::Base attribute readers should be available" do
19
+ @ec2 = EC2::Base.new( :access_key_id => "not a key",
20
+ :secret_access_key => "not a secret",
21
+ :use_ssl => true,
22
+ :server => "foo.example.com" )
23
+
24
+ @ec2.use_ssl.should.equal true
25
+ @ec2.port.should.equal 443
26
+ @ec2.server.should.equal "foo.example.com"
27
+ end
28
+
29
+
30
+ specify "EC2::Base should work with insecure connections as well" do
31
+ @ec2 = EC2::Base.new( :access_key_id => "not a key",
32
+ :secret_access_key => "not a secret",
33
+ :use_ssl => false,
34
+ :server => "foo.example.com" )
15
35
 
16
- @conn.expects(:make_request).with('RebootInstances', {"InstanceId.1"=>"i-2ea64347", "InstanceId.2"=>"i-21a64348"}).
17
- returns stub(:body => body, :is_a? => true)
18
- assert_equal true, @conn.reboot_instances('i-2ea64347', 'i-21a64348').parse
36
+ @ec2.use_ssl.should.equal false
37
+ @ec2.port.should.equal 80
38
+ @ec2.server.should.equal "foo.example.com"
39
+ end
40
+
41
+
42
+ specify "EC2.canonical_string(path) should data that is stripped of ?,&,= " do
43
+ path = "?name1=value1&name2=value2&name3=value3"
44
+ EC2.canonical_string(path).should.equal "name1value1name2value2name3value3"
45
+ end
46
+
47
+ specify "EC2.encode should return the expected string" do
48
+ EC2.encode("secretaccesskey", "foobar123", urlencode=true).should.equal "e3jeuDc3DIX2mW8cVqWiByj4j5g%3D"
49
+ EC2.encode("secretaccesskey", "foobar123", urlencode=false).should.equal "e3jeuDc3DIX2mW8cVqWiByj4j5g="
19
50
  end
20
51
 
21
- end
52
+ end
@@ -0,0 +1,54 @@
1
+ #--
2
+ # Amazon Web Services EC2 Query API Ruby library
3
+ #
4
+ # Ruby Gem Name:: amazon-ec2
5
+ # Author:: Glenn Rempe (mailto:glenn@elasticworkbench.com)
6
+ # Copyright:: Copyright (c) 2007 Glenn Rempe
7
+ # License:: Distributes under the same terms as Ruby
8
+ # Home:: http://amazon-ec2.rubyforge.org
9
+ #++
10
+
11
+ require File.dirname(__FILE__) + '/test_helper.rb'
12
+
13
+ context "The EC2 console " do
14
+
15
+ setup do
16
+ @ec2 = EC2::Base.new( :access_key_id => "not a key", :secret_access_key => "not a secret" )
17
+
18
+ @get_console_output_response_body = <<-RESPONSE
19
+ <GetConsoleOutputResponse xmlns="http://ec2.amazonaws.com/doc/2007-01-19">
20
+ <instanceId>i-28a64341</instanceId>
21
+ <timestamp>2007-01-03 15:00:00</timestamp>
22
+ <output>
23
+ YyB2ZXJzaW9uIDQuMC4xIDIwMDUwNzI3IChSZWQgSGF0IDQuMC4xLTUpKSAjMSBTTVAgVGh1IE9j
24
+ dCAyNiAwODo0MToyNiBTQVNUIDIwMDYKQklPUy1wcm92aWRlZCBwaHlzaWNhbCBSQU0gbWFwOgpY
25
+ ZW46IDAwMDAwMDAwMDAwMDAwMDAgLSAwMDAwMDAwMDZhNDAwMDAwICh1c2FibGUpCjk4ME1CIEhJ
26
+ R0hNRU0gYXZhaWxhYmxlLgo3MjdNQiBMT1dNRU0gYXZhaWxhYmxlLgpOWCAoRXhlY3V0ZSBEaXNh
27
+ YmxlKSBwcm90ZWN0aW9uOiBhY3RpdmUKSVJRIGxvY2t1cCBkZXRlY3Rpb24gZGlzYWJsZWQKQnVp
28
+ bHQgMSB6b25lbGlzdHMKS2VybmVsIGNvbW1hbmQgbGluZTogcm9vdD0vZGV2L3NkYTEgcm8gNApF
29
+ bmFibGluZyBmYXN0IEZQVSBzYXZlIGFuZCByZXN0b3JlLi4uIGRvbmUuCg==
30
+ </output>
31
+ </GetConsoleOutputResponse>
32
+ RESPONSE
33
+
34
+ end
35
+
36
+
37
+ specify "should return info written to a specific instances console" do
38
+ @ec2.stubs(:make_request).with('GetConsoleOutput', {"InstanceId"=>"i-2ea64347"}).
39
+ returns stub(:body => @get_console_output_response_body, :is_a? => true)
40
+ @ec2.get_console_output( :instance_id => "i-2ea64347" ).should.be.an.instance_of EC2::Response
41
+ response = @ec2.get_console_output( :instance_id => "i-2ea64347" )
42
+ response.instanceId.should.equal "i-28a64341"
43
+ response.timestamp.should.equal "2007-01-03 15:00:00"
44
+ end
45
+
46
+
47
+ specify "method get_console_output should raise an exception when called without nil/empty string arguments" do
48
+ lambda { @ec2.get_console_output() }.should.raise(EC2::ArgumentError)
49
+ lambda { @ec2.get_console_output(:instance_id => nil) }.should.raise(EC2::ArgumentError)
50
+ lambda { @ec2.get_console_output(:instance_id => "") }.should.raise(EC2::ArgumentError)
51
+ end
52
+
53
+
54
+ end