rudy 0.4.0 → 0.6.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 +54 -30
- data/README.rdoc +100 -12
- data/Rakefile +103 -8
- data/Rudyfile +119 -0
- data/bin/ird +175 -0
- data/bin/rudy +259 -156
- data/bin/rudy-ec2 +228 -95
- data/bin/rudy-s3 +76 -0
- data/bin/rudy-sdb +67 -0
- data/lib/annoy.rb +270 -0
- data/lib/console.rb +30 -9
- data/lib/escape.rb +305 -0
- data/lib/rudy.rb +151 -182
- data/lib/rudy/aws.rb +56 -49
- data/lib/rudy/aws/ec2.rb +47 -292
- data/lib/rudy/aws/ec2/address.rb +157 -0
- data/lib/rudy/aws/ec2/group.rb +301 -0
- data/lib/rudy/aws/ec2/image.rb +168 -0
- data/lib/rudy/aws/ec2/instance.rb +434 -0
- data/lib/rudy/aws/ec2/keypair.rb +104 -0
- data/lib/rudy/aws/ec2/snapshot.rb +98 -0
- data/lib/rudy/aws/ec2/volume.rb +230 -0
- data/lib/rudy/aws/ec2/zone.rb +77 -0
- data/lib/rudy/aws/s3.rb +54 -0
- data/lib/rudy/aws/sdb.rb +298 -0
- data/lib/rudy/aws/sdb/error.rb +46 -0
- data/lib/rudy/{metadata/backup.rb → backup.rb} +26 -51
- data/lib/rudy/cli.rb +157 -0
- data/lib/rudy/cli/aws/ec2/addresses.rb +105 -0
- data/lib/rudy/cli/aws/ec2/candy.rb +208 -0
- data/lib/rudy/cli/aws/ec2/groups.rb +121 -0
- data/lib/rudy/cli/aws/ec2/images.rb +196 -0
- data/lib/rudy/cli/aws/ec2/instances.rb +194 -0
- data/lib/rudy/cli/aws/ec2/keypairs.rb +53 -0
- data/lib/rudy/cli/aws/ec2/snapshots.rb +49 -0
- data/lib/rudy/cli/aws/ec2/volumes.rb +104 -0
- data/lib/rudy/cli/aws/ec2/zones.rb +22 -0
- data/lib/rudy/cli/aws/s3/buckets.rb +50 -0
- data/lib/rudy/cli/aws/s3/store.rb +22 -0
- data/lib/rudy/cli/aws/sdb/domains.rb +41 -0
- data/lib/rudy/cli/candy.rb +8 -0
- data/lib/rudy/{command → cli}/config.rb +34 -24
- data/lib/rudy/cli/disks.rb +35 -0
- data/lib/rudy/cli/machines.rb +94 -0
- data/lib/rudy/cli/routines.rb +57 -0
- data/lib/rudy/config.rb +77 -72
- data/lib/rudy/config/objects.rb +29 -0
- data/lib/rudy/disks.rb +248 -0
- data/lib/rudy/global.rb +121 -0
- data/lib/rudy/huxtable.rb +340 -0
- data/lib/rudy/machines.rb +245 -0
- data/lib/rudy/metadata.rb +123 -13
- data/lib/rudy/routines.rb +47 -0
- data/lib/rudy/routines/helpers/diskhelper.rb +101 -0
- data/lib/rudy/routines/helpers/scripthelper.rb +91 -0
- data/lib/rudy/routines/release.rb +34 -0
- data/lib/rudy/routines/shutdown.rb +57 -0
- data/lib/rudy/routines/startup.rb +58 -0
- data/lib/rudy/scm/svn.rb +1 -1
- data/lib/rudy/utils.rb +322 -4
- data/lib/storable.rb +26 -17
- data/lib/sysinfo.rb +274 -0
- data/lib/tryouts.rb +6 -13
- data/rudy.gemspec +128 -42
- data/support/randomize-root-password +45 -0
- data/support/rudy-ec2-startup +9 -9
- data/support/update-ec2-ami-tools +20 -0
- data/test/05_config/00_setup_test.rb +20 -0
- data/test/05_config/30_machines_test.rb +69 -0
- data/test/20_sdb/00_setup_test.rb +16 -0
- data/test/20_sdb/10_domains_test.rb +115 -0
- data/test/25_ec2/00_setup_test.rb +29 -0
- data/test/25_ec2/10_keypairs_test.rb +41 -0
- data/test/25_ec2/20_groups_test.rb +131 -0
- data/test/25_ec2/30_addresses_test.rb +38 -0
- data/test/25_ec2/40_volumes_test.rb +49 -0
- data/test/25_ec2/50_snapshots_test.rb +74 -0
- data/test/26_ec2_instances/00_setup_test.rb +28 -0
- data/test/26_ec2_instances/10_instances_test.rb +83 -0
- data/test/26_ec2_instances/50_images_test.rb +13 -0
- data/test/30_sdb_metadata/00_setup_test.rb +21 -0
- data/test/30_sdb_metadata/10_disks_test.rb +109 -0
- data/test/30_sdb_metadata/20_backups_test.rb +102 -0
- data/test/coverage.txt +51 -0
- data/test/helper.rb +36 -0
- data/vendor/highline-1.5.1/CHANGELOG +222 -0
- data/vendor/highline-1.5.1/INSTALL +35 -0
- data/vendor/highline-1.5.1/LICENSE +7 -0
- data/vendor/highline-1.5.1/README +63 -0
- data/vendor/highline-1.5.1/Rakefile +82 -0
- data/vendor/highline-1.5.1/TODO +6 -0
- data/vendor/highline-1.5.1/examples/ansi_colors.rb +38 -0
- data/vendor/highline-1.5.1/examples/asking_for_arrays.rb +18 -0
- data/vendor/highline-1.5.1/examples/basic_usage.rb +75 -0
- data/vendor/highline-1.5.1/examples/color_scheme.rb +32 -0
- data/vendor/highline-1.5.1/examples/limit.rb +12 -0
- data/vendor/highline-1.5.1/examples/menus.rb +65 -0
- data/vendor/highline-1.5.1/examples/overwrite.rb +19 -0
- data/vendor/highline-1.5.1/examples/page_and_wrap.rb +322 -0
- data/vendor/highline-1.5.1/examples/password.rb +7 -0
- data/vendor/highline-1.5.1/examples/trapping_eof.rb +22 -0
- data/vendor/highline-1.5.1/examples/using_readline.rb +17 -0
- data/vendor/highline-1.5.1/lib/highline.rb +758 -0
- data/vendor/highline-1.5.1/lib/highline/color_scheme.rb +120 -0
- data/vendor/highline-1.5.1/lib/highline/compatibility.rb +17 -0
- data/vendor/highline-1.5.1/lib/highline/import.rb +43 -0
- data/vendor/highline-1.5.1/lib/highline/menu.rb +395 -0
- data/vendor/highline-1.5.1/lib/highline/question.rb +463 -0
- data/vendor/highline-1.5.1/lib/highline/system_extensions.rb +193 -0
- data/vendor/highline-1.5.1/setup.rb +1360 -0
- data/vendor/highline-1.5.1/test/tc_color_scheme.rb +56 -0
- data/vendor/highline-1.5.1/test/tc_highline.rb +823 -0
- data/vendor/highline-1.5.1/test/tc_import.rb +54 -0
- data/vendor/highline-1.5.1/test/tc_menu.rb +429 -0
- data/vendor/highline-1.5.1/test/ts_all.rb +15 -0
- metadata +141 -38
- data/lib/aws_sdb.rb +0 -3
- data/lib/aws_sdb/error.rb +0 -42
- data/lib/aws_sdb/service.rb +0 -215
- data/lib/rudy/aws/simpledb.rb +0 -53
- data/lib/rudy/command/addresses.rb +0 -46
- data/lib/rudy/command/backups.rb +0 -175
- data/lib/rudy/command/base.rb +0 -841
- data/lib/rudy/command/deploy.rb +0 -12
- data/lib/rudy/command/disks.rb +0 -213
- data/lib/rudy/command/environment.rb +0 -73
- data/lib/rudy/command/groups.rb +0 -61
- data/lib/rudy/command/images.rb +0 -91
- data/lib/rudy/command/instances.rb +0 -85
- data/lib/rudy/command/machines.rb +0 -161
- data/lib/rudy/command/metadata.rb +0 -41
- data/lib/rudy/command/release.rb +0 -174
- data/lib/rudy/command/volumes.rb +0 -66
- data/lib/rudy/metadata/disk.rb +0 -138
- data/tryouts/console_tryout.rb +0 -91
data/lib/rudy/aws/ec2.rb
CHANGED
@@ -1,304 +1,59 @@
|
|
1
1
|
|
2
|
-
module Rudy
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
# {:aws_architecture=>"i386", :aws_owner=>"105148267242", :aws_id=>"ami-6fe40dd5",
|
14
|
-
# :aws_image_type=>"machine", :aws_location=>"bucket-name/your-image.manifest.xml",
|
15
|
-
# :aws_kernel_id=>"aki-a71cf9ce", :aws_state=>"available", :aws_ramdisk_id=>"ari-a51cf9cc",
|
16
|
-
# :aws_is_public=>false}
|
17
|
-
def list
|
18
|
-
@aws.describe_images_by_owner('self') || []
|
19
|
-
end
|
20
|
-
|
21
|
-
# +id+ AMI ID to deregister (ami-XXXXXXX)
|
22
|
-
# Returns true when successful. Otherwise throws an exception.
|
23
|
-
def deregister(id)
|
24
|
-
@aws.deregister_image(id)
|
25
|
-
end
|
26
|
-
|
27
|
-
# +path+ the S3 path to the manifest (bucket/file.manifest.xml)
|
28
|
-
# Returns the AMI ID when successful, otherwise throws an exception.
|
29
|
-
def register(path)
|
30
|
-
@aws.register_image(path)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
class Snapshots
|
34
|
-
include Rudy::AWS::ObjectBase
|
35
|
-
|
36
|
-
def list
|
37
|
-
@aws.describe_snapshots || []
|
38
|
-
end
|
39
|
-
|
40
|
-
def create(vol_id)
|
41
|
-
@aws.create_snapshot(vol_id)
|
42
|
-
end
|
43
|
-
|
44
|
-
def destroy(snap_id)
|
45
|
-
@aws.delete_snapshot(snap_id)
|
46
|
-
end
|
47
|
-
|
48
|
-
def exists?(id)
|
49
|
-
list.each do |v|
|
50
|
-
return true if v[:aws_id] === id
|
2
|
+
module Rudy; module AWS
|
3
|
+
module EC2
|
4
|
+
module Base
|
5
|
+
attr_accessor :ec2
|
6
|
+
def initialize(access_key=nil, secret_key=nil, region=nil, logger=nil)
|
7
|
+
|
8
|
+
if region
|
9
|
+
raise InvalidRegion, region unless Rudy::AWS.valid_region?(region)
|
10
|
+
host = "#{region}.ec2.amazonaws.com"
|
11
|
+
elsif ENV['EC2_URL']
|
12
|
+
host = URL.parse(ENV['EC2_URL']).host
|
51
13
|
end
|
52
|
-
|
14
|
+
|
15
|
+
host ||= DEFAULT_EC2_HOST
|
16
|
+
port ||= DEFAULT_EC2_PORT
|
17
|
+
|
18
|
+
@ec2 = ::EC2::Base.new(:port => port, :server=> host, :access_key_id => access_key, :secret_access_key => secret_key)
|
19
|
+
@logger = logger
|
53
20
|
end
|
54
|
-
|
55
21
|
end
|
56
22
|
|
57
|
-
class
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
# :aws_attached_at=>Wed Mar 11 07:06:44 UTC 2009,
|
65
|
-
# :aws_status=>"in-use",
|
66
|
-
# :aws_instance_id=>"i-0b2ab662",
|
67
|
-
# :aws_created_at=>Tue Mar 10 18:55:18 UTC 2009,
|
68
|
-
# :zone=>"us-east-1b",
|
69
|
-
# :aws_size=>10}]
|
70
|
-
def list
|
71
|
-
list = @aws.describe_volumes() || []
|
72
|
-
list.select { |v| v[:aws_status] != "deleting" }
|
73
|
-
end
|
74
|
-
|
75
|
-
def attach(inst_id, vol_id, device)
|
76
|
-
@aws.attach_volume(vol_id, inst_id, device)
|
77
|
-
end
|
78
|
-
|
79
|
-
def detach(vol_id)
|
80
|
-
@aws.detach_volume(vol_id)
|
81
|
-
end
|
82
|
-
|
83
|
-
def create(zone, size, snapshot=nil)
|
84
|
-
@aws.create_volume(snapshot, size, zone)
|
85
|
-
end
|
86
|
-
|
87
|
-
def destroy(vol_id)
|
88
|
-
@aws.delete_volume(vol_id)
|
89
|
-
end
|
90
|
-
|
91
|
-
def exists?(id)
|
92
|
-
list.each do |v|
|
93
|
-
return true if v[:aws_id] === id
|
94
|
-
end
|
95
|
-
false
|
96
|
-
end
|
97
|
-
|
98
|
-
def get(vol_id)
|
99
|
-
list = @aws.describe_volumes(vol_id) || []
|
100
|
-
list.first
|
101
|
-
end
|
102
|
-
|
103
|
-
def deleting?(vol_id)
|
104
|
-
return false unless vol_id
|
105
|
-
vol = get(vol_id)
|
106
|
-
(vol && vol[:aws_status] == "deleting")
|
107
|
-
end
|
108
|
-
|
109
|
-
def available?(vol_id)
|
110
|
-
return false unless vol_id
|
111
|
-
vol = get(vol_id)
|
112
|
-
(vol && vol[:aws_status] == "available")
|
113
|
-
end
|
114
|
-
|
115
|
-
def attached?(vol_id)
|
116
|
-
return false unless vol_id
|
117
|
-
vol = get(vol_id)
|
118
|
-
(vol && vol[:aws_status] == "in-use")
|
119
|
-
end
|
120
|
-
|
121
|
-
end
|
23
|
+
class NoRunningInstances < Rudy::Error; end
|
24
|
+
class MalformedResponse < Rudy::Error; end
|
25
|
+
class InvalidRegion < Rudy::Error; end
|
26
|
+
class UnknownState < Rudy::Error; end
|
27
|
+
class NoGroup < Rudy::Error; end
|
28
|
+
class NoKeyPair < Rudy::Error; end
|
29
|
+
class NoAMI < Rudy::Error; end
|
122
30
|
|
123
|
-
class
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
def attached_volume?(id, device)
|
139
|
-
list = volumes(id)
|
140
|
-
list.each do |v|
|
141
|
-
return true if v[:aws_device] == device
|
142
|
-
end
|
143
|
-
false
|
144
|
-
end
|
145
|
-
|
146
|
-
def volumes(id)
|
147
|
-
list = @aws.describe_volumes() || []
|
148
|
-
list.select { |v| v[:aws_status] != "deleting" && v[:aws_instance_id] === id }
|
149
|
-
end
|
150
|
-
|
151
|
-
def device_volume(id, device)
|
152
|
-
volumes.select { |v| v[:aws_device] === device }
|
153
|
-
end
|
154
|
-
|
155
|
-
def create(ami, group, keypair_name, user_data, zone)
|
156
|
-
@aws.run_instances(ami, 1, 1, [group], keypair_name, user_data, 'public', nil, nil, nil, zone)
|
157
|
-
end
|
158
|
-
|
159
|
-
# Creates a list of running instance IDs which are in a security group
|
160
|
-
# that matches +filter+.
|
161
|
-
# Returns a hash. The keys are instance IDs and the values are a hash
|
162
|
-
# of attributes associated to that instance.
|
163
|
-
# {:aws_state_code=>"16",
|
164
|
-
# :private_dns_name=>"domU-12-31-38-00-51-F1.compute-1.internal",
|
165
|
-
# :aws_instance_type=>"m1.small",
|
166
|
-
# :aws_reason=>"",
|
167
|
-
# :ami_launch_index=>"0",
|
168
|
-
# :aws_owner=>"207436219441",
|
169
|
-
# :aws_launch_time=>"2009-03-11T06:55:00.000Z",
|
170
|
-
# :aws_kernel_id=>"aki-a71cf9ce",
|
171
|
-
# :ssh_key_name=>"rilli-sexytime",
|
172
|
-
# :aws_reservation_id=>"r-66f5710f",
|
173
|
-
# :aws_state=>"running",
|
174
|
-
# :aws_ramdisk_id=>"ari-a51cf9cc",
|
175
|
-
# :aws_instance_id=>"i-0b2ab662",
|
176
|
-
# :aws_groups=>["rudydev-app"],
|
177
|
-
# :aws_availability_zone=>"us-east-1b",
|
178
|
-
# :aws_image_id=>"ami-daca2db3",
|
179
|
-
# :aws_product_codes=>[],
|
180
|
-
# :dns_name=>"ec2-67-202-9-30.compute-1.amazonaws.com"}
|
181
|
-
def list(filter='.')
|
182
|
-
filter = filter.to_s.downcase.tr('_|-', '.') # treat dashes, underscores as one
|
183
|
-
# Returns an array of hashes with the following keys:
|
184
|
-
# :aws_image_id, :aws_reason, :aws_state_code, :aws_owner, :aws_instance_id, :aws_reservation_id
|
185
|
-
# :aws_state, :dns_name, :ssh_key_name, :aws_groups, :private_dns_name, :aws_instance_type,
|
186
|
-
# :aws_launch_time, :aws_availability_zone :aws_kernel_id, :aws_ramdisk_id
|
187
|
-
instances = @aws.describe_instances || []
|
188
|
-
running_instances = {}
|
189
|
-
instances.each do |inst|
|
190
|
-
if inst[:aws_state] != "terminated" && (inst[:aws_groups].to_s =~ /#{filter}/)
|
191
|
-
running_instances[inst[:aws_instance_id]] = inst
|
192
|
-
end
|
193
|
-
end
|
194
|
-
running_instances
|
195
|
-
end
|
196
|
-
|
197
|
-
def get(inst_id)
|
198
|
-
# This is ridiculous. Send inst_id to describe volumes
|
199
|
-
instance = {}
|
200
|
-
list.each_pair do |id, hash|
|
201
|
-
next unless inst_id == id
|
202
|
-
instance = hash
|
203
|
-
end
|
204
|
-
instance
|
205
|
-
end
|
206
|
-
|
207
|
-
def running?(inst_id)
|
208
|
-
inst = get(inst_id)
|
209
|
-
(inst && inst[:aws_state] == "running")
|
210
|
-
end
|
211
|
-
|
212
|
-
def pending?(inst_id)
|
213
|
-
inst = get(inst_id)
|
214
|
-
(inst && inst[:aws_state] == "pending")
|
31
|
+
class NoAddress < Rudy::Error; end
|
32
|
+
class UnknownAddress < Rudy::Error; end
|
33
|
+
class NoInstanceID < Rudy::Error; end
|
34
|
+
class AddressAssociated < Rudy::Error; end
|
35
|
+
class ErrorCreatingAddress < Rudy::Error; end
|
36
|
+
class AddressNotAssociated < Rudy::Error; end
|
37
|
+
class InsecureKeyPairPermissions < Rudy::Error; end
|
38
|
+
|
39
|
+
class InsecureKeyPairPermissions < Rudy::Error; end
|
40
|
+
class ErrorCreatingKeyPair < Rudy::Error; end
|
41
|
+
class NoPrivateKeyFile < Rudy::Error; end
|
42
|
+
class KeyPairExists < Rudy::Error; end
|
43
|
+
class KeyPairAlreadyDefined < Rudy::Error
|
44
|
+
def message
|
45
|
+
"A keypair is defined for #{@obj}. Check your Rudy config."
|
215
46
|
end
|
216
47
|
end
|
217
48
|
|
218
|
-
class
|
219
|
-
|
49
|
+
class VolumeAlreadyAttached < Rudy::Error; end
|
50
|
+
class VolumeNotAvailable < Rudy::Error; end
|
51
|
+
class VolumeNotAttached < Rudy::Error; end
|
52
|
+
class NoInstanceID < Rudy::Error; end
|
53
|
+
class NoVolumeID < Rudy::Error; end
|
54
|
+
class UnknownState < Rudy::Error; end
|
55
|
+
class NoDevice < Rudy::Error; end
|
220
56
|
|
221
|
-
|
222
|
-
# +list+ is a list of security groups to look for. If it's empty, all groups
|
223
|
-
# associated to the account will be returned.
|
224
|
-
# right_aws returns an array of hashes
|
225
|
-
# :aws_group_name => "default-1",
|
226
|
-
# :aws_owner => "000000000888",
|
227
|
-
# :aws_description => "Default allowing SSH, HTTP, and HTTPS ingress",
|
228
|
-
# :aws_perms => [{:owner => "000000000888", :group => "default"},
|
229
|
-
# {:owner => "000000000888", :group => "default-1"},
|
230
|
-
# {:to_port => "-1", :protocol => "icmp", :from_port => "-1", :cidr_ips => "0.0.0.0/0"}]
|
231
|
-
# ]
|
232
|
-
def list(list=[])
|
233
|
-
glist = @aws.describe_security_groups(list) || []
|
234
|
-
|
235
|
-
end
|
236
|
-
|
237
|
-
# Create a new EC2 security group
|
238
|
-
# Returns true/false whether successful
|
239
|
-
def create(name, desc=nil)
|
240
|
-
@aws.create_security_group(name, desc || "Group #{name}")
|
241
|
-
end
|
242
|
-
|
243
|
-
# Delete an EC2 security group
|
244
|
-
# Returns true/false whether successful
|
245
|
-
def destroy(name)
|
246
|
-
@aws.delete_security_group(name)
|
247
|
-
end
|
248
|
-
|
249
|
-
# Modify an EC2 security group
|
250
|
-
# Returns true/false whether successful
|
251
|
-
def modify(name, from_port, to_port, protocol='tcp', ipa='0.0.0.0/0')
|
252
|
-
@aws.authorize_security_group_IP_ingress(name, from_port, to_port, protocol, ipa)
|
253
|
-
end
|
254
|
-
|
255
|
-
|
256
|
-
# Does the security group +name+ exist?
|
257
|
-
def exists?(name)
|
258
|
-
begin
|
259
|
-
g = list([name.to_s])
|
260
|
-
|
261
|
-
rescue RightAws::AwsError => ex
|
262
|
-
# Ignore (it raises an exception when the list contains an unknown group name)
|
263
|
-
ensure
|
264
|
-
g ||= []
|
265
|
-
end
|
266
|
-
|
267
|
-
!g.empty?
|
268
|
-
end
|
269
|
-
|
270
|
-
end
|
271
57
|
|
272
|
-
class Addresses
|
273
|
-
include Rudy::AWS::ObjectBase
|
274
|
-
|
275
|
-
# Returns and array of hashes:
|
276
|
-
# [{:instance_id=>"i-d630cbbf", :public_ip=>"75.101.1.140"},
|
277
|
-
# {:instance_id=>nil, :public_ip=>"75.101.1.141"}]
|
278
|
-
def list
|
279
|
-
@aws.describe_addresses || []
|
280
|
-
end
|
281
|
-
|
282
|
-
|
283
|
-
# Associate an elastic IP to an instance
|
284
|
-
def associate(instance, address)
|
285
|
-
@aws.associate_address(instance, address)
|
286
|
-
end
|
287
|
-
|
288
|
-
def valid?(address)
|
289
|
-
list.each do |a|
|
290
|
-
return true if a[:public_ip] == address
|
291
|
-
end
|
292
|
-
false
|
293
|
-
end
|
294
|
-
|
295
|
-
def associated?(address)
|
296
|
-
list.each do |a|
|
297
|
-
return true if a[:public_ip] == address && a[:instance_id]
|
298
|
-
end
|
299
|
-
false
|
300
|
-
end
|
301
|
-
end
|
302
58
|
end
|
303
|
-
|
304
|
-
end
|
59
|
+
end; end
|
@@ -0,0 +1,157 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module Rudy::AWS
|
4
|
+
|
5
|
+
module EC2
|
6
|
+
|
7
|
+
class Address < Storable
|
8
|
+
field :ipaddress
|
9
|
+
field :instid
|
10
|
+
|
11
|
+
def liner_note
|
12
|
+
info = self.associated? ? @instid : "available"
|
13
|
+
"%s (%s)" % [@ipaddress.to_s.bright, info]
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_s(with_titles=false)
|
17
|
+
liner_note
|
18
|
+
end
|
19
|
+
|
20
|
+
def associated?
|
21
|
+
!@instid.nil? && !@instid.empty?
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Addresses
|
26
|
+
include Rudy::AWS::ObjectBase
|
27
|
+
include Rudy::AWS::EC2::Base
|
28
|
+
|
29
|
+
|
30
|
+
def create
|
31
|
+
ret = @ec2.allocate_address
|
32
|
+
return false unless ret && ret['publicIp']
|
33
|
+
address = Rudy::AWS::EC2::Address.new
|
34
|
+
address.ipaddress = ret['publicIp']
|
35
|
+
address
|
36
|
+
end
|
37
|
+
|
38
|
+
def destroy(address)
|
39
|
+
address = address.ipaddress if address.is_a?(Rudy::AWS::EC2::Address)
|
40
|
+
raise UnknownAddress unless exists?(address)
|
41
|
+
|
42
|
+
opts ={
|
43
|
+
:public_ip => address || raise("No public IP address supplied")
|
44
|
+
}
|
45
|
+
ret = @ec2.release_address(opts)
|
46
|
+
(ret && ret['return'] == 'true')
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
# Associate an elastic IP to an instance
|
51
|
+
def associate(address, instance)
|
52
|
+
raise NoInstanceID unless instance
|
53
|
+
raise NoAddress unless address
|
54
|
+
|
55
|
+
address = address.ipaddress if address.is_a?(Rudy::AWS::EC2::Address)
|
56
|
+
instance = instance.awsid if instance.is_a?(Rudy::AWS::EC2::Instance)
|
57
|
+
raise UnknownAddress unless exists?(address)
|
58
|
+
raise AddressAssociated if associated?(address)
|
59
|
+
|
60
|
+
opts ={
|
61
|
+
:instance_id => instance,
|
62
|
+
:public_ip => address
|
63
|
+
}
|
64
|
+
ret = @ec2.associate_address(opts)
|
65
|
+
(ret && ret['return'] == 'true')
|
66
|
+
end
|
67
|
+
|
68
|
+
# Disssociate an elastic IP from an instance
|
69
|
+
def disassociate(address)
|
70
|
+
raise NoAddress unless address
|
71
|
+
address = address.ipaddress if address.is_a?(Rudy::AWS::EC2::Address)
|
72
|
+
instance = instance.awsid if instance.is_a?(Rudy::AWS::EC2::Instance)
|
73
|
+
raise UnknownAddress unless exists?(address)
|
74
|
+
raise AddressNotAssociated unless associated?(address)
|
75
|
+
|
76
|
+
opts ={
|
77
|
+
:public_ip => address
|
78
|
+
}
|
79
|
+
ret = @ec2.disassociate_address(opts)
|
80
|
+
(ret && ret['return'] == 'true')
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
|
85
|
+
# Returns a Array of Rudy::AWS::EC2::Address objects.
|
86
|
+
def list(addresses=[])
|
87
|
+
addresses = list_as_hash(addresses)
|
88
|
+
addresses &&= addresses.values
|
89
|
+
addresses
|
90
|
+
end
|
91
|
+
|
92
|
+
# Returns a Hash of Rudy::AWS::EC2::Address objects. The key of the IP address.
|
93
|
+
def list_as_hash(addresses=[])
|
94
|
+
addresses ||= []
|
95
|
+
addresses = [addresses].flatten.compact
|
96
|
+
alist = @ec2.describe_addresses(:addresses=> addresses)
|
97
|
+
|
98
|
+
return nil unless alist['addressesSet'].is_a?(Hash)
|
99
|
+
|
100
|
+
addresses = {}
|
101
|
+
alist['addressesSet']['item'].each do |address|
|
102
|
+
address = Addresses.from_hash(address)
|
103
|
+
addresses[address.ipaddress] = address
|
104
|
+
end
|
105
|
+
|
106
|
+
addresses
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
def any?
|
111
|
+
!list_as_hash.nil?
|
112
|
+
end
|
113
|
+
|
114
|
+
def get(address)
|
115
|
+
raise "Address cannot be nil" if address.nil?
|
116
|
+
address = address.ipaddress if address.is_a?(Rudy::AWS::EC2::Address)
|
117
|
+
(list(address) || []).first
|
118
|
+
end
|
119
|
+
|
120
|
+
def self.from_hash(h)
|
121
|
+
# requestId: 5ebcad80-eed9-4221-86f6-8d19d7acffe4
|
122
|
+
# addressesSet:
|
123
|
+
# item:
|
124
|
+
# - publicIp: 75.101.137.7
|
125
|
+
# instanceId:
|
126
|
+
address = Rudy::AWS::EC2::Address.new
|
127
|
+
address.ipaddress = h['publicIp']
|
128
|
+
address.instid = h['instanceId'] if h['instanceId'] && !h['instanceId'].empty?
|
129
|
+
address
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
# +address+ is an IP address or Rudy::AWS::EC2::Address object
|
134
|
+
# Returns true if the given address is assigned to the current account
|
135
|
+
def exists?(address)
|
136
|
+
address = address.ipaddress if address.is_a?(Rudy::AWS::EC2::Address)
|
137
|
+
list.each do |a|
|
138
|
+
return true if a.ipaddress == address
|
139
|
+
end
|
140
|
+
false
|
141
|
+
end
|
142
|
+
|
143
|
+
# +address+ is an IP address or Rudy::AWS::EC2::Address object
|
144
|
+
# Returns true if the given address is associated to an instance
|
145
|
+
def associated?(address)
|
146
|
+
address = address.ipaddress if address.is_a?(Rudy::AWS::EC2::Address)
|
147
|
+
list.each do |a|
|
148
|
+
return true if a.ipaddress == address && a.instid
|
149
|
+
end
|
150
|
+
false
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
|