rudy 0.8.5 → 0.9.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.
- data/CHANGES.txt +110 -18
- data/README.rdoc +40 -44
- data/Rudyfile +35 -50
- data/bin/rudy +88 -57
- data/bin/rudy-ec2 +2 -16
- data/bin/rudy-s3 +0 -10
- data/bin/rudy-sdb +11 -12
- data/lib/rudy.rb +59 -91
- data/lib/rudy/aws.rb +4 -45
- data/lib/rudy/aws/ec2.rb +57 -20
- data/lib/rudy/aws/ec2/address.rb +10 -11
- data/lib/rudy/aws/ec2/group.rb +10 -9
- data/lib/rudy/aws/ec2/image.rb +8 -8
- data/lib/rudy/aws/ec2/instance.rb +18 -19
- data/lib/rudy/aws/ec2/keypair.rb +14 -19
- data/lib/rudy/aws/ec2/snapshot.rb +16 -9
- data/lib/rudy/aws/ec2/volume.rb +39 -26
- data/lib/rudy/aws/ec2/zone.rb +5 -4
- data/lib/rudy/aws/s3.rb +2 -1
- data/lib/rudy/aws/sdb.rb +35 -86
- data/lib/rudy/backups.rb +24 -0
- data/lib/rudy/cli.rb +5 -131
- data/lib/rudy/cli/aws/ec2/addresses.rb +19 -27
- data/lib/rudy/cli/aws/ec2/candy.rb +45 -20
- data/lib/rudy/cli/aws/ec2/groups.rb +9 -13
- data/lib/rudy/cli/aws/ec2/images.rb +5 -133
- data/lib/rudy/cli/aws/ec2/instances.rb +25 -25
- data/lib/rudy/cli/aws/ec2/keypairs.rb +7 -11
- data/lib/rudy/cli/aws/ec2/snapshots.rb +5 -9
- data/lib/rudy/cli/aws/ec2/volumes.rb +22 -23
- data/lib/rudy/cli/aws/ec2/zones.rb +2 -3
- data/lib/rudy/cli/aws/sdb/domains.rb +5 -6
- data/lib/rudy/cli/aws/sdb/objects.rb +33 -0
- data/lib/rudy/cli/aws/sdb/select.rb +23 -0
- data/lib/rudy/cli/backups.rb +38 -0
- data/lib/rudy/cli/base.rb +104 -0
- data/lib/rudy/cli/candy.rb +1 -2
- data/lib/rudy/cli/config.rb +20 -7
- data/lib/rudy/cli/disks.rb +7 -9
- data/lib/rudy/cli/execbase.rb +56 -0
- data/lib/rudy/cli/machines.rb +242 -45
- data/lib/rudy/cli/metadata.rb +24 -10
- data/lib/rudy/cli/networks.rb +34 -0
- data/lib/rudy/cli/routines.rb +32 -6
- data/lib/rudy/cli/status.rb +60 -0
- data/lib/rudy/config.rb +55 -32
- data/lib/rudy/config/objects.rb +44 -30
- data/lib/rudy/disks.rb +25 -0
- data/lib/rudy/exceptions.rb +99 -0
- data/lib/rudy/global.rb +67 -28
- data/lib/rudy/guidelines.rb +3 -2
- data/lib/rudy/huxtable.rb +67 -58
- data/lib/rudy/machines.rb +41 -263
- data/lib/rudy/metadata.rb +212 -38
- data/lib/rudy/metadata/backup.rb +123 -78
- data/lib/rudy/metadata/disk.rb +153 -170
- data/lib/rudy/metadata/machine.rb +179 -0
- data/lib/rudy/mixins.rb +2 -1
- data/lib/rudy/mixins/hash.rb +3 -1
- data/lib/rudy/mixins/symbol.rb +8 -0
- data/lib/rudy/routines.rb +127 -344
- data/lib/rudy/routines/base.rb +229 -0
- data/lib/rudy/routines/handlers/base.rb +48 -0
- data/lib/rudy/routines/handlers/depends.rb +49 -0
- data/lib/rudy/routines/handlers/disks.rb +249 -0
- data/lib/rudy/routines/handlers/group.rb +44 -0
- data/lib/rudy/routines/handlers/host.rb +70 -0
- data/lib/rudy/routines/handlers/keypair.rb +70 -0
- data/lib/rudy/routines/handlers/machines.rb +15 -0
- data/lib/rudy/routines/handlers/script.rb +85 -0
- data/lib/rudy/routines/handlers/user.rb +45 -0
- data/lib/rudy/routines/passthrough.rb +19 -23
- data/lib/rudy/routines/reboot.rb +98 -50
- data/lib/rudy/routines/shutdown.rb +65 -14
- data/lib/rudy/routines/startup.rb +112 -17
- data/lib/rudy/utils.rb +35 -68
- data/rudy.gemspec +82 -25
- data/tryouts/01_mixins/01_hash_tryouts.rb +20 -0
- data/tryouts/10_require_time/10_rudy_tryouts.rb +33 -0
- data/tryouts/10_require_time/15_global_tryouts.rb +58 -0
- data/tryouts/12_config/10_load_config_tryouts.rb +43 -0
- data/tryouts/12_config/20_defaults_tryouts.rb +16 -0
- data/tryouts/12_config/30_accounts_tryouts.rb +17 -0
- data/tryouts/12_config/40_machines_tryouts.rb +53 -0
- data/tryouts/12_config/50_commands_tryouts.rb +17 -0
- data/tryouts/12_config/60_routines_tryouts.rb +16 -0
- data/tryouts/15_huxtable/10_huxtable_tryouts.rb +47 -0
- data/tryouts/15_huxtable/20_user_tryouts.rb +47 -0
- data/tryouts/20_simpledb/10_domains_tryouts.rb +36 -0
- data/tryouts/20_simpledb/20_objects_tryouts.rb +56 -0
- data/tryouts/25_ec2/10_keypairs_tryouts.rb +54 -0
- data/tryouts/25_ec2/20_groups_tryouts.rb +56 -0
- data/tryouts/25_ec2/21_groups_authorize_address_tryouts.rb +53 -0
- data/tryouts/25_ec2/22_groups_authorize_account_tryouts.rb +54 -0
- data/tryouts/25_ec2/30_addresses_tryouts.rb +42 -0
- data/tryouts/25_ec2/40_volumes_tryouts.rb +53 -0
- data/tryouts/25_ec2/50_snapshots_tryouts.rb +75 -0
- data/tryouts/26_ec2_instances/10_instance_tryouts.rb +107 -0
- data/tryouts/26_ec2_instances/50_images_tryouts.rb +7 -0
- data/tryouts/30_metadata/10_include_tryouts.rb +45 -0
- data/tryouts/30_metadata/13_object_tryouts.rb +19 -0
- data/tryouts/30_metadata/50_disk_tryouts.rb +115 -0
- data/tryouts/30_metadata/51_disk_digest_tryouts.rb +24 -0
- data/tryouts/30_metadata/53_disk_list_tryouts.rb +35 -0
- data/tryouts/30_metadata/56_disk_volume_tryouts.rb +68 -0
- data/tryouts/30_metadata/60_backup_tryouts.rb +101 -0
- data/tryouts/30_metadata/63_backup_list_tryouts.rb +38 -0
- data/tryouts/30_metadata/64_backup_disk_tryouts.rb +65 -0
- data/tryouts/30_metadata/66_backup_snapshot_tryouts.rb +76 -0
- data/tryouts/30_metadata/70_machine_tryouts.rb +85 -0
- data/tryouts/30_metadata/73_machine_list_tryouts.rb +58 -0
- data/tryouts/30_metadata/76_machine_instance_tryouts.rb +64 -0
- data/tryouts/30_metadata/77_machines_tryouts.rb +45 -0
- data/tryouts/40_routines/10_keypair_handler_tryouts.rb +52 -0
- data/tryouts/40_routines/11_group_handler_tryouts.rb +36 -0
- data/tryouts/80_cli/10_rudyec2_tryouts.rb +8 -0
- data/tryouts/80_cli/60_rudy_tryouts.rb +41 -0
- data/tryouts/exploration/console.rb +91 -0
- data/tryouts/exploration/machine.rb +23 -0
- data/tryouts/failer +6 -0
- metadata +116 -32
- data/bin/ird +0 -153
- data/lib/rudy/metadata/backups.rb +0 -67
- data/lib/rudy/metadata/debug.rb +0 -38
- data/lib/rudy/metadata/disks.rb +0 -67
- data/lib/rudy/metadata/objectbase.rb +0 -108
- data/lib/rudy/routines/helper.rb +0 -76
- data/lib/rudy/routines/helpers/dependshelper.rb +0 -34
- data/lib/rudy/routines/helpers/diskhelper.rb +0 -403
- data/lib/rudy/routines/helpers/scripthelper.rb +0 -197
- data/lib/rudy/routines/helpers/userhelper.rb +0 -37
- data/support/rudy-ec2-startup +0 -200
data/lib/rudy/aws/ec2/keypair.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
module Rudy::AWS
|
3
3
|
module EC2
|
4
4
|
|
5
|
-
class
|
5
|
+
class Keypair < Storable
|
6
6
|
|
7
7
|
field :name
|
8
8
|
field :fingerprint
|
@@ -25,20 +25,20 @@ module Rudy::AWS
|
|
25
25
|
|
26
26
|
end
|
27
27
|
|
28
|
-
|
29
|
-
include Rudy::AWS::
|
30
|
-
|
28
|
+
module EC2::Keypairs
|
29
|
+
include Rudy::AWS::EC2 # important! include,
|
30
|
+
extend self # then extend
|
31
31
|
|
32
32
|
def create(name)
|
33
33
|
raise "No name provided" unless name
|
34
|
-
ret =
|
35
|
-
|
34
|
+
ret = @@ec2.create_keypair(:key_name => name)
|
35
|
+
from_hash(ret)
|
36
36
|
end
|
37
37
|
|
38
38
|
def destroy(name)
|
39
|
-
name = name.name if name.is_a?(Rudy::AWS::EC2::
|
39
|
+
name = name.name if name.is_a?(Rudy::AWS::EC2::Keypair)
|
40
40
|
raise "No name provided" unless name.is_a?(String)
|
41
|
-
ret =
|
41
|
+
ret = @@ec2.delete_keypair(:key_name => name)
|
42
42
|
(ret && ret['return'] == 'true') # BUG? Always returns true
|
43
43
|
end
|
44
44
|
|
@@ -50,23 +50,24 @@ module Rudy::AWS
|
|
50
50
|
|
51
51
|
def list_as_hash(*names)
|
52
52
|
names = names.flatten
|
53
|
-
klist =
|
53
|
+
klist = @@ec2.describe_keypairs(:key_name => names)
|
54
54
|
return unless klist['keySet'].is_a?(Hash)
|
55
55
|
keypairs = {}
|
56
56
|
klist['keySet']['item'].each do |oldkp|
|
57
|
-
kp =
|
57
|
+
kp = from_hash(oldkp)
|
58
58
|
keypairs[kp.name] = kp
|
59
59
|
end
|
60
|
+
keypairs = nil if keypairs.empty?
|
60
61
|
keypairs
|
61
62
|
end
|
62
63
|
|
63
|
-
def
|
64
|
+
def from_hash(h)
|
64
65
|
# keyName: test-c5g4v3pe
|
65
66
|
# keyFingerprint: 65:d0:ce:e7:6a:b0:88:4a:9c:c7:2d:b8:33:0c:fd:3b:c8:0f:0a:3c
|
66
67
|
# keyMaterial: |-
|
67
68
|
# -----BEGIN RSA PRIVATE KEY-----
|
68
69
|
#
|
69
|
-
keypair = Rudy::AWS::EC2::
|
70
|
+
keypair = Rudy::AWS::EC2::Keypair.new
|
70
71
|
keypair.fingerprint = h['keyFingerprint']
|
71
72
|
keypair.name = h['keyName']
|
72
73
|
keypair.private_key = h['keyMaterial']
|
@@ -91,13 +92,7 @@ module Rudy::AWS
|
|
91
92
|
end
|
92
93
|
|
93
94
|
end
|
94
|
-
|
95
|
-
class Keypairs #:nodoc:
|
96
|
-
def initialize(*args)
|
97
|
-
raise "Oops! The correct class uses a capital 'P': Rudy::AWS::EC2::KeyPairs"
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
95
|
+
|
101
96
|
end
|
102
97
|
end
|
103
98
|
|
@@ -21,7 +21,7 @@ module Rudy::AWS
|
|
21
21
|
@@sformat % [liner_note, @volid, @status]
|
22
22
|
end
|
23
23
|
|
24
|
-
def
|
24
|
+
def pretty
|
25
25
|
lines = []
|
26
26
|
lines << liner_note
|
27
27
|
field_names.each do |key|
|
@@ -38,9 +38,10 @@ module Rudy::AWS
|
|
38
38
|
|
39
39
|
end
|
40
40
|
|
41
|
-
|
42
|
-
include Rudy::AWS::
|
43
|
-
|
41
|
+
module Snapshots
|
42
|
+
include Rudy::AWS::EC2 # important! include,
|
43
|
+
extend self # then extend
|
44
|
+
|
44
45
|
|
45
46
|
def list(snap_id=[])
|
46
47
|
snapshots = list_as_hash(snap_id)
|
@@ -51,25 +52,26 @@ module Rudy::AWS
|
|
51
52
|
end
|
52
53
|
def list_as_hash(snap_id=[])
|
53
54
|
snap_id = [snap_id].flatten.compact
|
54
|
-
slist =
|
55
|
+
slist = @@ec2.describe_snapshots(:snapshot_id => snap_id)
|
55
56
|
return unless slist['snapshotSet'].is_a?(Hash)
|
56
57
|
snapshots = {}
|
57
58
|
slist['snapshotSet']['item'].each do |snap|
|
58
|
-
kp = self.
|
59
|
+
kp = self.from_hash(snap)
|
59
60
|
snapshots[kp.awsid] = kp
|
60
61
|
end
|
62
|
+
snapshots = nil if snapshots.empty?
|
61
63
|
snapshots
|
62
64
|
end
|
63
65
|
|
64
66
|
def create(vol_id)
|
65
67
|
vol_id = (vol_id.is_a?(Rudy::AWS::EC2::Volume)) ? vol_id.awsid : vol_id
|
66
|
-
shash =
|
68
|
+
shash = @@ec2.create_snapshot(:volume_id => vol_id)
|
67
69
|
snap = Snapshots.from_hash(shash)
|
68
70
|
snap
|
69
71
|
end
|
70
72
|
|
71
73
|
def destroy(snap_id)
|
72
|
-
ret =
|
74
|
+
ret = @@ec2.delete_snapshot(:snapshot_id => snap_id)
|
73
75
|
(ret && ret['return'] == 'true')
|
74
76
|
end
|
75
77
|
|
@@ -99,10 +101,15 @@ module Rudy::AWS
|
|
99
101
|
list(snap_id).first || nil
|
100
102
|
end
|
101
103
|
|
102
|
-
def exists?(
|
104
|
+
def exists?(snap_id)
|
103
105
|
!get(snap_id).nil?
|
104
106
|
end
|
105
107
|
|
108
|
+
def completed?(snap_id)
|
109
|
+
s = get(snap_id)
|
110
|
+
return false if s.nil?
|
111
|
+
s.completed?
|
112
|
+
end
|
106
113
|
end
|
107
114
|
|
108
115
|
end
|
data/lib/rudy/aws/ec2/volume.rb
CHANGED
@@ -7,14 +7,19 @@ module Rudy::AWS
|
|
7
7
|
|
8
8
|
field :awsid
|
9
9
|
field :status
|
10
|
-
field :size
|
10
|
+
field :size => Integer
|
11
11
|
field :snapid
|
12
|
-
field :zone
|
13
|
-
field :
|
14
|
-
field :
|
12
|
+
field :zone => Symbol
|
13
|
+
field :created => Time
|
14
|
+
field :attached => Time
|
15
15
|
field :instid
|
16
16
|
field :device
|
17
17
|
|
18
|
+
def postprocess
|
19
|
+
@zone &&= @zone.to_sym
|
20
|
+
@size &&= @size.to_i
|
21
|
+
end
|
22
|
+
|
18
23
|
def liner_note
|
19
24
|
info = attached? ? "attached to #{@instid}" : @status
|
20
25
|
"%s (%s)" % [(self.awsid || '').bright, info]
|
@@ -26,7 +31,7 @@ module Rudy::AWS
|
|
26
31
|
line
|
27
32
|
end
|
28
33
|
|
29
|
-
def
|
34
|
+
def pretty
|
30
35
|
lines = [liner_note]
|
31
36
|
field_names.each do |n|
|
32
37
|
lines << sprintf(" %12s: %s", n, self.send(n)) if self.send(n)
|
@@ -48,10 +53,11 @@ module Rudy::AWS
|
|
48
53
|
end
|
49
54
|
|
50
55
|
|
51
|
-
|
52
|
-
include Rudy::AWS::
|
53
|
-
|
54
|
-
|
56
|
+
module Volumes
|
57
|
+
include Rudy::AWS::EC2 # important! include,
|
58
|
+
extend self # then extend
|
59
|
+
|
60
|
+
|
55
61
|
unless defined?(KNOWN_STATES)
|
56
62
|
KNOWN_STATES = [:available, :creating, :deleting, :attached, :detaching].freeze
|
57
63
|
end
|
@@ -72,11 +78,11 @@ module Rudy::AWS
|
|
72
78
|
# "availabilityZone"=>"us-east-1b",
|
73
79
|
# "createTime"=>"2009-03-17T20:10:48.000Z",
|
74
80
|
# "volumeId"=>"vol-48826421"
|
75
|
-
vol = execute_request({}) {
|
81
|
+
vol = Rudy::AWS::EC2.execute_request({}) { @@ec2.create_volume(opts) }
|
76
82
|
|
77
83
|
# TODO: use a waiter?
|
78
84
|
#Rudy.waiter(1, 30) do
|
79
|
-
# ret =
|
85
|
+
# ret = @@@ec2.volumes.available?(volume.awsid)
|
80
86
|
#end
|
81
87
|
|
82
88
|
reqid = vol['requestId']
|
@@ -86,7 +92,7 @@ module Rudy::AWS
|
|
86
92
|
def destroy(vol_id)
|
87
93
|
vol_id = Volumes.get_vol_id(vol_id)
|
88
94
|
raise VolumeNotAvailable, vol_id unless available?(vol_id)
|
89
|
-
ret = execute_request({}) {
|
95
|
+
ret = Rudy::AWS::EC2.execute_request({}) { @@ec2.delete_volume(:volume_id => vol_id) }
|
90
96
|
(ret['return'] == 'true')
|
91
97
|
end
|
92
98
|
|
@@ -103,7 +109,7 @@ module Rudy::AWS
|
|
103
109
|
:instance_id => inst_id,
|
104
110
|
:device => device.to_s # Solaris devices are numbers
|
105
111
|
}
|
106
|
-
ret = execute_request(false) {
|
112
|
+
ret = Rudy::AWS::EC2.execute_request(false) { @@ec2.attach_volume(opts) }
|
107
113
|
(ret['status'] == 'attaching')
|
108
114
|
end
|
109
115
|
|
@@ -111,16 +117,20 @@ module Rudy::AWS
|
|
111
117
|
vol_id = Volumes.get_vol_id(vol_id)
|
112
118
|
raise NoVolumeID unless vol_id
|
113
119
|
raise VolumeNotAttached, vol_id unless attached?(vol_id)
|
114
|
-
ret = execute_request({}) {
|
120
|
+
ret = Rudy::AWS::EC2.execute_request({}) {
|
121
|
+
@@ec2.detach_volume(:volume_id => vol_id)
|
122
|
+
}
|
115
123
|
(ret['status'] == 'detaching')
|
116
124
|
end
|
117
125
|
|
118
126
|
|
119
|
-
def list(state=nil, vol_id=[])
|
120
|
-
list_as_hash(state, vol_id)
|
127
|
+
def list(state=nil, vol_id=[], &each_vol)
|
128
|
+
volumes = list_as_hash(state, vol_id, &each_vol)
|
129
|
+
volumes &&= volumes.values
|
130
|
+
volumes
|
121
131
|
end
|
122
132
|
|
123
|
-
def list_as_hash(state=nil, vol_id=[])
|
133
|
+
def list_as_hash(state=nil, vol_id=[], &each_vol)
|
124
134
|
state &&= state.to_sym
|
125
135
|
state = nil if state == :any
|
126
136
|
# A nil state is fine, but we don't want an unknown one!
|
@@ -130,7 +140,9 @@ module Rudy::AWS
|
|
130
140
|
:volume_id => vol_id ? [vol_id].flatten : []
|
131
141
|
}
|
132
142
|
|
133
|
-
vlist = execute_request({}) {
|
143
|
+
vlist = Rudy::AWS::EC2.execute_request({}) {
|
144
|
+
@@ec2.describe_volumes(opts)
|
145
|
+
}
|
134
146
|
|
135
147
|
volumes = {}
|
136
148
|
return volumes unless vlist['volumeSet'].is_a?(Hash)
|
@@ -139,16 +151,21 @@ module Rudy::AWS
|
|
139
151
|
next if state && v.state != state.to_s
|
140
152
|
volumes[v.awsid] = v
|
141
153
|
end
|
154
|
+
volumes.values.each { |v| each_vol.call(v) } if each_vol
|
155
|
+
volumes = nil if volumes.empty?
|
142
156
|
volumes
|
143
157
|
end
|
144
158
|
|
145
159
|
def any?(state=nil,vol_id=[])
|
146
|
-
|
160
|
+
vols = list(state, vol_id)
|
161
|
+
!vols.nil?
|
147
162
|
end
|
148
163
|
|
149
164
|
def exists?(vol_id)
|
150
165
|
vol_id = Volumes.get_vol_id(vol_id)
|
151
166
|
vol = get(vol_id)
|
167
|
+
return false if vol.nil?
|
168
|
+
return false if vol.deleting?
|
152
169
|
!vol.nil?
|
153
170
|
end
|
154
171
|
|
@@ -195,14 +212,15 @@ module Rudy::AWS
|
|
195
212
|
vol.snapid = h['snapshotId']
|
196
213
|
vol.zone = h['availabilityZone']
|
197
214
|
vol.awsid = h['volumeId']
|
198
|
-
vol.
|
215
|
+
vol.created = h['createTime']
|
199
216
|
if h['attachmentSet'].is_a?(Hash)
|
200
217
|
item = h['attachmentSet']['item'].first
|
201
218
|
vol.status = item['status'] # Overwrite "available status". Possibly a bad idea.
|
202
219
|
vol.device = item['device']
|
203
|
-
vol.
|
220
|
+
vol.attached = item['attachTime']
|
204
221
|
vol.instid = item['instanceId']
|
205
222
|
end
|
223
|
+
vol.postprocess
|
206
224
|
vol
|
207
225
|
end
|
208
226
|
|
@@ -223,8 +241,3 @@ module Rudy::AWS
|
|
223
241
|
end
|
224
242
|
end
|
225
243
|
|
226
|
-
|
227
|
-
class Rudy::AWS::EC2::Volumes
|
228
|
-
|
229
|
-
|
230
|
-
end
|
data/lib/rudy/aws/ec2/zone.rb
CHANGED
@@ -19,9 +19,9 @@ module Rudy::AWS
|
|
19
19
|
|
20
20
|
end
|
21
21
|
|
22
|
-
|
23
|
-
include Rudy::AWS::
|
24
|
-
|
22
|
+
module Zones
|
23
|
+
include Rudy::AWS::EC2 # important! include,
|
24
|
+
extend self # then extend
|
25
25
|
|
26
26
|
def list(*names)
|
27
27
|
zones = list_as_hash(names)
|
@@ -31,13 +31,14 @@ module Rudy::AWS
|
|
31
31
|
|
32
32
|
def list_as_hash(*names)
|
33
33
|
names = names.flatten
|
34
|
-
zlist =
|
34
|
+
zlist = @@ec2.describe_availability_zones(:zone_name => names)
|
35
35
|
return unless zlist['availabilityZoneInfo'].is_a?(Hash)
|
36
36
|
zones = {}
|
37
37
|
zlist['availabilityZoneInfo']['item'].each do |zhash|
|
38
38
|
zon = Zones.from_hash(zhash)
|
39
39
|
zones[zon.name] = zon
|
40
40
|
end
|
41
|
+
zones = nil if zones.empty?
|
41
42
|
zones
|
42
43
|
end
|
43
44
|
|
data/lib/rudy/aws/s3.rb
CHANGED
@@ -3,7 +3,8 @@ module Rudy::AWS
|
|
3
3
|
class S3
|
4
4
|
|
5
5
|
def initialize(access_key=nil, secret_key=nil, region=nil, debug=nil)
|
6
|
-
|
6
|
+
require 'aws/s3'
|
7
|
+
|
7
8
|
url ||= 'http://sdb.amazonaws.com'
|
8
9
|
# There is a bug with passing :server to EC2::Base.new so
|
9
10
|
# we'll use the environment variable for now.
|
data/lib/rudy/aws/sdb.rb
CHANGED
@@ -13,7 +13,6 @@ module Rudy
|
|
13
13
|
class SDB
|
14
14
|
class NoAccessKey < RuntimeError; end
|
15
15
|
class NoSecretKey < RuntimeError; end
|
16
|
-
include Rudy::AWS::ObjectBase
|
17
16
|
|
18
17
|
require 'rudy/aws/sdb/error'
|
19
18
|
|
@@ -33,7 +32,7 @@ module Rudy
|
|
33
32
|
@base_url = url
|
34
33
|
@debug = debug || StringIO.new
|
35
34
|
end
|
36
|
-
|
35
|
+
|
37
36
|
def list_domains(max = nil, token = nil)
|
38
37
|
params = { 'Action' => 'ListDomains' }
|
39
38
|
params['NextToken'] =
|
@@ -63,12 +62,11 @@ module Rudy
|
|
63
62
|
end
|
64
63
|
|
65
64
|
|
66
|
-
# Takes a
|
65
|
+
# Takes a Hash of criteria.
|
67
66
|
# Returns a string suitable for a SimpleDB Select
|
68
|
-
def self.generate_select(
|
69
|
-
q = args.first.is_a?(Hash)? args.first : Hash[*args.flatten]
|
67
|
+
def self.generate_select(domain, fields={})
|
70
68
|
query = []
|
71
|
-
|
69
|
+
fields.each_pair do |n,v|
|
72
70
|
query << "#{Rudy::AWS.escape n}='#{Rudy::AWS.escape v}'"
|
73
71
|
end
|
74
72
|
str = "select * from #{domain} "
|
@@ -76,18 +74,6 @@ module Rudy
|
|
76
74
|
str
|
77
75
|
end
|
78
76
|
|
79
|
-
|
80
|
-
# Takes a zipped Array or Hash of criteria.
|
81
|
-
# Returns a string suitable for a SimpleDB Query
|
82
|
-
def self.generate_query(*args)
|
83
|
-
q = args.first.is_a?(Hash)? args.first : Hash[*args.flatten]
|
84
|
-
query = []
|
85
|
-
q.each do |n,v|
|
86
|
-
query << "['#{Rudy::AWS.escape n}'='#{Rudy::AWS.escape v}']"
|
87
|
-
end
|
88
|
-
query.join(" intersection ")
|
89
|
-
end
|
90
|
-
|
91
77
|
|
92
78
|
def select(select, token = nil)
|
93
79
|
params = {
|
@@ -122,72 +108,6 @@ module Rudy
|
|
122
108
|
hash_results.empty? ? nil : hash_results
|
123
109
|
end
|
124
110
|
|
125
|
-
# <QueryResult><ItemName>in-c2ffrw</ItemName><ItemName>in-72yagt</ItemName><ItemName>in-52j8gj</ItemName>
|
126
|
-
def query(domain, query, max = nil, token = nil)
|
127
|
-
params = {
|
128
|
-
'Action' => 'Query',
|
129
|
-
'QueryExpression' => query,
|
130
|
-
'DomainName' => domain.to_s
|
131
|
-
}
|
132
|
-
params['NextToken'] =
|
133
|
-
token unless token.nil? || token.empty?
|
134
|
-
params['MaxNumberOfItems'] =
|
135
|
-
max.to_s unless max.nil? || max.to_i == 0
|
136
|
-
|
137
|
-
|
138
|
-
doc = call(:get, params)
|
139
|
-
results = []
|
140
|
-
if doc
|
141
|
-
REXML::XPath.each(doc, '//ItemName/text()') do |item|
|
142
|
-
results << item.to_s
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
#return results, REXML::XPath.first(doc, '//NextToken/text()').to_s
|
147
|
-
results.empty? ? nil : results
|
148
|
-
|
149
|
-
end
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
# <QueryWithAttributesResult><Item><Name>in-c2ffrw</Name><Attribute><Name>code</Name><Value>in-c2ffrw</Value></Attribute><Attribute><Name>date_created</Name><Value>2008-10-31</Value></Attribute></Item><Item>
|
154
|
-
def query_with_attributes(domain, query, max = nil, token = nil)
|
155
|
-
params = {
|
156
|
-
'Action' => 'QueryWithAttributes',
|
157
|
-
'QueryExpression' => query,
|
158
|
-
'DomainName' => domain.to_s
|
159
|
-
}
|
160
|
-
params['NextToken'] =
|
161
|
-
token unless token.nil? || token.empty?
|
162
|
-
params['MaxNumberOfItems'] =
|
163
|
-
max.to_s unless max.nil? || max.to_i == 0
|
164
|
-
|
165
|
-
doc = call(:get, params)
|
166
|
-
results = []
|
167
|
-
if doc
|
168
|
-
REXML::XPath.each(doc, "//Item") do |item|
|
169
|
-
name = REXML::XPath.first(item, './Name/text()').to_s
|
170
|
-
|
171
|
-
attributes = {'Name' => name}
|
172
|
-
REXML::XPath.each(item, "./Attribute") do |attr|
|
173
|
-
key = REXML::XPath.first(attr, './Name/text()').to_s
|
174
|
-
value = REXML::XPath.first(attr, './Value/text()').to_s
|
175
|
-
( attributes[key] ||= [] ) << value
|
176
|
-
end
|
177
|
-
results << attributes
|
178
|
-
end
|
179
|
-
#return results, REXML::XPath.first(doc, '//NextToken/text()').to_s
|
180
|
-
end
|
181
|
-
|
182
|
-
hash_results = {}
|
183
|
-
results.each do |item|
|
184
|
-
hash_results[item.delete('Name')] = item
|
185
|
-
end
|
186
|
-
|
187
|
-
hash_results
|
188
|
-
end
|
189
|
-
|
190
|
-
|
191
111
|
|
192
112
|
def put_attributes(domain, item, attributes, replace = true)
|
193
113
|
replace = true if replace == :replace
|
@@ -252,7 +172,35 @@ module Rudy
|
|
252
172
|
|
253
173
|
|
254
174
|
protected
|
175
|
+
|
176
|
+
|
177
|
+
# Execute AWS requests safely. This will trap errors and return
|
178
|
+
# a default value (if specified).
|
179
|
+
# * +default+ A default response value
|
180
|
+
# * +request+ A block which contains the AWS request
|
181
|
+
# Returns the return value from the request is returned untouched
|
182
|
+
# or the default value on error or if the request returned nil.
|
183
|
+
def execute_request(default=nil, timeout=nil, &request)
|
184
|
+
timeout ||= 15
|
185
|
+
raise "No block provided" unless request
|
186
|
+
response = nil
|
187
|
+
begin
|
188
|
+
Timeout::timeout(timeout) do
|
189
|
+
response = request.call
|
190
|
+
end
|
255
191
|
|
192
|
+
rescue Timeout::Error => ex
|
193
|
+
STDERR.puts "Timeout (#{timeout}): #{ex.message}!"
|
194
|
+
rescue SocketError => ex
|
195
|
+
#STDERR.puts ex.message
|
196
|
+
#STDERR.puts ex.backtrace
|
197
|
+
raise SocketError, "Check your Internets!" unless Rudy::Huxtable.global.offline
|
198
|
+
ensure
|
199
|
+
response ||= default
|
200
|
+
end
|
201
|
+
response
|
202
|
+
end
|
203
|
+
|
256
204
|
def call(method, params)
|
257
205
|
params.merge!( {
|
258
206
|
'Version' => '2007-11-07',
|
@@ -276,7 +224,8 @@ module Rudy
|
|
276
224
|
query = query.join('&')
|
277
225
|
url = "#{@base_url}?#{query}"
|
278
226
|
uri = URI.parse(url)
|
279
|
-
|
227
|
+
|
228
|
+
#Rudy::Huxtable.ld url if Rudy.debug?
|
280
229
|
|
281
230
|
response = execute_request(nil) {
|
282
231
|
Net::HTTP.new(uri.host, uri.port).send_request(method, uri.request_uri)
|
@@ -294,7 +243,7 @@ module Rudy
|
|
294
243
|
error = doc.get_elements('*/Errors/Error')[0]
|
295
244
|
raise(
|
296
245
|
Module.class_eval(
|
297
|
-
"
|
246
|
+
"Rudy::AWS::SDB::#{error.get_elements('Code')[0].text}Error"
|
298
247
|
).new(
|
299
248
|
error.get_elements('Message')[0].text,
|
300
249
|
doc.get_elements('*/RequestID')[0].text
|