rudy 0.8.5 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
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