brightbox-cli 4.2.1 → 4.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b24f4292c151b1a916960e8a251c3928468ac915ee5f1fe139e8ef3a4d1e0a82
4
- data.tar.gz: f7da261677380fd05cf1e4c3f73021db46c0b24b7da36a8e3820928ca96cfbe4
3
+ metadata.gz: 517f21d7fc3e156180d8558868220e332943bd12ee492754e727d3f23d03d89c
4
+ data.tar.gz: ba05065d1729812c1aa1b41f44767872ea863a8295f8074ae8050742c1903e68
5
5
  SHA512:
6
- metadata.gz: e8eed506ef89c92c2f85d0567fb3e1c8910c3705a209330025d2443ead0fc237bc210d9a5867d9dc92b8331ba9d10d03992640307fcdf5e00575f815af1a8984
7
- data.tar.gz: 49ae72e6347419f04bdb4c2190a0dc7ca2dc5066eda0c831adfe80cf4cec7483be83a3b6feabb1de837827dc97bbe5e0cd891874875e19115a30a523ed9ac3b9
6
+ metadata.gz: 1218d3d1956bac00755dde84bc1546f43dc05f4ea3386420b47745039326ad01f50f016faee353474e620beba0105e059de437085334da2bb4c6545392426880
7
+ data.tar.gz: 8ca4763dfbc21624b85ca97ea70525da34e4a2adb19abb405b2f95b8f8df500180a7780d0d13ffc6bc9cfade8306ed904a0fbbd56e95af1ad33ab913f16c6e7a
data/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ### v4.3.0 / 2023-01-11
2
+
3
+ [Full Changelog](https://github.com/brightbox/brightbox-cli/compare/v4.2.1...v4.3.0)
4
+
5
+ Enhancements:
6
+
7
+ * Adds `volumes` subcommand for Volume management.
8
+
9
+ Changes:
10
+
11
+ * Update `fog-brightbox` to `v1.7.0`
12
+
1
13
  ### v4.2.1 / 2022-11-16
2
14
 
3
15
  [Full Changelog](https://github.com/brightbox/brightbox-cli/compare/v4.2.0...v4.2.1)
@@ -11,7 +23,7 @@ Bug fixes:
11
23
 
12
24
  [Full Changelog](https://github.com/brightbox/brightbox-cli/compare/v4.1.0...v4.2.0)
13
25
 
14
- Changes:
26
+ Enhancements:
15
27
 
16
28
  * Adds three new, mutually exclusive options to `images create` to specify
17
29
  different sources:
@@ -24,7 +36,7 @@ Changes:
24
36
 
25
37
  [Full Changelog](https://github.com/brightbox/brightbox-cli/compare/v4.0.0...v4.1.0)
26
38
 
27
- Changes:
39
+ Enhancements:
28
40
 
29
41
  * Adds `volume-size` to `servers create` to allow passing of arbitrary sizes for
30
42
  network based storage types.
data/Gemfile.lock CHANGED
@@ -1,9 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- brightbox-cli (4.2.1)
4
+ brightbox-cli (4.3.0)
5
5
  dry-inflector (= 0.2.0)
6
- fog-brightbox (>= 1.8.0)
6
+ fog-brightbox (>= 1.9.1)
7
7
  fog-core (< 2.0)
8
8
  gli (~> 2.21)
9
9
  highline (~> 2.0)
@@ -25,8 +25,8 @@ GEM
25
25
  rexml
26
26
  diff-lcs (1.5.0)
27
27
  dry-inflector (0.2.0)
28
- excon (0.94.0)
29
- fog-brightbox (1.8.0)
28
+ excon (0.97.0)
29
+ fog-brightbox (1.9.1)
30
30
  dry-inflector
31
31
  fog-core (>= 1.45, < 3.0)
32
32
  fog-json
@@ -40,7 +40,7 @@ GEM
40
40
  formatador (0.3.0)
41
41
  gli (2.21.0)
42
42
  hashdiff (1.0.1)
43
- highline (2.0.3)
43
+ highline (2.1.0)
44
44
  hirb (0.7.3)
45
45
  i18n (1.10.0)
46
46
  concurrent-ruby (~> 1.0)
@@ -21,7 +21,7 @@ Gem::Specification.new do |s|
21
21
  s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
22
22
  s.require_paths = ["lib"]
23
23
 
24
- s.add_dependency "fog-brightbox", ">= 1.8.0"
24
+ s.add_dependency "fog-brightbox", ">= 1.9.1"
25
25
  s.add_dependency "fog-core", "< 2.0"
26
26
  s.add_dependency "gli", "~> 2.21"
27
27
  s.add_dependency "highline", "~> 2.0"
@@ -0,0 +1,36 @@
1
+ module Brightbox
2
+ command [:volumes] do |cmd|
3
+ cmd.desc I18n.t("volumes.attach.desc")
4
+ cmd.arg_name I18n.t("volumes.attach.args")
5
+
6
+ cmd.command [:attach] do |c|
7
+ c.desc I18n.t("volumes.options.boot")
8
+ c.default_value false
9
+ c.switch [:boot], negatable: true
10
+
11
+ c.action do |global_options, options, args|
12
+ vol_id = args.shift
13
+
14
+ if vol_id.nil? || !vol_id.start_with?("vol-")
15
+ raise I18n.t("volumes.args.specify_one_id_first")
16
+ end
17
+
18
+ srv_id = args.shift
19
+
20
+ if srv_id.nil? || !srv_id.start_with?("srv-")
21
+ raise I18n.t("volumes.attach.specify_server_id_second")
22
+ end
23
+
24
+ boot_flag = options[:boot]
25
+
26
+ volume = Volume.find(vol_id)
27
+
28
+ info I18n.t("volumes.attach.acting", volume: volume)
29
+ volume.attach(server: srv_id, boot: boot_flag)
30
+ volume.reload
31
+
32
+ render_table([volume], global_options)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,45 @@
1
+ module Brightbox
2
+ command [:volumes] do |cmd|
3
+ cmd.desc I18n.t("volumes.copy.desc")
4
+ cmd.arg_name I18n.t("volumes.args.one")
5
+
6
+ cmd.command [:copy] do |c|
7
+ c.desc I18n.t("options.description.desc")
8
+ c.flag %i[d description]
9
+
10
+ c.desc I18n.t("volumes.options.delete_with_server")
11
+ c.default_value false
12
+ c.switch ["delete-with-server"], negatable: true
13
+
14
+ c.desc I18n.t("options.name.desc")
15
+ c.flag %i[n name]
16
+
17
+ c.desc I18n.t("volumes.options.serial")
18
+ c.flag [:serial]
19
+
20
+ c.action do |global_options, options, args|
21
+ vol_id = args.shift
22
+
23
+ if vol_id.nil? || !vol_id.start_with?("vol-")
24
+ raise I18n.t("volumes.args.specify_one_id_first")
25
+ end
26
+
27
+ params = {
28
+ delete_with_server: options["delete-with-server"]
29
+ }
30
+ params[:description] = options[:description] if options[:description]
31
+ params[:name] = options[:name] if options[:name]
32
+ params[:serial] = options[:serial] if options[:serial]
33
+
34
+ volume = Volume.find(vol_id)
35
+
36
+ unless params.empty?
37
+ info I18n.t("volumes.copy.acting", volume: volume)
38
+ volume.copy(params)
39
+ end
40
+
41
+ render_table([volume], global_options)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,63 @@
1
+ module Brightbox
2
+ command [:volumes] do |cmd|
3
+ cmd.desc I18n.t("volumes.create.desc")
4
+
5
+ cmd.command [:create] do |c|
6
+ c.desc I18n.t("options.description.desc")
7
+ c.flag %i[d description]
8
+
9
+ c.desc I18n.t("volumes.options.delete_with_server")
10
+ c.default_value false
11
+ c.switch ["delete-with-server"], negatable: true
12
+
13
+ c.desc I18n.t("volumes.options.encrypted")
14
+ c.switch %i[e encrypted], negatable: true
15
+
16
+ c.desc I18n.t("volumes.options.fs_label")
17
+ c.flag ["fs-label"]
18
+
19
+ c.desc I18n.t("volumes.options.fs_type")
20
+ c.flag ["fs-type"]
21
+
22
+ c.desc I18n.t("volumes.options.image")
23
+ c.flag %i[i image]
24
+
25
+ c.desc I18n.t("options.name.desc")
26
+ c.flag %i[n name]
27
+
28
+ c.desc I18n.t("volumes.options.serial")
29
+ c.flag [:serial]
30
+
31
+ c.desc I18n.t("volumes.options.size")
32
+ c.flag %i[s size]
33
+
34
+ c.action do |global_options, options, _args|
35
+ if options[:image].nil? && options[:"fs-type"].nil?
36
+ raise I18n.t("volumes.create.image_or_type_required")
37
+ end
38
+
39
+ if !options[:image].nil? && !options[:"fs-type"].nil?
40
+ raise I18n.t("volumes.create.either_image_or_type")
41
+ end
42
+
43
+ params = {
44
+ delete_with_server: options[:"delete-with-server"],
45
+ encrypted: options[:encrypted]
46
+ }
47
+
48
+ params[:filesystem_label] = options[:"fs-label"] if options[:"fs-label"]
49
+ params[:filesystem_type] = options[:"fs-type"] if options[:"fs-type"]
50
+ params[:image_id] = options[:image] if options[:image]
51
+
52
+ params[:description] = options[:description] if options[:description]
53
+ params[:name] = options[:name] if options[:name]
54
+ params[:serial] = options[:serial] if options[:serial]
55
+ params[:size] = options[:size] if options[:size]
56
+
57
+ info I18n.t("volumes.create.acting")
58
+ volume = Volume.create(params)
59
+ render_table([volume], global_options)
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,26 @@
1
+ module Brightbox
2
+ command [:volumes] do |cmd|
3
+ cmd.desc I18n.t("volumes.destroy.desc")
4
+ cmd.arg_name I18n.t("volumes.args.many")
5
+
6
+ cmd.command [:destroy] do |c|
7
+ c.action do |_global_options, _options, args|
8
+ raise I18n.t("volumes.args.specify_many_ids") if args.empty?
9
+
10
+ volumes = Volume.find_or_call(args) do |id|
11
+ raise I18n.t("volumes.args.unknown_id", volume: volume)
12
+ end
13
+
14
+ volumes.each do |volume|
15
+ info I18n.t("volumes.destroy.acting", volume: volume)
16
+
17
+ begin
18
+ volume.destroy
19
+ rescue Brightbox::Api::Conflict
20
+ error "Could not destroy #{id}"
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,23 @@
1
+ module Brightbox
2
+ command [:volumes] do |cmd|
3
+ cmd.desc I18n.t("volumes.detach.desc")
4
+ cmd.arg_name I18n.t("volumes.args.many")
5
+
6
+ cmd.command [:detach] do |c|
7
+ c.action do |global_options, _options, args|
8
+ raise I18n.t("volumes.args.specify_many_ids") if args.empty?
9
+
10
+ volumes = Volume.find_or_call(args) do |volume|
11
+ raise I18n.t("volumes.args.unknown_id", volume: volume)
12
+ end
13
+
14
+ volumes.each do |volume|
15
+ info I18n.t("volumes.detach.acting", volume: volume)
16
+ volume.detach
17
+ end
18
+
19
+ render_table(volumes, global_options)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,16 @@
1
+ module Brightbox
2
+ command [:volumes] do |cmd|
3
+ cmd.default_command :list
4
+
5
+ cmd.desc I18n.t("volumes.list.desc")
6
+ cmd.arg_name I18n.t("volumes.args.optional")
7
+
8
+ cmd.command [:list] do |c|
9
+ c.action do |global_options, _options, args|
10
+ volumes = Volume.find_all_or_warn(args)
11
+
12
+ render_table(volumes, global_options)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,39 @@
1
+ module Brightbox
2
+ command [:volumes] do |cmd|
3
+ cmd.desc I18n.t("volumes.lock.desc")
4
+ cmd.arg_name I18n.t("volumes.args.many")
5
+
6
+ cmd.command [:lock] do |c|
7
+ c.action do |_global_options, _options, args|
8
+ raise I18n.t("volumes.args.specify_many_ids") if args.empty?
9
+
10
+ volumes = Volume.find_or_call(args) do |volume|
11
+ raise I18n.t("volumes.args.unknown_id", volume: volume)
12
+ end
13
+
14
+ volumes.each do |volume|
15
+ info I18n.t("volumes.lock.acting", volume: volume)
16
+ volume.lock!
17
+ end
18
+ end
19
+ end
20
+
21
+ cmd.desc I18n.t("volumes.unlock.desc")
22
+ cmd.arg_name I18n.t("volumes.args.many")
23
+
24
+ cmd.command [:unlock] do |c|
25
+ c.action do |_global_options, _options, args|
26
+ raise I18n.t("volumes.args.specify_many_ids") if args.empty?
27
+
28
+ volumes = Volume.find_or_call(args) do |volume|
29
+ raise I18n.t("volumes.args.unknown_id", volume: volume)
30
+ end
31
+
32
+ volumes.each do |volume|
33
+ info I18n.t("volumes.unlock.acting", volume: volume)
34
+ volume.unlock!
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,36 @@
1
+ module Brightbox
2
+ command [:volumes] do |cmd|
3
+ cmd.desc I18n.t("volumes.resize.desc")
4
+ cmd.arg_name I18n.t("volumes.args.one")
5
+
6
+ cmd.command [:resize] do |c|
7
+ c.desc I18n.t("volumes.options.size")
8
+ c.flag %i[s size]
9
+
10
+ c.action do |global_options, options, args|
11
+ vol_id = args.shift
12
+
13
+ if vol_id.nil? || !vol_id.start_with?("vol-")
14
+ raise I18n.t("volumes.args.specify_one_id_first")
15
+ end
16
+
17
+ if options[:size].nil?
18
+ raise I18n.t("volumes.resize.size_option_needed")
19
+ end
20
+
21
+ new_size = options[:size].to_i
22
+
23
+ volume = Volume.find(vol_id)
24
+ old_size = volume.size
25
+
26
+ info I18n.t("volumes.resize.acting", volume: volume)
27
+ volume.resize(
28
+ from: old_size,
29
+ to: new_size
30
+ )
31
+
32
+ render_table([volume], global_options)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,18 @@
1
+ module Brightbox
2
+ command [:volumes] do |cmd|
3
+ cmd.desc I18n.t("volumes.show.desc")
4
+ cmd.arg_name I18n.t("volumes.args.optional")
5
+
6
+ cmd.command [:show] do |c|
7
+ c.action do |global_options, _options, args|
8
+ volumes = Volume.find_all_or_warn(args)
9
+
10
+ table_opts = global_options.merge(
11
+ :vertical => true,
12
+ :fields => Volume.detailed_fields
13
+ )
14
+ render_table(volumes, table_opts)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,50 @@
1
+ module Brightbox
2
+ command [:volumes] do |cmd|
3
+ cmd.desc I18n.t("volumes.update.desc")
4
+ cmd.arg_name I18n.t("volumes.args.one")
5
+
6
+ cmd.command [:update] do |c|
7
+ c.desc I18n.t("options.description.desc")
8
+ c.flag %i[d description]
9
+
10
+ c.desc I18n.t("volumes.options.delete_with_server")
11
+ c.default_value :ignore # So we can discard unless deliberately passed
12
+ c.switch ["delete-with-server"], negatable: true
13
+
14
+ c.desc I18n.t("options.name.desc")
15
+ c.flag %i[n name]
16
+
17
+ c.desc I18n.t("volumes.options.serial")
18
+ c.flag [:serial]
19
+
20
+ c.action do |global_options, options, args|
21
+ vol_id = args.shift
22
+
23
+ if vol_id.nil? || !vol_id.start_with?("vol-")
24
+ raise I18n.t("volumes.args.specify_one_id_first")
25
+ end
26
+
27
+ params = {}
28
+
29
+ # Switches will always appear in the options so we need a non-boolean
30
+ # setting to determine if the user did not add it to their command
31
+ unless options["delete-with-server"] == :ignore
32
+ params[:delete_with_server] = options["delete-with-server"]
33
+ end
34
+
35
+ params[:description] = options[:description] if options[:description]
36
+ params[:name] = options[:name] if options[:name]
37
+ params[:serial] = options[:serial] if options[:serial]
38
+
39
+ volume = Volume.find(vol_id)
40
+
41
+ unless params.empty?
42
+ info I18n.t("volumes.update.acting", volume: volume)
43
+ volume.update(params)
44
+ end
45
+
46
+ render_table([volume], global_options)
47
+ end
48
+ end
49
+ end
50
+ end
@@ -31,9 +31,21 @@ module Brightbox
31
31
  row_attributes[:server_groups] = server_groups.map { |sg| sg["id"] }.join(", ")
32
32
  end
33
33
 
34
+ row_attributes[:volumes] = volume_ids if volumes
35
+
34
36
  row_attributes
35
37
  end
36
38
 
39
+ def volume_ids
40
+ volumes.map do |vol|
41
+ if vol["boot"] == true
42
+ "*#{vol['id']}*"
43
+ else
44
+ vol["id"]
45
+ end
46
+ end.join(", ")
47
+ end
48
+
37
49
  def self.default_field_order
38
50
  %i[
39
51
  id
@@ -65,6 +77,7 @@ module Brightbox
65
77
  cloud_ipv6s
66
78
  snapshots
67
79
  server_groups
80
+ volumes
68
81
  ]
69
82
  end
70
83
  end
@@ -1,3 +1,3 @@
1
1
  module Brightbox
2
- VERSION = "4.2.1".freeze unless defined?(Brightbox::VERSION)
2
+ VERSION = "4.3.0".freeze unless defined?(Brightbox::VERSION)
3
3
  end
@@ -0,0 +1,81 @@
1
+ module Brightbox
2
+ class Volume < Api
3
+ def self.require_account?; true; end
4
+
5
+ def self.all
6
+ conn.volumes
7
+ end
8
+
9
+ def self.create(options)
10
+ new(conn.volumes.create(options))
11
+ end
12
+
13
+ def self.get(id)
14
+ conn.volumes.get(id)
15
+ end
16
+
17
+ def self.default_field_order
18
+ %i[
19
+ id
20
+ type
21
+ size
22
+ status
23
+ server
24
+ boot
25
+ name
26
+ ]
27
+ end
28
+
29
+ def self.detailed_fields
30
+ %i[
31
+ id
32
+ name
33
+ description
34
+ type
35
+ size
36
+ status
37
+ created_at
38
+ encrypted
39
+ serial
40
+ locked
41
+ filesystem_label
42
+ filesystem_type
43
+ image
44
+ source
45
+ source_type
46
+ server
47
+ boot
48
+ delete_with_server
49
+ zone
50
+ ]
51
+ end
52
+
53
+ def attach(server:, boot: false)
54
+ self.class.conn.attach_volume(id, server: server, boot: boot)
55
+ reload
56
+ self
57
+ end
58
+
59
+ def attributes
60
+ a = fog_model.attributes
61
+ a[:id] = fog_model.id
62
+ a[:image] = image_id
63
+ a[:locked] = locked?
64
+ a[:server] = server_id
65
+ a[:status] = state
66
+ a[:type] = storage_type
67
+ a[:zone] = zone_id
68
+ a
69
+ end
70
+
71
+ def to_row
72
+ attributes
73
+ end
74
+
75
+ def update(options)
76
+ self.class.conn.update_volume(id, options)
77
+ reload
78
+ self
79
+ end
80
+ end
81
+ end
data/lib/brightbox_cli.rb CHANGED
@@ -56,6 +56,7 @@ module Brightbox
56
56
  autoload :DatabaseType, File.expand_path("brightbox-cli/database_type", __dir__)
57
57
  autoload :DatabaseServer, File.expand_path("brightbox-cli/database_server", __dir__)
58
58
  autoload :DatabaseSnapshot, File.expand_path("brightbox-cli/database_snapshot", __dir__)
59
+ autoload :Volume, File.expand_path("brightbox-cli/volume", __dir__)
59
60
  autoload :Token, File.expand_path("brightbox-cli/token", __dir__)
60
61
 
61
62
  module Config
data/locales/en.yml CHANGED
@@ -155,7 +155,7 @@ en:
155
155
  reboot:
156
156
  desc: Reboot servers (OS reboot issued)
157
157
  reset:
158
- desc: Reset servers (Hardward reset issued)
158
+ desc: Reset servers (Hardware reset issued)
159
159
  show:
160
160
  desc: Show servers
161
161
  shutdown:
@@ -245,3 +245,59 @@ en:
245
245
  desc: Show users
246
246
  update:
247
247
  desc: Update a user
248
+ volumes:
249
+ desc: Manage an account's volumes
250
+ args:
251
+ one: <volume>
252
+ optional: [<volume>...]
253
+ many: <volume>...
254
+ specify_one_id_first: You must specify the volume ID as the first argument
255
+ specify_many_ids: You must specify volume IDs as arguments
256
+ unknown_id: Couldn't find %{volume}
257
+ options:
258
+ boot: Set this volume as boot volume on server
259
+ delete_with_server: Set volume to be deleted with a server if attached
260
+ encrypted: Encrypt the volume
261
+ fs_label: Filesystem label, visible from within some OS
262
+ fs_type: Filesystem type to use to create blank volume
263
+ image: Create volume from existing Image ID
264
+ serial: Customisable serial number for volume
265
+ size: Volume size in MB
266
+ attach:
267
+ desc: Attach a volume to an existing server
268
+ args: <volume> <server>
269
+ specify_server_id_second: "You must specify the server ID to attach to as the second argument"
270
+ acting: Attaching %{volume}
271
+ copy:
272
+ desc: Create a new volume from an existing one
273
+ acting: Copying %{volume}
274
+ create:
275
+ desc: Create a new volume
276
+ acting: Creating volume
277
+ image_or_type_required: An 'image' or 'fs-type' option must be passed
278
+ either_image_or_type: An 'image' and 'fs-type' can not be passed together
279
+ destroy:
280
+ desc: Destroy one or more volumes
281
+ acting: Destroying %{volume}
282
+ detach:
283
+ desc: Detach a volume from a server
284
+ acting: Detaching %{volume}
285
+ list:
286
+ desc: List all volumes or limit using passed IDs
287
+ lock:
288
+ desc: Lock volumes
289
+ acting: Locking %{volume}
290
+ resize:
291
+ desc: Resize a volume
292
+ size_option_needed: A 'size' option is required
293
+ acting: Resizing %{volume}
294
+ show:
295
+ desc: Show details about multiple volumes
296
+ unlock:
297
+ desc: Unlock volumes
298
+ acting: Unlocking %{volume}
299
+ update:
300
+ desc: Update a volume
301
+ acting: Updating %{volume}
302
+
303
+