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.
Files changed (132) hide show
  1. data/CHANGES.txt +110 -18
  2. data/README.rdoc +40 -44
  3. data/Rudyfile +35 -50
  4. data/bin/rudy +88 -57
  5. data/bin/rudy-ec2 +2 -16
  6. data/bin/rudy-s3 +0 -10
  7. data/bin/rudy-sdb +11 -12
  8. data/lib/rudy.rb +59 -91
  9. data/lib/rudy/aws.rb +4 -45
  10. data/lib/rudy/aws/ec2.rb +57 -20
  11. data/lib/rudy/aws/ec2/address.rb +10 -11
  12. data/lib/rudy/aws/ec2/group.rb +10 -9
  13. data/lib/rudy/aws/ec2/image.rb +8 -8
  14. data/lib/rudy/aws/ec2/instance.rb +18 -19
  15. data/lib/rudy/aws/ec2/keypair.rb +14 -19
  16. data/lib/rudy/aws/ec2/snapshot.rb +16 -9
  17. data/lib/rudy/aws/ec2/volume.rb +39 -26
  18. data/lib/rudy/aws/ec2/zone.rb +5 -4
  19. data/lib/rudy/aws/s3.rb +2 -1
  20. data/lib/rudy/aws/sdb.rb +35 -86
  21. data/lib/rudy/backups.rb +24 -0
  22. data/lib/rudy/cli.rb +5 -131
  23. data/lib/rudy/cli/aws/ec2/addresses.rb +19 -27
  24. data/lib/rudy/cli/aws/ec2/candy.rb +45 -20
  25. data/lib/rudy/cli/aws/ec2/groups.rb +9 -13
  26. data/lib/rudy/cli/aws/ec2/images.rb +5 -133
  27. data/lib/rudy/cli/aws/ec2/instances.rb +25 -25
  28. data/lib/rudy/cli/aws/ec2/keypairs.rb +7 -11
  29. data/lib/rudy/cli/aws/ec2/snapshots.rb +5 -9
  30. data/lib/rudy/cli/aws/ec2/volumes.rb +22 -23
  31. data/lib/rudy/cli/aws/ec2/zones.rb +2 -3
  32. data/lib/rudy/cli/aws/sdb/domains.rb +5 -6
  33. data/lib/rudy/cli/aws/sdb/objects.rb +33 -0
  34. data/lib/rudy/cli/aws/sdb/select.rb +23 -0
  35. data/lib/rudy/cli/backups.rb +38 -0
  36. data/lib/rudy/cli/base.rb +104 -0
  37. data/lib/rudy/cli/candy.rb +1 -2
  38. data/lib/rudy/cli/config.rb +20 -7
  39. data/lib/rudy/cli/disks.rb +7 -9
  40. data/lib/rudy/cli/execbase.rb +56 -0
  41. data/lib/rudy/cli/machines.rb +242 -45
  42. data/lib/rudy/cli/metadata.rb +24 -10
  43. data/lib/rudy/cli/networks.rb +34 -0
  44. data/lib/rudy/cli/routines.rb +32 -6
  45. data/lib/rudy/cli/status.rb +60 -0
  46. data/lib/rudy/config.rb +55 -32
  47. data/lib/rudy/config/objects.rb +44 -30
  48. data/lib/rudy/disks.rb +25 -0
  49. data/lib/rudy/exceptions.rb +99 -0
  50. data/lib/rudy/global.rb +67 -28
  51. data/lib/rudy/guidelines.rb +3 -2
  52. data/lib/rudy/huxtable.rb +67 -58
  53. data/lib/rudy/machines.rb +41 -263
  54. data/lib/rudy/metadata.rb +212 -38
  55. data/lib/rudy/metadata/backup.rb +123 -78
  56. data/lib/rudy/metadata/disk.rb +153 -170
  57. data/lib/rudy/metadata/machine.rb +179 -0
  58. data/lib/rudy/mixins.rb +2 -1
  59. data/lib/rudy/mixins/hash.rb +3 -1
  60. data/lib/rudy/mixins/symbol.rb +8 -0
  61. data/lib/rudy/routines.rb +127 -344
  62. data/lib/rudy/routines/base.rb +229 -0
  63. data/lib/rudy/routines/handlers/base.rb +48 -0
  64. data/lib/rudy/routines/handlers/depends.rb +49 -0
  65. data/lib/rudy/routines/handlers/disks.rb +249 -0
  66. data/lib/rudy/routines/handlers/group.rb +44 -0
  67. data/lib/rudy/routines/handlers/host.rb +70 -0
  68. data/lib/rudy/routines/handlers/keypair.rb +70 -0
  69. data/lib/rudy/routines/handlers/machines.rb +15 -0
  70. data/lib/rudy/routines/handlers/script.rb +85 -0
  71. data/lib/rudy/routines/handlers/user.rb +45 -0
  72. data/lib/rudy/routines/passthrough.rb +19 -23
  73. data/lib/rudy/routines/reboot.rb +98 -50
  74. data/lib/rudy/routines/shutdown.rb +65 -14
  75. data/lib/rudy/routines/startup.rb +112 -17
  76. data/lib/rudy/utils.rb +35 -68
  77. data/rudy.gemspec +82 -25
  78. data/tryouts/01_mixins/01_hash_tryouts.rb +20 -0
  79. data/tryouts/10_require_time/10_rudy_tryouts.rb +33 -0
  80. data/tryouts/10_require_time/15_global_tryouts.rb +58 -0
  81. data/tryouts/12_config/10_load_config_tryouts.rb +43 -0
  82. data/tryouts/12_config/20_defaults_tryouts.rb +16 -0
  83. data/tryouts/12_config/30_accounts_tryouts.rb +17 -0
  84. data/tryouts/12_config/40_machines_tryouts.rb +53 -0
  85. data/tryouts/12_config/50_commands_tryouts.rb +17 -0
  86. data/tryouts/12_config/60_routines_tryouts.rb +16 -0
  87. data/tryouts/15_huxtable/10_huxtable_tryouts.rb +47 -0
  88. data/tryouts/15_huxtable/20_user_tryouts.rb +47 -0
  89. data/tryouts/20_simpledb/10_domains_tryouts.rb +36 -0
  90. data/tryouts/20_simpledb/20_objects_tryouts.rb +56 -0
  91. data/tryouts/25_ec2/10_keypairs_tryouts.rb +54 -0
  92. data/tryouts/25_ec2/20_groups_tryouts.rb +56 -0
  93. data/tryouts/25_ec2/21_groups_authorize_address_tryouts.rb +53 -0
  94. data/tryouts/25_ec2/22_groups_authorize_account_tryouts.rb +54 -0
  95. data/tryouts/25_ec2/30_addresses_tryouts.rb +42 -0
  96. data/tryouts/25_ec2/40_volumes_tryouts.rb +53 -0
  97. data/tryouts/25_ec2/50_snapshots_tryouts.rb +75 -0
  98. data/tryouts/26_ec2_instances/10_instance_tryouts.rb +107 -0
  99. data/tryouts/26_ec2_instances/50_images_tryouts.rb +7 -0
  100. data/tryouts/30_metadata/10_include_tryouts.rb +45 -0
  101. data/tryouts/30_metadata/13_object_tryouts.rb +19 -0
  102. data/tryouts/30_metadata/50_disk_tryouts.rb +115 -0
  103. data/tryouts/30_metadata/51_disk_digest_tryouts.rb +24 -0
  104. data/tryouts/30_metadata/53_disk_list_tryouts.rb +35 -0
  105. data/tryouts/30_metadata/56_disk_volume_tryouts.rb +68 -0
  106. data/tryouts/30_metadata/60_backup_tryouts.rb +101 -0
  107. data/tryouts/30_metadata/63_backup_list_tryouts.rb +38 -0
  108. data/tryouts/30_metadata/64_backup_disk_tryouts.rb +65 -0
  109. data/tryouts/30_metadata/66_backup_snapshot_tryouts.rb +76 -0
  110. data/tryouts/30_metadata/70_machine_tryouts.rb +85 -0
  111. data/tryouts/30_metadata/73_machine_list_tryouts.rb +58 -0
  112. data/tryouts/30_metadata/76_machine_instance_tryouts.rb +64 -0
  113. data/tryouts/30_metadata/77_machines_tryouts.rb +45 -0
  114. data/tryouts/40_routines/10_keypair_handler_tryouts.rb +52 -0
  115. data/tryouts/40_routines/11_group_handler_tryouts.rb +36 -0
  116. data/tryouts/80_cli/10_rudyec2_tryouts.rb +8 -0
  117. data/tryouts/80_cli/60_rudy_tryouts.rb +41 -0
  118. data/tryouts/exploration/console.rb +91 -0
  119. data/tryouts/exploration/machine.rb +23 -0
  120. data/tryouts/failer +6 -0
  121. metadata +116 -32
  122. data/bin/ird +0 -153
  123. data/lib/rudy/metadata/backups.rb +0 -67
  124. data/lib/rudy/metadata/debug.rb +0 -38
  125. data/lib/rudy/metadata/disks.rb +0 -67
  126. data/lib/rudy/metadata/objectbase.rb +0 -108
  127. data/lib/rudy/routines/helper.rb +0 -76
  128. data/lib/rudy/routines/helpers/dependshelper.rb +0 -34
  129. data/lib/rudy/routines/helpers/diskhelper.rb +0 -403
  130. data/lib/rudy/routines/helpers/scripthelper.rb +0 -197
  131. data/lib/rudy/routines/helpers/userhelper.rb +0 -37
  132. data/support/rudy-ec2-startup +0 -200
@@ -2,7 +2,7 @@
2
2
  module Rudy::AWS
3
3
  module EC2
4
4
 
5
- class KeyPair < Storable
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
- class KeyPairs
29
- include Rudy::AWS::ObjectBase
30
- include Rudy::AWS::EC2::Base
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 = @ec2.create_keypair(:key_name => name)
35
- self.class.from_hash(ret)
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::KeyPair)
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 = @ec2.delete_keypair(:key_name => name)
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 = @ec2.describe_keypairs(:key_name => names)
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 = self.class.from_hash(oldkp)
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 self.from_hash(h)
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::KeyPair.new
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 inspect
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
- class Snapshots
42
- include Rudy::AWS::ObjectBase
43
- include Rudy::AWS::EC2::Base
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 = @ec2.describe_snapshots(:snapshot_id => snap_id)
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.class.from_hash(snap)
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 = @ec2.create_snapshot(:volume_id => vol_id)
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 = @ec2.delete_snapshot(:snapshot_id => snap_id)
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?(id)
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
@@ -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 :create_time
14
- field :attach_time
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 inspect
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
- class Volumes
52
- include Rudy::AWS::ObjectBase
53
- include Rudy::AWS::EC2::Base
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({}) { @ec2.create_volume(opts) }
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 = @@ec2.volumes.available?(volume.awsid)
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({}) { @ec2.delete_volume(:volume_id => vol_id) }
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) { @ec2.attach_volume(opts) }
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({}) { @ec2.detach_volume(:volume_id => vol_id) }
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).values
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({}) { @ec2.describe_volumes(opts) }
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
- !list(state, vol_id).nil?
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.create_time = h['createTime']
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.attach_time = item['attachTime']
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
@@ -19,9 +19,9 @@ module Rudy::AWS
19
19
 
20
20
  end
21
21
 
22
- class Zones
23
- include Rudy::AWS::ObjectBase
24
- include Rudy::AWS::EC2::Base
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 = @ec2.describe_availability_zones(:zone_name => names)
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 zipped Array or Hash of criteria.
65
+ # Takes a Hash of criteria.
67
66
  # Returns a string suitable for a SimpleDB Select
68
- def self.generate_select(fields, domain, *args)
69
- q = args.first.is_a?(Hash)? args.first : Hash[*args.flatten]
67
+ def self.generate_select(domain, fields={})
70
68
  query = []
71
- q.each_pair do |n,v|
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
- @debug.puts("#{url}") if @debug
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
- "AwsSdb::#{error.get_elements('Code')[0].text}Error"
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