bbcloud 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. data/.gitignore +4 -0
  2. data/LICENSE +19 -0
  3. data/README +34 -0
  4. data/Rakefile +2 -0
  5. data/bbcloud.gemspec +29 -0
  6. data/bin/brightbox-accounts +9 -0
  7. data/bin/brightbox-cloudips +9 -0
  8. data/bin/brightbox-config +9 -0
  9. data/bin/brightbox-images +9 -0
  10. data/bin/brightbox-servers +9 -0
  11. data/bin/brightbox-types +9 -0
  12. data/bin/brightbox-users +9 -0
  13. data/bin/brightbox-zones +9 -0
  14. data/lib/bbcloud/accounts.rb +39 -0
  15. data/lib/bbcloud/api.rb +107 -0
  16. data/lib/bbcloud/cli.rb +127 -0
  17. data/lib/bbcloud/cloud_ips.rb +40 -0
  18. data/lib/bbcloud/commands/accounts-list.rb +9 -0
  19. data/lib/bbcloud/commands/accounts-reset-ftp-password.rb +27 -0
  20. data/lib/bbcloud/commands/accounts-show.rb +18 -0
  21. data/lib/bbcloud/commands/cloudips-create.rb +21 -0
  22. data/lib/bbcloud/commands/cloudips-destroy.rb +37 -0
  23. data/lib/bbcloud/commands/cloudips-list.rb +11 -0
  24. data/lib/bbcloud/commands/cloudips-map.rb +55 -0
  25. data/lib/bbcloud/commands/cloudips-show.rb +13 -0
  26. data/lib/bbcloud/commands/cloudips-unmap.rb +32 -0
  27. data/lib/bbcloud/commands/config-client-add.rb +45 -0
  28. data/lib/bbcloud/commands/config-client-default.rb +24 -0
  29. data/lib/bbcloud/commands/config-client-remove.rb +25 -0
  30. data/lib/bbcloud/commands/images-destroy.rb +18 -0
  31. data/lib/bbcloud/commands/images-list.rb +19 -0
  32. data/lib/bbcloud/commands/images-show.rb +17 -0
  33. data/lib/bbcloud/commands/servers-create.rb +65 -0
  34. data/lib/bbcloud/commands/servers-destroy.rb +25 -0
  35. data/lib/bbcloud/commands/servers-list.rb +13 -0
  36. data/lib/bbcloud/commands/servers-restart.rb +30 -0
  37. data/lib/bbcloud/commands/servers-show.rb +47 -0
  38. data/lib/bbcloud/commands/servers-shutdown.rb +17 -0
  39. data/lib/bbcloud/commands/servers-snapshot.rb +17 -0
  40. data/lib/bbcloud/commands/servers-start.rb +18 -0
  41. data/lib/bbcloud/commands/servers-stop.rb +18 -0
  42. data/lib/bbcloud/commands/types-list.rb +10 -0
  43. data/lib/bbcloud/commands/types-show.rb +22 -0
  44. data/lib/bbcloud/commands/users-list.rb +10 -0
  45. data/lib/bbcloud/commands/users-show.rb +27 -0
  46. data/lib/bbcloud/commands/users-update.rb +39 -0
  47. data/lib/bbcloud/commands/zones-list.rb +9 -0
  48. data/lib/bbcloud/config.rb +92 -0
  49. data/lib/bbcloud/images.rb +44 -0
  50. data/lib/bbcloud/servers.rb +66 -0
  51. data/lib/bbcloud/tables.rb +95 -0
  52. data/lib/bbcloud/types.rb +43 -0
  53. data/lib/bbcloud/users.rb +47 -0
  54. data/lib/bbcloud/vendor/hirb/.gemspec +22 -0
  55. data/lib/bbcloud/vendor/hirb/CHANGELOG.rdoc +106 -0
  56. data/lib/bbcloud/vendor/hirb/LICENSE.txt +22 -0
  57. data/lib/bbcloud/vendor/hirb/README.rdoc +182 -0
  58. data/lib/bbcloud/vendor/hirb/Rakefile +35 -0
  59. data/lib/bbcloud/vendor/hirb/lib/bond/completions/hirb.rb +15 -0
  60. data/lib/bbcloud/vendor/hirb/lib/hirb/console.rb +43 -0
  61. data/lib/bbcloud/vendor/hirb/lib/hirb/dynamic_view.rb +113 -0
  62. data/lib/bbcloud/vendor/hirb/lib/hirb/formatter.rb +116 -0
  63. data/lib/bbcloud/vendor/hirb/lib/hirb/helpers/auto_table.rb +24 -0
  64. data/lib/bbcloud/vendor/hirb/lib/hirb/helpers/object_table.rb +14 -0
  65. data/lib/bbcloud/vendor/hirb/lib/hirb/helpers/parent_child_tree.rb +24 -0
  66. data/lib/bbcloud/vendor/hirb/lib/hirb/helpers/table/filters.rb +10 -0
  67. data/lib/bbcloud/vendor/hirb/lib/hirb/helpers/table/resizer.rb +82 -0
  68. data/lib/bbcloud/vendor/hirb/lib/hirb/helpers/table.rb +323 -0
  69. data/lib/bbcloud/vendor/hirb/lib/hirb/helpers/tree.rb +181 -0
  70. data/lib/bbcloud/vendor/hirb/lib/hirb/helpers/vertical_table.rb +37 -0
  71. data/lib/bbcloud/vendor/hirb/lib/hirb/helpers.rb +17 -0
  72. data/lib/bbcloud/vendor/hirb/lib/hirb/import_object.rb +10 -0
  73. data/lib/bbcloud/vendor/hirb/lib/hirb/menu.rb +221 -0
  74. data/lib/bbcloud/vendor/hirb/lib/hirb/pager.rb +95 -0
  75. data/lib/bbcloud/vendor/hirb/lib/hirb/string.rb +44 -0
  76. data/lib/bbcloud/vendor/hirb/lib/hirb/util.rb +96 -0
  77. data/lib/bbcloud/vendor/hirb/lib/hirb/version.rb +3 -0
  78. data/lib/bbcloud/vendor/hirb/lib/hirb/view.rb +284 -0
  79. data/lib/bbcloud/vendor/hirb/lib/hirb/views/couch_db.rb +11 -0
  80. data/lib/bbcloud/vendor/hirb/lib/hirb/views/misc_db.rb +15 -0
  81. data/lib/bbcloud/vendor/hirb/lib/hirb/views/mongo_db.rb +14 -0
  82. data/lib/bbcloud/vendor/hirb/lib/hirb/views/orm.rb +11 -0
  83. data/lib/bbcloud/vendor/hirb/lib/hirb/views/rails.rb +19 -0
  84. data/lib/bbcloud/vendor/hirb/lib/hirb/views.rb +8 -0
  85. data/lib/bbcloud/vendor/hirb/lib/hirb.rb +81 -0
  86. data/lib/bbcloud/vendor/hirb/test/auto_table_test.rb +30 -0
  87. data/lib/bbcloud/vendor/hirb/test/console_test.rb +27 -0
  88. data/lib/bbcloud/vendor/hirb/test/deps.rip +4 -0
  89. data/lib/bbcloud/vendor/hirb/test/dynamic_view_test.rb +94 -0
  90. data/lib/bbcloud/vendor/hirb/test/formatter_test.rb +171 -0
  91. data/lib/bbcloud/vendor/hirb/test/hirb_test.rb +39 -0
  92. data/lib/bbcloud/vendor/hirb/test/import_test.rb +9 -0
  93. data/lib/bbcloud/vendor/hirb/test/menu_test.rb +239 -0
  94. data/lib/bbcloud/vendor/hirb/test/object_table_test.rb +79 -0
  95. data/lib/bbcloud/vendor/hirb/test/pager_test.rb +162 -0
  96. data/lib/bbcloud/vendor/hirb/test/resizer_test.rb +62 -0
  97. data/lib/bbcloud/vendor/hirb/test/table_test.rb +550 -0
  98. data/lib/bbcloud/vendor/hirb/test/test_helper.rb +61 -0
  99. data/lib/bbcloud/vendor/hirb/test/tree_test.rb +184 -0
  100. data/lib/bbcloud/vendor/hirb/test/util_test.rb +59 -0
  101. data/lib/bbcloud/vendor/hirb/test/view_test.rb +172 -0
  102. data/lib/bbcloud/vendor/hirb/test/views_test.rb +13 -0
  103. data/lib/bbcloud/version.rb +3 -0
  104. data/lib/bbcloud/zones.rb +27 -0
  105. 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,13 @@
1
+ desc 'List servers'
2
+ arg_name '[server-id...]'
3
+ command [:list] do |c|
4
+ c.action do |global_options,options,args|
5
+
6
+ Type.cache_all!
7
+ Zone.cache_all!
8
+
9
+ servers = Server.find(args).compact
10
+
11
+ render_table(servers, global_options)
12
+ end
13
+ 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,10 @@
1
+ desc 'List types'
2
+ arg_name '[type-id...]'
3
+ command [:list] do |c|
4
+ c.action do |global_options,options,args|
5
+
6
+ types = Type.find args, :order => :ram
7
+
8
+ render_table(types, global_options)
9
+ end
10
+ 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,10 @@
1
+ desc 'List users'
2
+ arg_name '[user-id...]'
3
+ command [:list] do |c|
4
+ c.action do |global_options, options, args|
5
+
6
+ users = User.find args
7
+
8
+ render_table(users, global_options)
9
+ end
10
+ 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,9 @@
1
+ desc 'List zones'
2
+ arg_name '[zone-id...]'
3
+ command [:list] do |c|
4
+ c.action do |global_options, options, args|
5
+
6
+ zones = Zone.find args
7
+ render_table(zones, global_options)
8
+ end
9
+ 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