amazon-ec2 0.1.0 → 0.2.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.
@@ -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