bbcloud 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/LICENSE +19 -0
- data/README +34 -0
- data/Rakefile +2 -0
- data/bbcloud.gemspec +29 -0
- data/bin/brightbox-accounts +9 -0
- data/bin/brightbox-cloudips +9 -0
- data/bin/brightbox-config +9 -0
- data/bin/brightbox-images +9 -0
- data/bin/brightbox-servers +9 -0
- data/bin/brightbox-types +9 -0
- data/bin/brightbox-users +9 -0
- data/bin/brightbox-zones +9 -0
- data/lib/bbcloud/accounts.rb +39 -0
- data/lib/bbcloud/api.rb +107 -0
- data/lib/bbcloud/cli.rb +127 -0
- data/lib/bbcloud/cloud_ips.rb +40 -0
- data/lib/bbcloud/commands/accounts-list.rb +9 -0
- data/lib/bbcloud/commands/accounts-reset-ftp-password.rb +27 -0
- data/lib/bbcloud/commands/accounts-show.rb +18 -0
- data/lib/bbcloud/commands/cloudips-create.rb +21 -0
- data/lib/bbcloud/commands/cloudips-destroy.rb +37 -0
- data/lib/bbcloud/commands/cloudips-list.rb +11 -0
- data/lib/bbcloud/commands/cloudips-map.rb +55 -0
- data/lib/bbcloud/commands/cloudips-show.rb +13 -0
- data/lib/bbcloud/commands/cloudips-unmap.rb +32 -0
- data/lib/bbcloud/commands/config-client-add.rb +45 -0
- data/lib/bbcloud/commands/config-client-default.rb +24 -0
- data/lib/bbcloud/commands/config-client-remove.rb +25 -0
- data/lib/bbcloud/commands/images-destroy.rb +18 -0
- data/lib/bbcloud/commands/images-list.rb +19 -0
- data/lib/bbcloud/commands/images-show.rb +17 -0
- data/lib/bbcloud/commands/servers-create.rb +65 -0
- data/lib/bbcloud/commands/servers-destroy.rb +25 -0
- data/lib/bbcloud/commands/servers-list.rb +13 -0
- data/lib/bbcloud/commands/servers-restart.rb +30 -0
- data/lib/bbcloud/commands/servers-show.rb +47 -0
- data/lib/bbcloud/commands/servers-shutdown.rb +17 -0
- data/lib/bbcloud/commands/servers-snapshot.rb +17 -0
- data/lib/bbcloud/commands/servers-start.rb +18 -0
- data/lib/bbcloud/commands/servers-stop.rb +18 -0
- data/lib/bbcloud/commands/types-list.rb +10 -0
- data/lib/bbcloud/commands/types-show.rb +22 -0
- data/lib/bbcloud/commands/users-list.rb +10 -0
- data/lib/bbcloud/commands/users-show.rb +27 -0
- data/lib/bbcloud/commands/users-update.rb +39 -0
- data/lib/bbcloud/commands/zones-list.rb +9 -0
- data/lib/bbcloud/config.rb +92 -0
- data/lib/bbcloud/images.rb +44 -0
- data/lib/bbcloud/servers.rb +66 -0
- data/lib/bbcloud/tables.rb +95 -0
- data/lib/bbcloud/types.rb +43 -0
- data/lib/bbcloud/users.rb +47 -0
- data/lib/bbcloud/vendor/hirb/.gemspec +22 -0
- data/lib/bbcloud/vendor/hirb/CHANGELOG.rdoc +106 -0
- data/lib/bbcloud/vendor/hirb/LICENSE.txt +22 -0
- data/lib/bbcloud/vendor/hirb/README.rdoc +182 -0
- data/lib/bbcloud/vendor/hirb/Rakefile +35 -0
- data/lib/bbcloud/vendor/hirb/lib/bond/completions/hirb.rb +15 -0
- data/lib/bbcloud/vendor/hirb/lib/hirb/console.rb +43 -0
- data/lib/bbcloud/vendor/hirb/lib/hirb/dynamic_view.rb +113 -0
- data/lib/bbcloud/vendor/hirb/lib/hirb/formatter.rb +116 -0
- data/lib/bbcloud/vendor/hirb/lib/hirb/helpers/auto_table.rb +24 -0
- data/lib/bbcloud/vendor/hirb/lib/hirb/helpers/object_table.rb +14 -0
- data/lib/bbcloud/vendor/hirb/lib/hirb/helpers/parent_child_tree.rb +24 -0
- data/lib/bbcloud/vendor/hirb/lib/hirb/helpers/table/filters.rb +10 -0
- data/lib/bbcloud/vendor/hirb/lib/hirb/helpers/table/resizer.rb +82 -0
- data/lib/bbcloud/vendor/hirb/lib/hirb/helpers/table.rb +323 -0
- data/lib/bbcloud/vendor/hirb/lib/hirb/helpers/tree.rb +181 -0
- data/lib/bbcloud/vendor/hirb/lib/hirb/helpers/vertical_table.rb +37 -0
- data/lib/bbcloud/vendor/hirb/lib/hirb/helpers.rb +17 -0
- data/lib/bbcloud/vendor/hirb/lib/hirb/import_object.rb +10 -0
- data/lib/bbcloud/vendor/hirb/lib/hirb/menu.rb +221 -0
- data/lib/bbcloud/vendor/hirb/lib/hirb/pager.rb +95 -0
- data/lib/bbcloud/vendor/hirb/lib/hirb/string.rb +44 -0
- data/lib/bbcloud/vendor/hirb/lib/hirb/util.rb +96 -0
- data/lib/bbcloud/vendor/hirb/lib/hirb/version.rb +3 -0
- data/lib/bbcloud/vendor/hirb/lib/hirb/view.rb +284 -0
- data/lib/bbcloud/vendor/hirb/lib/hirb/views/couch_db.rb +11 -0
- data/lib/bbcloud/vendor/hirb/lib/hirb/views/misc_db.rb +15 -0
- data/lib/bbcloud/vendor/hirb/lib/hirb/views/mongo_db.rb +14 -0
- data/lib/bbcloud/vendor/hirb/lib/hirb/views/orm.rb +11 -0
- data/lib/bbcloud/vendor/hirb/lib/hirb/views/rails.rb +19 -0
- data/lib/bbcloud/vendor/hirb/lib/hirb/views.rb +8 -0
- data/lib/bbcloud/vendor/hirb/lib/hirb.rb +81 -0
- data/lib/bbcloud/vendor/hirb/test/auto_table_test.rb +30 -0
- data/lib/bbcloud/vendor/hirb/test/console_test.rb +27 -0
- data/lib/bbcloud/vendor/hirb/test/deps.rip +4 -0
- data/lib/bbcloud/vendor/hirb/test/dynamic_view_test.rb +94 -0
- data/lib/bbcloud/vendor/hirb/test/formatter_test.rb +171 -0
- data/lib/bbcloud/vendor/hirb/test/hirb_test.rb +39 -0
- data/lib/bbcloud/vendor/hirb/test/import_test.rb +9 -0
- data/lib/bbcloud/vendor/hirb/test/menu_test.rb +239 -0
- data/lib/bbcloud/vendor/hirb/test/object_table_test.rb +79 -0
- data/lib/bbcloud/vendor/hirb/test/pager_test.rb +162 -0
- data/lib/bbcloud/vendor/hirb/test/resizer_test.rb +62 -0
- data/lib/bbcloud/vendor/hirb/test/table_test.rb +550 -0
- data/lib/bbcloud/vendor/hirb/test/test_helper.rb +61 -0
- data/lib/bbcloud/vendor/hirb/test/tree_test.rb +184 -0
- data/lib/bbcloud/vendor/hirb/test/util_test.rb +59 -0
- data/lib/bbcloud/vendor/hirb/test/view_test.rb +172 -0
- data/lib/bbcloud/vendor/hirb/test/views_test.rb +13 -0
- data/lib/bbcloud/version.rb +3 -0
- data/lib/bbcloud/zones.rb +27 -0
- metadata +241 -0
@@ -0,0 +1,13 @@
|
|
1
|
+
desc 'show details on Cloud IPs'
|
2
|
+
arg_name 'cloudip-id...'
|
3
|
+
command [:show] do |c|
|
4
|
+
|
5
|
+
c.action do |global_options,options,args|
|
6
|
+
|
7
|
+
ips = CloudIP.find args
|
8
|
+
|
9
|
+
fields = [:id, :status, :public_ip, :reverse_dns, :server_id, :interface_id]
|
10
|
+
|
11
|
+
render_table(ips.compact, global_options.merge({ :vertical => true, :fields => fields}))
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
desc 'unmap Cloud IPs'
|
2
|
+
arg_name 'cloudip-id...'
|
3
|
+
command [:unmap] do |c|
|
4
|
+
|
5
|
+
c.action do |global_options,options,args|
|
6
|
+
|
7
|
+
raise "you must specify the cloud ip ids to unmap as arguments" if args.empty?
|
8
|
+
|
9
|
+
ips = CloudIP.find args
|
10
|
+
|
11
|
+
ips.compact!
|
12
|
+
|
13
|
+
ips.each do |ip|
|
14
|
+
if ip.mapped?
|
15
|
+
info "Unmapping cloud ip #{ip}"
|
16
|
+
ip.unmap
|
17
|
+
ip.reload
|
18
|
+
else
|
19
|
+
warn "Cloud ip #{ip} already unmapped"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Wait up to 3 seconds for unmapping to complete
|
24
|
+
3.times do
|
25
|
+
break unless ips.find { |ip| ip.mapped? }
|
26
|
+
sleep 1
|
27
|
+
ips.each { |ip| ip.reload if ip.mapped? }
|
28
|
+
end
|
29
|
+
|
30
|
+
render_table(ips, global_options)
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
desc 'Add new api client details to config'
|
2
|
+
arg_name 'client-id secret [api_url, auth_url]'
|
3
|
+
command [:client_add] do |c|
|
4
|
+
|
5
|
+
c.desc "api client alias, for local reference (defaults to client-id)"
|
6
|
+
c.flag [:a, "alias"]
|
7
|
+
|
8
|
+
c.desc "auth url"
|
9
|
+
c.flag [:t, "auth-url"]
|
10
|
+
|
11
|
+
c.action do |global_options, options, args|
|
12
|
+
|
13
|
+
info "Using config file #{CONFIG.config_filename}"
|
14
|
+
|
15
|
+
client_id = args.shift
|
16
|
+
secret = args.shift
|
17
|
+
api_url = args.shift || "https://api.gb1.brightbox.com"
|
18
|
+
auth_url = args.shift || api_url
|
19
|
+
calias = options[:a] || client_id
|
20
|
+
|
21
|
+
if client_id.nil?
|
22
|
+
raise "You must specify the api client-id"
|
23
|
+
end
|
24
|
+
|
25
|
+
if secret.nil?
|
26
|
+
raise "You must specify the api secret"
|
27
|
+
end
|
28
|
+
|
29
|
+
client_config = CONFIG[calias]
|
30
|
+
unless client_config.empty?
|
31
|
+
raise "An api client with the id or alias #{calias} already exists"
|
32
|
+
end
|
33
|
+
|
34
|
+
info "Creating new api client config #{calias}"
|
35
|
+
|
36
|
+
client_config['alias'] = calias
|
37
|
+
client_config['client_id'] = client_id
|
38
|
+
client_config['secret'] = secret
|
39
|
+
client_config['api_url'] = api_url
|
40
|
+
client_config['auth_url'] = auth_url
|
41
|
+
|
42
|
+
CONFIG.save!
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
desc 'Set the default api client in the config'
|
2
|
+
arg_name 'alias'
|
3
|
+
command [:client_default] do |c|
|
4
|
+
|
5
|
+
c.action do |global_options, options, args|
|
6
|
+
|
7
|
+
info "Using config file #{CONFIG.config_filename}"
|
8
|
+
calias = args.shift
|
9
|
+
|
10
|
+
if calias.nil?
|
11
|
+
raise "You must specify the api alias you want to set as the default"
|
12
|
+
end
|
13
|
+
|
14
|
+
client_config = CONFIG[calias]
|
15
|
+
if client_config.empty?
|
16
|
+
raise "An api client with the alias #{calias} does not exist in the config"
|
17
|
+
end
|
18
|
+
|
19
|
+
info "Setting #{calias} as default api client"
|
20
|
+
CONFIG['core']['default_client'] = calias
|
21
|
+
CONFIG.save!
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
desc 'Remove api client details from config'
|
2
|
+
arg_name 'alias'
|
3
|
+
command [:client_remove] do |c|
|
4
|
+
|
5
|
+
c.action do |global_options, options, args|
|
6
|
+
|
7
|
+
info "Using config file #{CONFIG.config_filename}"
|
8
|
+
|
9
|
+
calias = args.shift
|
10
|
+
|
11
|
+
if calias.nil?
|
12
|
+
raise "You must specify the api alias you want to remove"
|
13
|
+
end
|
14
|
+
|
15
|
+
client_config = CONFIG[calias]
|
16
|
+
if client_config.empty?
|
17
|
+
raise "An api client with alias #{calias} does not exist in the config"
|
18
|
+
end
|
19
|
+
|
20
|
+
info "Removing api client #{calias}"
|
21
|
+
CONFIG.delete_section calias
|
22
|
+
CONFIG.save!
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
desc 'Destroy images'
|
2
|
+
arg_name 'image-id...'
|
3
|
+
command [:destroy] do |c|
|
4
|
+
|
5
|
+
c.action do |global_options,options,args|
|
6
|
+
|
7
|
+
images = Image.find(args).compact
|
8
|
+
|
9
|
+
images.each do |i|
|
10
|
+
info "Destroying image #{i}"
|
11
|
+
i.destroy
|
12
|
+
i.reload
|
13
|
+
end
|
14
|
+
|
15
|
+
render_table(images)
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
desc 'List available images'
|
2
|
+
arg_name '[image-id...]'
|
3
|
+
command [:list] do |c|
|
4
|
+
c.action do |global_options, options, args|
|
5
|
+
images = Image.find args
|
6
|
+
|
7
|
+
snapshots = images.select { |i| i.source_type == 'snapshot' }
|
8
|
+
|
9
|
+
images = images - snapshots
|
10
|
+
|
11
|
+
images.sort! do |a,b|
|
12
|
+
[a.official ? 0 : 1, a.name, a.arch] <=> [b.official ? 0 : 1, b.name, b.arch]
|
13
|
+
end
|
14
|
+
|
15
|
+
snapshots.sort! { |a, b| a.created_at <=> b.created_at }
|
16
|
+
|
17
|
+
render_table(images + snapshots, global_options)
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
desc 'Show detailed image info'
|
2
|
+
arg_name 'image-id...'
|
3
|
+
command [:show] do |c|
|
4
|
+
|
5
|
+
c.action do |global_options,options,args|
|
6
|
+
|
7
|
+
images = Image.find(args).compact
|
8
|
+
|
9
|
+
table_opts = global_options.merge({
|
10
|
+
:vertical => true,
|
11
|
+
:fields => [:id, :type, :owner, :created_at, :status, :arch, :name, :description, :virtual_size, :disk_size, :ancestor_id ]
|
12
|
+
})
|
13
|
+
|
14
|
+
render_table(images, table_opts)
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
desc 'Create servers'
|
2
|
+
arg_name 'image_id'
|
3
|
+
command [:create] do |c|
|
4
|
+
c.desc "Number of servers to create"
|
5
|
+
c.default_value 1
|
6
|
+
c.flag [:i, "server-count"]
|
7
|
+
|
8
|
+
c.desc "Zone to create the servers in"
|
9
|
+
c.flag [:z, "zone"]
|
10
|
+
|
11
|
+
c.desc "Type of server to create"
|
12
|
+
c.default_value "nano"
|
13
|
+
c.flag [:t, :type]
|
14
|
+
|
15
|
+
c.desc "Friendly name of server"
|
16
|
+
c.flag [:n, :name]
|
17
|
+
|
18
|
+
|
19
|
+
c.action do |global_options, options, args|
|
20
|
+
|
21
|
+
if args.empty?
|
22
|
+
raise "You must specify the image_id as the first argument"
|
23
|
+
end
|
24
|
+
|
25
|
+
if options[:i].to_s !~ /^[0-9]+$/
|
26
|
+
raise "server-count must be a number"
|
27
|
+
end
|
28
|
+
|
29
|
+
options[:i] = options[:i].to_i
|
30
|
+
|
31
|
+
image_id = args.shift
|
32
|
+
image = Image.find image_id
|
33
|
+
raise "Couldn't find image #{image_id}" unless image
|
34
|
+
|
35
|
+
type_id = options[:t]
|
36
|
+
if type_id =~ /^typ\-/
|
37
|
+
type = Type.find type_id
|
38
|
+
else
|
39
|
+
type = Type.find_by_handle type_id
|
40
|
+
end
|
41
|
+
raise "Couldn't find server type #{type_id}" unless type
|
42
|
+
|
43
|
+
if options[:z]
|
44
|
+
zone = options[:z]
|
45
|
+
if zone =~ /^typ\-/
|
46
|
+
zone = Zone.find zone
|
47
|
+
else
|
48
|
+
zone = Zone.find_by_handle zone
|
49
|
+
end
|
50
|
+
end
|
51
|
+
raise "Couldn't find server type #{type_id}" unless type
|
52
|
+
|
53
|
+
msg = "Creating #{options[:i]} '#{type.handle}' (#{type.id}) server#{options[:i] > 1 ? 's' : ''} with image #{image.name.strip} (#{image.id})"
|
54
|
+
msg << " in zone #{zone.handle} (#{zone})" if zone
|
55
|
+
info msg
|
56
|
+
servers = []
|
57
|
+
options[:i].times do
|
58
|
+
servers << Server.create(:image_id => image.id,
|
59
|
+
:flavor_id => type.id,
|
60
|
+
:zone_id => zone.to_s,
|
61
|
+
:name => options[:n])
|
62
|
+
end
|
63
|
+
render_table(servers, global_options)
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
desc 'Destroy servers'
|
2
|
+
arg_name '[server-id...]'
|
3
|
+
command [:destroy] do |c|
|
4
|
+
c.action do |global_options, options, args|
|
5
|
+
|
6
|
+
if args.empty?
|
7
|
+
raise "you must specify the id of the server(s) you want to destroy"
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
servers = args.collect do |sid|
|
12
|
+
info "Destroying server #{sid}"
|
13
|
+
server = Server.find sid
|
14
|
+
begin
|
15
|
+
server.destroy
|
16
|
+
rescue Brightbox::Api::Conflict => e
|
17
|
+
error "Could not destroy #{sid}"
|
18
|
+
end
|
19
|
+
server.reload
|
20
|
+
server
|
21
|
+
end
|
22
|
+
|
23
|
+
render_table(servers, global_options)
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
desc 'Restart the specified servers'
|
2
|
+
arg_name 'server-id...'
|
3
|
+
command [:restart] do |c|
|
4
|
+
c.desc "Soft restart (default)"
|
5
|
+
c.switch [:s, "soft"]
|
6
|
+
|
7
|
+
c.desc "Hard restart"
|
8
|
+
c.default_value true
|
9
|
+
c.switch [:d, "hard"]
|
10
|
+
|
11
|
+
c.action do |global_options,options,args|
|
12
|
+
|
13
|
+
if options[:soft] and options[:hard]
|
14
|
+
raise "Cannot do both hard and soft restart at the same time"
|
15
|
+
end
|
16
|
+
|
17
|
+
type = options[:hard] ? "hard" : "soft"
|
18
|
+
|
19
|
+
servers = Server.find(args).compact
|
20
|
+
|
21
|
+
servers.each do |s|
|
22
|
+
info "Restarting server #{s}"
|
23
|
+
s.reboot(type)
|
24
|
+
s.reload
|
25
|
+
end
|
26
|
+
|
27
|
+
render_table(servers)
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
desc 'Show detailed server info'
|
2
|
+
arg_name 'server-id...'
|
3
|
+
command [:show] do |c|
|
4
|
+
|
5
|
+
c.action do |global_options,options,args|
|
6
|
+
|
7
|
+
servers = Server.find(args)
|
8
|
+
rows = []
|
9
|
+
servers.each do |s|
|
10
|
+
if s.is_a? String
|
11
|
+
error "Could not find server #{s}"
|
12
|
+
next
|
13
|
+
end
|
14
|
+
o = s.to_row
|
15
|
+
if s.server_type.exists?
|
16
|
+
o[:type] = s.server_type.id
|
17
|
+
o[:type_handle] = s.server_type.handle
|
18
|
+
o[:type_name] = s.server_type.name
|
19
|
+
o[:ram] = s.server_type.ram
|
20
|
+
o[:cores] = s.server_type.cores
|
21
|
+
o[:disk] = s.server_type.disk.to_i
|
22
|
+
end
|
23
|
+
|
24
|
+
if s.image.exists? and false
|
25
|
+
o[:image_name] = s.image.name
|
26
|
+
o[:arch] = s.image.arch
|
27
|
+
end
|
28
|
+
o[:private_ips] = s.interfaces.collect { |i| i['ipv4_address'] }.join(", ")
|
29
|
+
o[:cloud_ip_ids] = s.cloud_ips.collect { |i| i['id'] }.join(", ")
|
30
|
+
o[:cloud_ips] = s.cloud_ips.collect { |i| i['public_ip'] }.join(", ")
|
31
|
+
o[:snapshots] = s.snapshots.collect { |i| i['id'] }.join(", ")
|
32
|
+
rows << o
|
33
|
+
end
|
34
|
+
|
35
|
+
table_opts = global_options.merge({
|
36
|
+
:vertical => true,
|
37
|
+
:fields => [:id, :status, :name, :description, :created_at, :deleted_at,
|
38
|
+
:zone, :type, :type_name, :type_handle, :ram, :cores,
|
39
|
+
:disk, :image, :image_name, :private_ips, :cloud_ips,
|
40
|
+
:cloud_ip_ids, :hostname, :public_hostname, :snapshots
|
41
|
+
]
|
42
|
+
})
|
43
|
+
|
44
|
+
render_table(rows, table_opts)
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
desc 'Shutdown the specified servers'
|
2
|
+
arg_name 'server-id...'
|
3
|
+
command [:shutdown] do |c|
|
4
|
+
c.action do |global_options,options,args|
|
5
|
+
|
6
|
+
servers = Server.find(args).compact
|
7
|
+
|
8
|
+
servers.each do |s|
|
9
|
+
info "Shutting down server #{s}"
|
10
|
+
s.shutdown
|
11
|
+
s.reload
|
12
|
+
end
|
13
|
+
|
14
|
+
render_table(servers)
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
desc 'Snapshot the specified servers'
|
2
|
+
arg_name 'server-id...'
|
3
|
+
command [:snapshot] do |c|
|
4
|
+
|
5
|
+
c.action do |global_options,options,args|
|
6
|
+
|
7
|
+
servers = Server.find(args).compact
|
8
|
+
|
9
|
+
servers.each do |s|
|
10
|
+
info "Snapshotting server #{s}"
|
11
|
+
s.snapshot
|
12
|
+
end
|
13
|
+
|
14
|
+
render_table(servers)
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
desc 'Start the specified servers'
|
2
|
+
arg_name 'server-id...'
|
3
|
+
command [:start] do |c|
|
4
|
+
|
5
|
+
c.action do |global_options,options,args|
|
6
|
+
|
7
|
+
servers = Server.find(args).compact
|
8
|
+
|
9
|
+
servers.each do |s|
|
10
|
+
info "Starting server #{s}"
|
11
|
+
s.start
|
12
|
+
s.reload
|
13
|
+
end
|
14
|
+
|
15
|
+
render_table(servers)
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
desc 'Stop the specified servers'
|
2
|
+
arg_name 'server-id...'
|
3
|
+
command [:stop] do |c|
|
4
|
+
|
5
|
+
c.action do |global_options,options,args|
|
6
|
+
|
7
|
+
servers = Server.find(args).compact
|
8
|
+
|
9
|
+
servers.each do |s|
|
10
|
+
info "Stopping server #{s}"
|
11
|
+
s.stop
|
12
|
+
s.reload
|
13
|
+
end
|
14
|
+
|
15
|
+
render_table(servers)
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
desc 'Show detailed type info'
|
2
|
+
arg_name 'type-id...'
|
3
|
+
command [:show] do |c|
|
4
|
+
|
5
|
+
c.action do |global_options,options,args|
|
6
|
+
|
7
|
+
types = Type.find(args)
|
8
|
+
rows = []
|
9
|
+
types.each do |t|
|
10
|
+
next if t.nil?
|
11
|
+
rows << t
|
12
|
+
end
|
13
|
+
|
14
|
+
table_opts = global_options.merge({
|
15
|
+
:vertical => true,
|
16
|
+
:fields => [:id, :handle, :status, :name, :ram, :disk, :cores, :description]
|
17
|
+
})
|
18
|
+
|
19
|
+
render_table(rows, table_opts)
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
desc 'Show detailed user info'
|
2
|
+
arg_name 'user-id...'
|
3
|
+
command [:show] do |c|
|
4
|
+
|
5
|
+
c.action do |global_options,options,args|
|
6
|
+
|
7
|
+
users = User.find(args)
|
8
|
+
|
9
|
+
rows = []
|
10
|
+
|
11
|
+
users.each do |s|
|
12
|
+
s.reload # to get ssh_key
|
13
|
+
o = s.to_row
|
14
|
+
o[:ssh_key] = s.ssh_key.to_s.strip
|
15
|
+
o[:accounts] = s.accounts.collect { |a| a.id }.join(", ")
|
16
|
+
rows << o
|
17
|
+
end
|
18
|
+
|
19
|
+
table_opts = global_options.merge({
|
20
|
+
:vertical => true,
|
21
|
+
:fields => [:id, :name, :email_address, :accounts, :ssh_key ]
|
22
|
+
})
|
23
|
+
|
24
|
+
render_table(rows, table_opts)
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
desc 'Update user details'
|
2
|
+
arg_name 'user-id...'
|
3
|
+
command [:update] do |c|
|
4
|
+
c.desc "Path to public ssh key file"
|
5
|
+
c.long_desc "This is the path to the public ssh key that you'd like to use for new servers. You can specify '-' to read from stdin"
|
6
|
+
c.flag [:f, "ssh-key"]
|
7
|
+
|
8
|
+
c.desc "Name"
|
9
|
+
c.flag [:n, "name"]
|
10
|
+
|
11
|
+
c.action do |global_options, options, args|
|
12
|
+
|
13
|
+
raise "You must specify the user id as the first argument" if args.empty?
|
14
|
+
|
15
|
+
user = User.find args.first
|
16
|
+
|
17
|
+
raise "Could not find user #{args.first}" if user.nil?
|
18
|
+
|
19
|
+
if options[:f] == '-'
|
20
|
+
user.ssh_key = STDIN.read
|
21
|
+
elsif options[:f]
|
22
|
+
File.open(File.expand_path(options[:f])) { |f| user.ssh_key = f.read }
|
23
|
+
end
|
24
|
+
|
25
|
+
if options[:n]
|
26
|
+
user.name = options[:n]
|
27
|
+
end
|
28
|
+
|
29
|
+
user.save
|
30
|
+
|
31
|
+
table_opts = global_options.merge({
|
32
|
+
:vertical => true,
|
33
|
+
:fields => [:id, :name, :email_address, :ssh_key ]
|
34
|
+
})
|
35
|
+
|
36
|
+
render_table([user], table_opts)
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
class BBConfigError < StandardError ; end
|
2
|
+
|
3
|
+
class BBConfig
|
4
|
+
require 'fileutils'
|
5
|
+
require 'ini'
|
6
|
+
|
7
|
+
attr_writer :client_name
|
8
|
+
|
9
|
+
def initialize(options = {})
|
10
|
+
@options = options
|
11
|
+
end
|
12
|
+
|
13
|
+
def dir
|
14
|
+
return @dir if @dir
|
15
|
+
return nil if @dir == false
|
16
|
+
@dir = File.expand_path(@options[:dir] || "~/.brightbox")
|
17
|
+
@config_filename = File.join(@dir, 'config')
|
18
|
+
# Make the directory if necessary
|
19
|
+
unless File.exists? @dir
|
20
|
+
begin
|
21
|
+
FileUtils.mkdir @dir
|
22
|
+
rescue Errno::EEXIST
|
23
|
+
end
|
24
|
+
end
|
25
|
+
#
|
26
|
+
if File.directory? @dir
|
27
|
+
@dir
|
28
|
+
else
|
29
|
+
@dir = false
|
30
|
+
nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def config_filename
|
35
|
+
dir
|
36
|
+
@config_filename
|
37
|
+
end
|
38
|
+
|
39
|
+
def config
|
40
|
+
return @config if @config
|
41
|
+
return {} if @config == false
|
42
|
+
@config ||= Ini.new config_filename
|
43
|
+
@config
|
44
|
+
rescue Ini::Error => e
|
45
|
+
raise BBConfigError, "Config problem in #{config_filename}: #{e}"
|
46
|
+
end
|
47
|
+
|
48
|
+
def [](k)
|
49
|
+
config[k]
|
50
|
+
end
|
51
|
+
|
52
|
+
def delete_section(name)
|
53
|
+
config.delete_section name
|
54
|
+
end
|
55
|
+
|
56
|
+
def save!
|
57
|
+
if @config.is_a? Ini
|
58
|
+
@config.write
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def clients
|
63
|
+
config.sections.find_all { |s| s != 'core' }
|
64
|
+
end
|
65
|
+
|
66
|
+
def client_name
|
67
|
+
if @client_name
|
68
|
+
@client_name
|
69
|
+
else
|
70
|
+
default_client = config['core']['default_client']
|
71
|
+
@client_name = default_client || clients.first
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def to_fog
|
76
|
+
raise Ini::Error, "No api client configured" if clients.empty?
|
77
|
+
c = config[client_name]
|
78
|
+
%w{api_url client_id secret}.each do |k|
|
79
|
+
if c[k].to_s.empty?
|
80
|
+
raise BBConfigError, "#{k} option missing from config in section #{client_name}"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
{
|
84
|
+
:brightbox_api_url => c['api_url'],
|
85
|
+
:brightbox_auth_url => c['auth_url'] || c['api_url'],
|
86
|
+
:brightbox_client_id => c['client_id'],
|
87
|
+
:brightbox_secret => c['secret']
|
88
|
+
}
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
end
|