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
@@ -0,0 +1,121 @@
|
|
1
|
+
|
2
|
+
module Rudy; module CLI;
|
3
|
+
module AWS; module EC2;
|
4
|
+
|
5
|
+
class Groups < Rudy::CLI::CommandBase
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
def create_groups_valid?
|
10
|
+
@rgroups = Rudy::AWS::EC2::Groups.new(@@global.accesskey, @@global.secretkey, @@global.region)
|
11
|
+
raise Drydock::ArgError.new('group name', @alias) unless @argv.name
|
12
|
+
raise "Group #{@argv.name} alread exists" if @rgroups.exists?(@argv.name)
|
13
|
+
true
|
14
|
+
end
|
15
|
+
def create_groups
|
16
|
+
opts = check_options
|
17
|
+
puts "Creating #{@argv.name}"
|
18
|
+
|
19
|
+
execute_action {
|
20
|
+
@rgroups.create(@argv.name, @option.description, opts[:addresses], opts[:ports], opts[:protocols])
|
21
|
+
}
|
22
|
+
|
23
|
+
@rgroups.list(@argv.name) do |group|
|
24
|
+
puts @@global.verbose > 0 ? group.inspect : group.dump(@@global.format)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
def destroy_groups_valid?
|
30
|
+
@rgroups = Rudy::AWS::EC2::Groups.new(@@global.accesskey, @@global.secretkey, @@global.region)
|
31
|
+
raise Drydock::ArgError.new('group name', @alias) unless @argv.name
|
32
|
+
raise "Group #{@argv.name} does not exist" unless @rgroups.exists?(@argv.name)
|
33
|
+
true
|
34
|
+
end
|
35
|
+
|
36
|
+
def destroy_groups
|
37
|
+
puts "Destroying group: #{@argv.name}"
|
38
|
+
execute_check(:medium)
|
39
|
+
execute_action { @rgroups.destroy(@argv.name) }
|
40
|
+
@argv.clear # so groups will print all other groups
|
41
|
+
groups
|
42
|
+
end
|
43
|
+
|
44
|
+
def revoke_groups_valid?; modify_group_valid?; end
|
45
|
+
def revoke_groups; modify_group(:revoke); end
|
46
|
+
|
47
|
+
def authorize_groups_valid?; modify_group_valid?; end
|
48
|
+
def authorize_groups; modify_group(:authorize); end
|
49
|
+
|
50
|
+
def groups
|
51
|
+
opts = {}
|
52
|
+
name = @option.all ? nil : @argv.name
|
53
|
+
rgroups = Rudy::AWS::EC2::Groups.new(@@global.accesskey, @@global.secretkey, @@global.region)
|
54
|
+
rgroups.list(name).each do |group|
|
55
|
+
puts @@global.verbose > 0 ? group.inspect : group.dump(@@global.format)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def modify_group_valid?
|
62
|
+
if @option.owner == 'self'
|
63
|
+
raise "AWS_ACCOUNT_NUMBER not set" unless @@global.accountnum
|
64
|
+
@option.owner = @@global.accountnum
|
65
|
+
end
|
66
|
+
|
67
|
+
if (@option.addresses || @option.ports) && (@option.group || @option.owner)
|
68
|
+
raise Drydock::OptError.new('', @alias, "Cannot mix group and network authorization")
|
69
|
+
end
|
70
|
+
if @option.owner && !@option.group
|
71
|
+
raise Drydock::OptError.new('', @alias, "Must provide -g with -o")
|
72
|
+
end
|
73
|
+
|
74
|
+
raise Drydock::ArgError.new('group name', @alias) unless @argv.name
|
75
|
+
@groups = Rudy::AWS::EC2::Groups.new(@@global.accesskey, @@global.secretkey, @@global.region)
|
76
|
+
end
|
77
|
+
|
78
|
+
def modify_group(action)
|
79
|
+
opts = check_options
|
80
|
+
if (@option.group || @option.owner)
|
81
|
+
g = [opts[:owner], opts[:group]].join(':')
|
82
|
+
puts "#{action.to_s.capitalize} access to #{@argv.name.bright} from #{g.bright}"
|
83
|
+
else
|
84
|
+
print "#{action.to_s.capitalize} access to #{@argv.name.bright}"
|
85
|
+
puts " from #{opts[:addresses].join(', ').bright}"
|
86
|
+
print "on #{opts[:protocols].join(', ').bright} "
|
87
|
+
puts "ports: #{opts[:ports].map { |p| "#{p.join(' to ').bright}" }.join(', ')}"
|
88
|
+
end
|
89
|
+
rgroups = Rudy::AWS::EC2::Groups.new(@@global.accesskey, @@global.secretkey, @@global.region)
|
90
|
+
execute_check(:medium)
|
91
|
+
execute_action {
|
92
|
+
if (@option.group || @option.owner)
|
93
|
+
rgroups.send("#{action.to_s}_group", @argv.name, opts[:group], opts[:owner])
|
94
|
+
else
|
95
|
+
rgroups.send(action, @argv.name, opts[:addresses], opts[:ports], opts[:protocols])
|
96
|
+
end
|
97
|
+
}
|
98
|
+
groups # prints on the modified group b/c of @argv.name
|
99
|
+
end
|
100
|
+
|
101
|
+
def check_options
|
102
|
+
opts = {}
|
103
|
+
[:addresses, :protocols, :owner, :group, :ports].each do |opt|
|
104
|
+
opts[opt] = @option.send(opt) if @option.respond_to?(opt)
|
105
|
+
end
|
106
|
+
unless @option.group || @option.owner
|
107
|
+
opts[:ports].collect! { |port| port.split(/[:-]/) } if opts[:ports]
|
108
|
+
opts[:ports] ||= [[22,22],[80,80],[443,443]]
|
109
|
+
opts[:addresses] ||= [Rudy::Utils::external_ip_address]
|
110
|
+
opts[:protocols] ||= [:tcp]
|
111
|
+
else
|
112
|
+
opts[:owner] ||= @@global.accountnum
|
113
|
+
end
|
114
|
+
opts
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
end; end
|
121
|
+
end; end
|
@@ -0,0 +1,196 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module Rudy; module CLI;
|
4
|
+
module AWS; module EC2;
|
5
|
+
|
6
|
+
class Images < Rudy::CLI::CommandBase
|
7
|
+
|
8
|
+
#def print_header
|
9
|
+
# puts @global.print_header, @@global.print_header
|
10
|
+
#end
|
11
|
+
|
12
|
+
|
13
|
+
def images_valid?
|
14
|
+
if @option.owner == 'self'
|
15
|
+
raise "AWS_ACCOUNT_NUMBER not set" unless @@global.accountnum
|
16
|
+
@option.owner = @@global.accountnum
|
17
|
+
end
|
18
|
+
|
19
|
+
true
|
20
|
+
end
|
21
|
+
def images
|
22
|
+
|
23
|
+
rimages = Rudy::AWS::EC2::Images.new(@@global.accesskey, @@global.secretkey, @@global.region)
|
24
|
+
unless @option.all
|
25
|
+
@option.owner ||= 'amazon'
|
26
|
+
puts "Images owned by #{@option.owner.bright}" unless @argv.awsid
|
27
|
+
end
|
28
|
+
|
29
|
+
images = rimages.list(@option.owner, @argv) || []
|
30
|
+
images.each do |img|
|
31
|
+
puts @@global.verbose > 0 ? img.inspect : img.dump(@@global.format)
|
32
|
+
end
|
33
|
+
puts "No images" if images.empty?
|
34
|
+
end
|
35
|
+
|
36
|
+
def prepare_images_valid?
|
37
|
+
true
|
38
|
+
end
|
39
|
+
def prepare_images
|
40
|
+
opts = {}
|
41
|
+
opts[:group] = @option.group if @option.group
|
42
|
+
opts[:group] = :any if @option.all
|
43
|
+
opts[:id] = @option.instid if @option.instid
|
44
|
+
|
45
|
+
puts "This will do the following:"
|
46
|
+
puts "- Clear bash history"
|
47
|
+
# NOTE: We can't delete the host keys here. Otherwise we can't create the image.
|
48
|
+
#puts "- Delete host SSH keys (this is permanent!)"
|
49
|
+
puts ""
|
50
|
+
|
51
|
+
# Options to be sent to Net::SSH
|
52
|
+
ssh_opts = { :user => @global.user || Rudy.sysinfo.user, :debug => STDERR }
|
53
|
+
if @@global.pkey
|
54
|
+
raise "Cannot find file #{@@global.pkey}" unless File.exists?(@@global.pkey)
|
55
|
+
raise InsecureKeyPermissions, @@global.pkey unless File.stat(@@global.pkey).mode == 33152
|
56
|
+
ssh_opts[:keys] = @@global.pkey
|
57
|
+
end
|
58
|
+
|
59
|
+
execute_check(:medium)
|
60
|
+
|
61
|
+
rudy = Rudy::AWS::EC2::Instances.new(@@global.accesskey, @@global.secretkey, @@global.region)
|
62
|
+
lt = rudy.list_group(opts[:group], :running, opts[:id]) do |inst|
|
63
|
+
|
64
|
+
puts "Preparing #{inst.dns_public}..."
|
65
|
+
|
66
|
+
# Open the connection and run the command
|
67
|
+
rbox = Rye::Box.new(inst.dns_public, ssh_opts)
|
68
|
+
rbox.safe = false
|
69
|
+
# We need to explicitly add the rm command for rbox so we
|
70
|
+
# can delete the SSH host keys. This is will force the instance
|
71
|
+
# to re-create it's SSH keys on first boot.
|
72
|
+
def rbox.rm(*args); cmd('rm', args); end
|
73
|
+
p ret = rbox.history(:c)
|
74
|
+
p ret.exit_code
|
75
|
+
p ret.stderr
|
76
|
+
p ret.stdout
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
puts "done"
|
81
|
+
end
|
82
|
+
|
83
|
+
def create_images_valid?
|
84
|
+
raise "No account number" unless @@global.accountnum
|
85
|
+
raise "No Amazon cert-***.pem" unless @@global.cert
|
86
|
+
raise "No Amazon pk-***.pem" unless @@global.privatekey
|
87
|
+
true
|
88
|
+
end
|
89
|
+
|
90
|
+
def create_images
|
91
|
+
opts = {}
|
92
|
+
opts[:group] = @option.group if @option.group
|
93
|
+
opts[:group] = :any if @option.all
|
94
|
+
opts[:id] = @option.instid if @option.instid
|
95
|
+
|
96
|
+
puts "You may want to run rudy-ec2 #{@alias} --prepare before this.".color(:blue)
|
97
|
+
puts "This feature is experimental. Make sure you enter the bucket"
|
98
|
+
puts "and image names correctly because if they're wrong the image"
|
99
|
+
puts "won't get created and you'll be annoyed that you waited."
|
100
|
+
|
101
|
+
# Options to be sent to Net::SSH
|
102
|
+
ssh_opts = { :user => @global.user || Rudy.sysinfo.user, :debug => STDERR }
|
103
|
+
if @@global.pkey
|
104
|
+
raise "Cannot find file #{@@global.pkey}" unless File.exists?(@@global.pkey)
|
105
|
+
raise InsecureKeyPermissions, @@global.pkey unless File.stat(@@global.pkey).mode == 33152
|
106
|
+
ssh_opts[:keys] = @@global.pkey
|
107
|
+
end
|
108
|
+
|
109
|
+
unless @option.name
|
110
|
+
print "Enter the image name: "
|
111
|
+
@option.image_name = gets.chomp
|
112
|
+
end
|
113
|
+
|
114
|
+
unless @option.bucket
|
115
|
+
print "Enter the S3 bucket that will store the image: "
|
116
|
+
@option.bucket_name = gets.chomp
|
117
|
+
end
|
118
|
+
|
119
|
+
execute_check(:medium)
|
120
|
+
|
121
|
+
rudy = Rudy::AWS::EC2::Instances.new(@@global.accesskey, @@global.secretkey, @@global.region)
|
122
|
+
lt = rudy.list_group(opts[:group], :running, opts[:id]) do |inst|
|
123
|
+
|
124
|
+
puts inst.dns_public
|
125
|
+
|
126
|
+
# Open the connection and run the command
|
127
|
+
rbox = Rye::Box.new(inst.dns_public, ssh_opts)
|
128
|
+
|
129
|
+
# ~/.rudy, /etc/motd, history -c, /etc/hosts, /var/log/rudy*
|
130
|
+
cert = File.read(@@global.cert)
|
131
|
+
pk = File.read(@@global.privatekey)
|
132
|
+
rbox.safe = false
|
133
|
+
rbox.echo("'#{cert}' > /mnt/cert-temporary.pem")
|
134
|
+
rbox.echo("'#{pk}' > /mnt/pk-temporary.pem")
|
135
|
+
rbox.safe = true
|
136
|
+
rbox.touch("/root/firstrun")
|
137
|
+
|
138
|
+
# TODO:
|
139
|
+
# We have to delete the host keys just before we run the bundle command.
|
140
|
+
# The problem is that if we lose the connection we won't be able to connect
|
141
|
+
# to the instance again. A better solution is to ass the keys to the ignore
|
142
|
+
# list for the bundle command.
|
143
|
+
|
144
|
+
#ret = rbox.rm('/etc/ssh/ssh_host_*_key*')
|
145
|
+
#puts "Starting bundling process...".bright
|
146
|
+
#puts ssh_command(machine[:dns_name], keypairpath, @global.user, "ec2-bundle-vol -r i386 -p #{@option.image_name} -k /mnt/pk-*pem -c /mnt/cert*pem -u #{@option.account}", @option.print)
|
147
|
+
#puts ssh_command(machine[:dns_name], keypairpath, @global.user, "ec2-upload-bundle -b #{@option.bucket_name} -m /tmp/#{@option.image_name}.manifest.xml -a #{@global.accesskey} -s #{@global.secretkey}", @option.print)
|
148
|
+
#
|
149
|
+
#@ec2.images.register("#{@option.bucket_name}/#{@option.image_name}.manifest.xml") unless @option.print
|
150
|
+
|
151
|
+
break
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
155
|
+
|
156
|
+
#def create_images_valid?
|
157
|
+
# puts "Make sure the machine is clean. I don't want archive no crud!"
|
158
|
+
# switch_user("root")
|
159
|
+
#
|
160
|
+
# raise "No EC2 .pem keys provided" unless has_pem_keys?
|
161
|
+
# raise "No SSH key provided for #{@global.user}!" unless has_keypair?
|
162
|
+
# raise "No SSH key provided for root!" unless has_keypair?(:root)
|
163
|
+
# true
|
164
|
+
#end
|
165
|
+
#
|
166
|
+
#
|
167
|
+
#def prepare_images
|
168
|
+
# # TODO: Avail hooks for clean an instance
|
169
|
+
# # Clean off Rudy specific crap.
|
170
|
+
#end
|
171
|
+
#
|
172
|
+
#
|
173
|
+
|
174
|
+
#
|
175
|
+
#def deregister
|
176
|
+
# ami = @argv.first
|
177
|
+
# raise "You must supply an AMI ID (ami-XXXXXXX)" unless ami
|
178
|
+
# puts "Deregistering AMI: #{ami}"
|
179
|
+
#
|
180
|
+
# exit unless Annoy.are_you_sure?
|
181
|
+
#
|
182
|
+
# if @ec2.images.deregister(ami)
|
183
|
+
# puts "Done!"
|
184
|
+
# else
|
185
|
+
# puts "There was an unknown problem!"
|
186
|
+
# end
|
187
|
+
#
|
188
|
+
#end
|
189
|
+
|
190
|
+
end
|
191
|
+
|
192
|
+
|
193
|
+
end; end
|
194
|
+
end; end
|
195
|
+
|
196
|
+
|
@@ -0,0 +1,194 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module Rudy; module CLI;
|
4
|
+
module AWS; module EC2;
|
5
|
+
class InstanceAndGroupError < Drydock::ArgError
|
6
|
+
def message; "You cannot provide a group and an instance ID"; end
|
7
|
+
end
|
8
|
+
class NoInstanceError < Drydock::ArgError
|
9
|
+
def message; "You must provide a group or instance ID"; end
|
10
|
+
end
|
11
|
+
|
12
|
+
class Instances < Rudy::CLI::CommandBase
|
13
|
+
|
14
|
+
def instances_create_valid?
|
15
|
+
|
16
|
+
raise "Cannot supply an instance ID" if @option.instid
|
17
|
+
|
18
|
+
if @option.group
|
19
|
+
rgroup = Rudy::AWS::EC2::Groups.new(@@global.accesskey, @@global.secretkey, @@global.region)
|
20
|
+
raise "Group #{@option.group} does not exist" unless rgroup.exists?(@option.group)
|
21
|
+
end
|
22
|
+
|
23
|
+
true
|
24
|
+
end
|
25
|
+
|
26
|
+
def instances_create
|
27
|
+
|
28
|
+
opts = { # Defaults
|
29
|
+
:group => 'default',
|
30
|
+
:size => 'm1.small',
|
31
|
+
:zone => @@global.zone
|
32
|
+
}
|
33
|
+
|
34
|
+
radd = Rudy::AWS::EC2::Addresses.new(@@global.accesskey, @@global.secretkey, @@global.region)
|
35
|
+
rinst = Rudy::AWS::EC2::Instances.new(@@global.accesskey, @@global.secretkey, @@global.region)
|
36
|
+
|
37
|
+
if @option.address
|
38
|
+
raise "Cannot specify both -a and -n" if @option.newaddress
|
39
|
+
raise "#{@option.address} is not allocated to you" unless radd.exists?(@option.address)
|
40
|
+
raise "#{@option.address} is already associated!" if radd.associated?(@option.address)
|
41
|
+
end
|
42
|
+
|
43
|
+
# These can be sent directly to EC2 class
|
44
|
+
[:group, :ami, :size, :keypair, :private].each do |n|
|
45
|
+
opts[n] = @option.send(n) if @option.send(n)
|
46
|
+
end
|
47
|
+
|
48
|
+
puts "Creating #{opts[:size]} instance in #{@@global.zone}"
|
49
|
+
|
50
|
+
unless opts[:keypair]
|
51
|
+
puts "You did not specify a keypair. Unless you've prepared a user account".color(:blue)
|
52
|
+
puts "on this image (#{opts[:ami]}) you will not be able to log in to it.".color(:blue)
|
53
|
+
exit unless Annoy.proceed?(:low)
|
54
|
+
end
|
55
|
+
|
56
|
+
instances = rinst.list_group(opts[:group], :running)
|
57
|
+
|
58
|
+
if instances && instances.size > 0
|
59
|
+
instance_count = (instances.size == 1) ? 'is 1 instance' : "are #{instances.size} instances"
|
60
|
+
puts "There #{instance_count} running in the #{opts[:group]} group."
|
61
|
+
exit unless Annoy.proceed?(:low)
|
62
|
+
end
|
63
|
+
|
64
|
+
if @option.newaddress
|
65
|
+
print "Creating address... "
|
66
|
+
address = radd.create
|
67
|
+
puts "#{address.ipaddress}"
|
68
|
+
@option.address = address.ipaddress
|
69
|
+
end
|
70
|
+
|
71
|
+
execute_action do
|
72
|
+
first_instance = true
|
73
|
+
rinst.create(opts) do |inst| # Rudy::AWS::EC2::Instance objects
|
74
|
+
|
75
|
+
# Assign IP address to only the first instance
|
76
|
+
if first_instance && @option.address
|
77
|
+
puts "Associating #{@option.address} to #{inst.awsid}"
|
78
|
+
radd.associate(@option.address, inst.awsid)
|
79
|
+
first_instance = false
|
80
|
+
end
|
81
|
+
|
82
|
+
puts @@global.verbose > 0 ? inst.inspect : inst.dump(@@global.format)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def instances_restart_valid?
|
88
|
+
raise InstanceAndGroupError.new(nil, @alias) if @option.group && @argv.instid
|
89
|
+
raise NoInstanceError.new(nil, @alias) if !@option.group && !@argv.instid
|
90
|
+
|
91
|
+
if @option.group
|
92
|
+
rgroup = Rudy::AWS::EC2::Groups.new(@@global.accesskey, @@global.secretkey, @@global.region)
|
93
|
+
raise "Group #{@option.group} does not exist" unless rgroup.exists?(@option.group)
|
94
|
+
end
|
95
|
+
|
96
|
+
if @option.private
|
97
|
+
raise Drydock::OptsError.new(nil, @alias, "Cannot allocate public IP for private instance") if @option.address || @option.newadress
|
98
|
+
end
|
99
|
+
|
100
|
+
@rinst = Rudy::AWS::EC2::Instances.new(@@global.accesskey, @@global.secretkey, @@global.region)
|
101
|
+
raise "No instances" unless @rinst.any?
|
102
|
+
true
|
103
|
+
end
|
104
|
+
alias :instances_destroy_valid? :instances_restart_valid?
|
105
|
+
|
106
|
+
def instances_destroy
|
107
|
+
instances_action :destroy
|
108
|
+
end
|
109
|
+
|
110
|
+
def instances_restart
|
111
|
+
instances_action :restart
|
112
|
+
end
|
113
|
+
|
114
|
+
def consoles_valid?
|
115
|
+
@rinst = Rudy::AWS::EC2::Instances.new(@@global.accesskey, @@global.secretkey, @@global.region)
|
116
|
+
raise "No instances" unless @rinst.any?
|
117
|
+
true
|
118
|
+
end
|
119
|
+
def consoles
|
120
|
+
opts = {}
|
121
|
+
opts[:group] = @option.group if @option.group
|
122
|
+
opts[:id] = @argv.instid if @argv.instid
|
123
|
+
opts[:id] &&= [opts[:id]].flatten
|
124
|
+
|
125
|
+
lt = @rinst.list_group(opts[:group], :any, opts[:id]) do |inst|
|
126
|
+
puts '-'*50
|
127
|
+
puts "Console for: #{inst.liner_note}", $/
|
128
|
+
console = @rinst.console(inst.awsid)
|
129
|
+
output = console ? Base64.decode64(console) : "Unavailable"
|
130
|
+
puts output.noansi # Remove color and clear, etc...
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
def status
|
136
|
+
opts = {}
|
137
|
+
|
138
|
+
opts[:group] = @option.group if @option.group
|
139
|
+
opts[:state] = @option.state if @option.state
|
140
|
+
|
141
|
+
# A nil value forces the @ec2.instances.list to return all instances
|
142
|
+
if @option.all
|
143
|
+
opts[:state] = :any
|
144
|
+
opts[:group] = :any
|
145
|
+
end
|
146
|
+
|
147
|
+
opts[:id] = @argv.instid if @argv.instid
|
148
|
+
opts[:id] &&= [opts[:id]].flatten
|
149
|
+
|
150
|
+
rudy = Rudy::AWS::EC2::Instances.new(@@global.accesskey, @@global.secretkey, @@global.region)
|
151
|
+
lt = rudy.list_group(opts[:group], opts[:state], opts[:id]) do |inst|
|
152
|
+
puts @@global.verbose > 0 ? inst.inspect : inst.dump(@@global.format)
|
153
|
+
end
|
154
|
+
puts "No instances running" if !lt || lt.empty?
|
155
|
+
end
|
156
|
+
alias :instances :status
|
157
|
+
|
158
|
+
|
159
|
+
private
|
160
|
+
|
161
|
+
# * +action+ is one of :destroy, :restart
|
162
|
+
def instances_action(action)
|
163
|
+
opts = {}
|
164
|
+
opts[:group] = @option.group if @option.group
|
165
|
+
opts[:id] = @argv.instid if @argv.instid
|
166
|
+
opts[:id] &&= [opts[:id]].flatten
|
167
|
+
|
168
|
+
instances = @rinst.list_group(opts[:group], :running, opts[:id])
|
169
|
+
raise "No matching instances running" if instances.nil?
|
170
|
+
|
171
|
+
inst_names = instances.collect { |inst| inst.dns_public || inst.awsid }
|
172
|
+
inst_ids = instances.collect { |inst| inst.awsid }
|
173
|
+
|
174
|
+
instance_count = (instances.size == 1) ? '1 instance' : "#{instances.size} instances"
|
175
|
+
|
176
|
+
print "#{action.to_s.capitalize} #{instance_count} (#{inst_names.join(', ')}) "
|
177
|
+
print "in #{opts[:group]}" if opts[:group]
|
178
|
+
puts
|
179
|
+
execute_check(:medium)
|
180
|
+
|
181
|
+
execute_action("#{action.to_s.capitalize} Failed") {
|
182
|
+
@rinst.send(action, inst_ids)
|
183
|
+
}
|
184
|
+
status
|
185
|
+
end
|
186
|
+
|
187
|
+
|
188
|
+
end
|
189
|
+
|
190
|
+
end; end
|
191
|
+
end; end
|
192
|
+
|
193
|
+
|
194
|
+
|