internuity-awsum 0.2 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/Rakefile +2 -1
  2. data/lib/awsum.rb +1 -1
  3. data/lib/ec2/address.rb +118 -0
  4. data/lib/ec2/availability_zone.rb +68 -0
  5. data/lib/ec2/keypair.rb +75 -0
  6. data/lib/ec2/region.rb +96 -0
  7. data/lib/ec2/security_group.rb +175 -0
  8. data/lib/error.rb +55 -0
  9. data/lib/net_fix.rb +100 -0
  10. data/lib/requestable.rb +2 -0
  11. data/lib/s3/bucket.rb +66 -0
  12. data/lib/s3/headers.rb +24 -0
  13. data/lib/s3/object.rb +138 -0
  14. data/lib/s3/s3.rb +219 -0
  15. data/test/fixtures/ec2/addresses.xml +10 -0
  16. data/test/fixtures/ec2/allocate_address.xml +5 -0
  17. data/test/fixtures/ec2/associate_address.xml +5 -0
  18. data/test/fixtures/ec2/authorize_ip_access.xml +5 -0
  19. data/test/fixtures/ec2/authorize_owner_group_access.xml +5 -0
  20. data/test/fixtures/ec2/authorize_owner_group_access_error.xml +2 -0
  21. data/test/fixtures/ec2/availability_zones.xml +16 -0
  22. data/test/fixtures/ec2/create_key_pair.xml +29 -0
  23. data/test/fixtures/ec2/create_security_group.xml +5 -0
  24. data/test/fixtures/ec2/delete_key_pair.xml +5 -0
  25. data/test/fixtures/ec2/delete_security_group.xml +5 -0
  26. data/test/fixtures/ec2/deregister_image.xml +5 -0
  27. data/test/fixtures/ec2/disassociate_address.xml +5 -0
  28. data/test/fixtures/ec2/internal_error.xml +2 -0
  29. data/test/fixtures/ec2/invalid_amiid_error.xml +2 -0
  30. data/test/fixtures/ec2/invalid_request_error.xml +2 -0
  31. data/test/fixtures/ec2/key_pairs.xml +10 -0
  32. data/test/fixtures/ec2/regions.xml +14 -0
  33. data/test/fixtures/ec2/register_image.xml +5 -0
  34. data/test/fixtures/ec2/release_address.xml +5 -0
  35. data/test/fixtures/ec2/revoke_ip_access.xml +5 -0
  36. data/test/fixtures/ec2/revoke_owner_group_access.xml +5 -0
  37. data/test/fixtures/ec2/security_groups.xml +159 -0
  38. data/test/fixtures/ec2/unassociated_address.xml +10 -0
  39. data/test/fixtures/s3/buckets.xml +2 -0
  40. data/test/fixtures/s3/copy_failure.xml +23 -0
  41. data/test/fixtures/s3/invalid_request_signature.xml +5 -0
  42. data/test/fixtures/s3/keys.xml +2 -0
  43. data/test/units/ec2/test_addresses.rb +60 -0
  44. data/test/units/ec2/test_keypair.rb +87 -0
  45. data/test/units/ec2/test_regions.rb +33 -0
  46. data/test/units/ec2/test_security_group.rb +105 -0
  47. data/test/units/s3/test_bucket.rb +58 -0
  48. data/test/units/s3/test_object.rb +111 -0
  49. data/test/units/s3/test_s3.rb +298 -0
  50. data/test/units/test_error.rb +101 -0
  51. data/test/units/test_requestable.rb +241 -0
  52. data/test/work_out_string_to_sign.rb +7 -0
  53. metadata +132 -43
data/Rakefile CHANGED
@@ -54,7 +54,8 @@ spec = Gem::Specification.new do |s|
54
54
  s.files = FileList["README*",
55
55
  "LICENSE",
56
56
  "Rakefile",
57
- "{lib,test}/**/*"].to_a
57
+ "{lib,test}/**/*",
58
+ "{lib,test}/*"].to_a
58
59
  s.require_path = "lib"
59
60
  s.test_files = FileList["test/**/test_*.rb"].to_a + FileList["test/fixtures/**/*.xml"].to_a
60
61
  s.rubyforge_project = "awsum"
@@ -15,7 +15,7 @@ require 's3/s3'
15
15
 
16
16
  module Awsum
17
17
 
18
- VERSION = "0.1"
18
+ VERSION = "0.3"
19
19
 
20
20
  API_VERSION = '2008-12-01'
21
21
  SIGNATURE_VERSION = 2
@@ -0,0 +1,118 @@
1
+ module Awsum
2
+ class Ec2
3
+ class Address
4
+ attr_reader :public_ip, :instance_id
5
+
6
+ def initialize(ec2, public_ip, instance_id) #:nodoc:
7
+ @ec2 = ec2
8
+ @public_ip = public_ip
9
+ @instance_id = instance_id
10
+ end
11
+
12
+ # Get the Instance associated with this address.
13
+ #
14
+ # Returns nil if no instance is associated.
15
+ def instance
16
+ @ec2.instance(@instance_id) if @instance_id
17
+ end
18
+
19
+ # Will associate this address with an instance
20
+ #
21
+ # Raises an error if the address is already associated with an instance
22
+ def associate(instance_id)
23
+ if @instance_id.nil?
24
+ @ec2.associate_address instance_id, @public_ip
25
+ else
26
+ raise 'Cannot associate with an already associated instance' #FIXME: Write a better Awsum error here'
27
+ end
28
+ end
29
+
30
+ # Will disassociate this address from it's instance
31
+ #
32
+ # Raises an error if the address is not associated with an instance
33
+ def disassociate
34
+ if @instance_id.nil?
35
+ raise 'Not associated' #FIXME: Write a better Awsum error here'
36
+ else
37
+ result = @ec2.disassociate_address @public_ip
38
+ @instance_id = nil
39
+ result
40
+ end
41
+ end
42
+
43
+ # Will release this address
44
+ #
45
+ # Raises an error if the address is associated with an instance
46
+ def release
47
+ if @instance_id.nil?
48
+ @ec2.release_address @public_ip
49
+ else
50
+ raise 'Associated with an instance' #FIXME: Write a better Awsum error here'
51
+ end
52
+ end
53
+
54
+ # Will release this address regardless of whether it is associated with an instance or not.
55
+ def release!
56
+ @ec2.release_address! @public_ip
57
+ end
58
+ end
59
+
60
+ class AddressParser < Awsum::Parser #:nodoc:
61
+ def initialize(ec2)
62
+ @ec2 = ec2
63
+ @addresses = []
64
+ @text = nil
65
+ @stack = []
66
+ end
67
+
68
+ def tag_start(tag, attributes)
69
+ #Quick hack so we can use the same parser for AllocateAddress which doesn't use the item tag to wrap the address information
70
+ if tag == 'AllocateAddressResponse'
71
+ @stack << 'addressesSet'
72
+ end
73
+
74
+ case tag
75
+ when 'addressesSet'
76
+ @stack << 'addressesSet'
77
+ when 'item', 'AllocateAddressResponse'
78
+ case @stack[-1]
79
+ when 'addressesSet'
80
+ @current = {}
81
+ end
82
+ end
83
+ @text = ''
84
+ end
85
+
86
+ def text(text)
87
+ @text << text unless @text.nil?
88
+ end
89
+
90
+ def tag_end(tag)
91
+ case tag
92
+ when 'DescribeAddressesResponse'
93
+ #no-op
94
+ when 'addressesSet'
95
+ @stack.pop
96
+ when 'item', 'AllocateAddressResponse'
97
+ case @stack[-1]
98
+ when 'addressesSet'
99
+ @addresses << Address.new(
100
+ @ec2,
101
+ @current['publicIp'],
102
+ @current['instanceId']
103
+ )
104
+ end
105
+ else
106
+ unless @text.nil? || @current.nil?
107
+ text = @text.strip
108
+ @current[tag] = (text == '' ? nil : text)
109
+ end
110
+ end
111
+ end
112
+
113
+ def result
114
+ @addresses
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,68 @@
1
+ module Awsum
2
+ class Ec2
3
+ class AvailabilityZone
4
+ attr_reader :name, :state, :availability_zone_name
5
+
6
+ def initialize(ec2, name, state, availability_zone_name) #:nodoc:
7
+ @ec2 = ec2
8
+ @name = name
9
+ @state = state
10
+ @availability_zone_name = availability_zone_name
11
+ end
12
+ end
13
+
14
+ class AvailabilityZoneParser < Awsum::Parser #:nodoc:
15
+ def initialize(ec2)
16
+ @ec2 = ec2
17
+ @availability_zones = []
18
+ @text = nil
19
+ @stack = []
20
+ end
21
+
22
+ def tag_start(tag, attributes)
23
+ case tag
24
+ when 'availabilityZoneInfo'
25
+ @stack << 'availabilityZoneInfo'
26
+ when 'item'
27
+ case @stack[-1]
28
+ when 'availabilityZoneInfo'
29
+ @current = {}
30
+ end
31
+ end
32
+ @text = ''
33
+ end
34
+
35
+ def text(text)
36
+ @text << text unless @text.nil?
37
+ end
38
+
39
+ def tag_end(tag)
40
+ case tag
41
+ when 'DescribeAvailabilityZonesResponse', 'requestId'
42
+ #no-op
43
+ when 'availabilityZoneInfo'
44
+ @stack.pop
45
+ when 'item'
46
+ case @stack[-1]
47
+ when 'availabilityZoneInfo'
48
+ @availability_zones << AvailabilityZone.new(
49
+ @ec2,
50
+ @current['zoneName'],
51
+ @current['zoneState'],
52
+ @current['regionName']
53
+ )
54
+ end
55
+ else
56
+ unless @text.nil? || @current.nil?
57
+ text = @text.strip
58
+ @current[tag] = (text == '' ? nil : text)
59
+ end
60
+ end
61
+ end
62
+
63
+ def result
64
+ @availability_zones
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,75 @@
1
+ module Awsum
2
+ class Ec2
3
+ class KeyPair
4
+ attr_reader :name, :fingerprint, :material
5
+
6
+ def initialize(ec2, name, fingerprint, material)
7
+ @ec2 = ec2
8
+ @name = name
9
+ @fingerprint = fingerprint
10
+ @material = material
11
+ end
12
+ end
13
+
14
+ class KeyPairParser < Awsum::Parser #:nodoc:
15
+ def initialize(ec2)
16
+ @ec2 = ec2
17
+ @key_pairs = []
18
+ @text = nil
19
+ @stack = []
20
+ end
21
+
22
+ def tag_start(tag, attributes)
23
+ #Quick hack so we can use the same parser for CreateKeyPair which doesn't use the item tag to wrap the key pair information
24
+ if tag == 'CreateKeyPairResponse'
25
+ @stack << 'keySet'
26
+ end
27
+
28
+ case tag
29
+ when 'keySet'
30
+ @stack << 'keySet'
31
+ when 'item', 'CreateKeyPairResponse'
32
+ case @stack[-1]
33
+ when 'keySet'
34
+ @current = {}
35
+ @text = ''
36
+ end
37
+ end
38
+ end
39
+
40
+ def text(text)
41
+ @text << text unless @text.nil?
42
+ end
43
+
44
+ def tag_end(tag)
45
+ case tag
46
+ when 'DescribeKeyPairsResponse'
47
+ #no-op
48
+ when 'keySet'
49
+ @stack.pop
50
+ when 'item', 'CreateKeyPairResponse'
51
+ case @stack[-1]
52
+ when 'keySet'
53
+ @key_pairs << KeyPair.new(
54
+ @ec2,
55
+ @current['keyName'],
56
+ @current['keyFingerprint'],
57
+ @current['keyMaterial']
58
+ )
59
+ @text = ''
60
+ end
61
+ else
62
+ unless @text.nil?
63
+ text = @text.strip
64
+ @current[tag] = (text == '' ? nil : text)
65
+ @text = ''
66
+ end
67
+ end
68
+ end
69
+
70
+ def result
71
+ @key_pairs
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,96 @@
1
+ module Awsum
2
+ class Ec2
3
+ class Region
4
+ attr_reader :name, :end_point
5
+
6
+ def initialize(ec2, name, end_point) #:nodoc:
7
+ @ec2 = ec2
8
+ @name = name
9
+ @end_point = end_point
10
+ end
11
+
12
+ # List the AvailabilityZone(s) of this Region
13
+ def availability_zones
14
+ @ec2.availability_zones
15
+ end
16
+
17
+ # Operate all Awsum::Ec2 methods against this Region
18
+ #
19
+ # ====Example
20
+ #
21
+ # ec2.region('eu-west-1').use do
22
+ # #Runs an instance within the eu-west-1 region
23
+ # instance = run_instances('i-ABCDEF')
24
+ # end
25
+ def use(&block)
26
+ old_host = @ec2.host
27
+ @ec2.host = end_point
28
+ if block
29
+ block.arity < 1 ? instance_eval(&block) : block[self]
30
+ end
31
+ @ec2.host = old_host
32
+ self
33
+ end
34
+
35
+ private
36
+ #--
37
+ # Will pass all missing methods onto the ec2 object
38
+ def method_missing(method_name, *args, &block)
39
+ @ec2.send(method_name, *args, &block)
40
+ end
41
+ end
42
+
43
+ class RegionParser < Awsum::Parser #:nodoc:
44
+ def initialize(ec2)
45
+ @ec2 = ec2
46
+ @regions = []
47
+ @text = nil
48
+ @stack = []
49
+ end
50
+
51
+ def tag_start(tag, attributes)
52
+ case tag
53
+ when 'regionInfo'
54
+ @stack << 'regionInfo'
55
+ when 'item'
56
+ case @stack[-1]
57
+ when 'regionInfo'
58
+ @current = {}
59
+ end
60
+ end
61
+ @text = ''
62
+ end
63
+
64
+ def text(text)
65
+ @text << text unless @text.nil?
66
+ end
67
+
68
+ def tag_end(tag)
69
+ case tag
70
+ when 'DescribeRegionsResponse', 'requestId'
71
+ #no-op
72
+ when 'regionInfo'
73
+ @stack.pop
74
+ when 'item'
75
+ case @stack[-1]
76
+ when 'regionInfo'
77
+ @regions << Region.new(
78
+ @ec2,
79
+ @current['regionName'],
80
+ @current['regionEndpoint']
81
+ )
82
+ end
83
+ else
84
+ unless @text.nil? || @current.nil?
85
+ text = @text.strip
86
+ @current[tag] = (text == '' ? nil : text)
87
+ end
88
+ end
89
+ end
90
+
91
+ def result
92
+ @regions
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,175 @@
1
+ module Awsum
2
+ class Ec2
3
+ class SecurityGroup
4
+ attr_reader :name, :description, :owner_id, :ip_permissions, :group_permissions
5
+
6
+ def initialize(ec2, name, description, owner_id, ip_permissions, group_permissions)
7
+ @ec2 = ec2
8
+ @name = name
9
+ @description = description
10
+ @owner_id = owner_id
11
+ @ip_permissions = ip_permissions
12
+ @group_permissions = group_permissions
13
+ end
14
+
15
+ # Authorize access for a group
16
+ def authorize_group(group_name, owner_id)
17
+ @ec2.authorize_security_group_ingress(@name, :source_security_group_name => group_name, :source_security_group_owner_id => owner_id)
18
+ end
19
+
20
+ # Revoke access for a group
21
+ def revoke_group(group_name, owner_id)
22
+ @ec2.revoke_security_group_ingress(@name, :source_security_group_name => group_name, :source_security_group_owner_id => owner_id)
23
+ end
24
+
25
+ # Authorize access for an ip address
26
+ def authorize_ip(from_port, to_port, protocol = 'tcp', cidr_ip = '0.0.0.0/0')
27
+ @ec2.authorize_security_group_ingress(@name, :ip_protocol => protocol, :from_port => from_port, :to_port => to_port, :cidr_ip => cidr_ip)
28
+ end
29
+
30
+ # Revoke access from an ip address
31
+ def revoke_ip(from_port, to_port, protocol = 'tcp', cidr_ip = '0.0.0.0/0')
32
+ @ec2.revoke_security_group_ingress(@name, :ip_protocol => protocol, :from_port => from_port, :to_port => to_port, :cidr_ip => cidr_ip)
33
+ end
34
+
35
+ # Delete this SecurityGroup
36
+ def delete
37
+ @ec2.delete_security_group(@name)
38
+ end
39
+
40
+ private
41
+ class Permission #:nodoc:
42
+ attr_reader :protocol, :from_port, :to_port
43
+
44
+ def initialize(protocol, from_port, to_port)
45
+ @protocol = protocol
46
+ @from_port = from_port.to_i
47
+ @to_port = to_port.to_i
48
+ end
49
+ end
50
+
51
+ protected
52
+ class IpPermission < Permission
53
+ attr_reader :ip
54
+
55
+ def initialize(protocol, from_port, to_port, ip)
56
+ super(protocol, from_port, to_port)
57
+ @ip = ip
58
+ end
59
+ end
60
+
61
+ class GroupPermission < Permission
62
+ attr_reader :group, :user_id
63
+
64
+ def initialize(protocol, from_port, to_port, group, user_id)
65
+ super(protocol, from_port, to_port)
66
+ @group = group
67
+ @user_id = user_id
68
+ end
69
+ end
70
+ end
71
+
72
+ class SecurityGroupParser < Awsum::Parser #:nodoc:
73
+ def initialize(ec2)
74
+ @ec2 = ec2
75
+ @security_groups = []
76
+ @text = nil
77
+ @stack = []
78
+ @group_permissions = []
79
+ @ip_permissions = []
80
+ end
81
+
82
+ def tag_start(tag, attributes)
83
+ case tag
84
+ when 'securityGroupInfo'
85
+ @stack << 'securityGroupInfo'
86
+ when 'ipPermissions'
87
+ @stack << 'ipPermissions'
88
+ when 'groups'
89
+ @stack << 'groups'
90
+ when 'ipRanges'
91
+ @stack << 'ipRanges'
92
+ when 'item'
93
+ case @stack[-1]
94
+ when 'securityGroupInfo'
95
+ @current = {}
96
+ @group_permissions = []
97
+ @ip_permissions = []
98
+ @text = ''
99
+ when 'ipPermissions'
100
+ @permissions = {}
101
+ @text = ''
102
+ when 'groups'
103
+ @group_info = {}
104
+ @text = ''
105
+ when 'ipRanges'
106
+ @ip_info = {}
107
+ @text = ''
108
+ end
109
+ end
110
+ end
111
+
112
+ def text(text)
113
+ @text << text unless @text.nil?
114
+ end
115
+
116
+ def tag_end(tag)
117
+ case tag
118
+ when 'DescribeSecurityGroupsResponse', 'requestId'
119
+ #no-op
120
+ when 'securityGroupInfo', 'ipPermissions', 'groups', 'ipRanges'
121
+ @stack.pop
122
+ when 'item'
123
+ case @stack[-1]
124
+ when 'securityGroupInfo'
125
+ @security_groups << SecurityGroup.new(
126
+ @ec2,
127
+ @current['groupName'],
128
+ @current['groupDescription'],
129
+ @current['ownerId'],
130
+ @ip_permissions,
131
+ @group_permissions
132
+ )
133
+ @text = ''
134
+ when 'groups'
135
+ @group_permissions << SecurityGroup::GroupPermission.new(
136
+ @permissions['ipProtocol'],
137
+ @permissions['fromPort'],
138
+ @permissions['toPort'],
139
+ @group_info['groupName'],
140
+ @group_info['userId']
141
+ )
142
+ when 'ipRanges'
143
+ @ip_permissions << SecurityGroup::IpPermission.new(
144
+ @permissions['ipProtocol'],
145
+ @permissions['fromPort'],
146
+ @permissions['toPort'],
147
+ @ip_info['cidrIp']
148
+ )
149
+ end
150
+ else
151
+ unless @text.nil?
152
+ text = @text.strip
153
+ text = (text == '' ? nil : text)
154
+
155
+ case @stack[-1]
156
+ when 'securityGroupInfo'
157
+ @current[tag] = text
158
+ when 'ipPermissions'
159
+ @permissions[tag] = text
160
+ when 'groups'
161
+ @group_info[tag] = text
162
+ when 'ipRanges'
163
+ @ip_info[tag] = text
164
+ end
165
+ @text = ''
166
+ end
167
+ end
168
+ end
169
+
170
+ def result
171
+ @security_groups
172
+ end
173
+ end
174
+ end
175
+ end