brightbox-cli 4.3.1 → 4.4.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: a05097c67b080ccedd218b30d3e0923b4b1804c76ac5cbe5a76678b75d8f221e
4
- data.tar.gz: 9c9076964ac3c57b48a7d4d55183e4c2c87214462e564823dc815d566d1f95ad
3
+ metadata.gz: 20cc19a7e6458988359a604fa90d67570b83c124b40c265a5f9beb0d3bc3a199
4
+ data.tar.gz: 98072a6ccd8ab0dcf4a3e3ac7f27ecf6982a7f3cf275b86e979aae0fc12461d8
5
5
  SHA512:
6
- metadata.gz: 768f52b7d7eaed35b46d606f4699e23b2793f9ba0a00c86feaa0155cda89a55cc7a02e5f53268c554cd8731a0154bd1f5b37a0bdffb2f18c7cf852a97c353516
7
- data.tar.gz: 5178134a5acd7146df5a1d4e127773d0e9b322e48a0495bc01eba5408c25e81cc4e7f3d08c45ee83332d84cd04e7e562f7d2f0778c1762182e9787b9451e5066
6
+ metadata.gz: 1c949f6d0679c9d72b7c7f61a6a0fd68b0669452911dde7da845a6f7e9a388c5b2a253ab0219bf6228faf4bc51ac6accfc559d714425c18499525d47b84ab73e
7
+ data.tar.gz: 7975e2d18399cc35bcd49f474657f6766e5d694bdbf70a1d49b79288edcbc9c07ea1d54b0757bd992ef08c517d4eef0e2a684e9ebf102f4718f3c72bc31368f9
data/CHANGELOG.md CHANGED
@@ -1,3 +1,34 @@
1
+ ### v4.4.0 / 2023-01-26
2
+
3
+ [Full Changelog](https://github.com/brightbox/brightbox-cli/compare/v4.3.2...v4.4.0)
4
+
5
+ Enhancements:
6
+
7
+ * Added `configmaps` subcommand for manage config management.
8
+
9
+ ### v4.3.2 / 2023-01-12
10
+
11
+ [Full Changelog](https://github.com/brightbox/brightbox-cli/compare/v4.3.1...v4.3.2)
12
+
13
+ Bug fixes:
14
+
15
+ * Declared top level help for `volumes` subcommand.
16
+ * Fix `volumes update --delete-with-server` switch.
17
+ * Fix `lbs update --sslv3` switch.
18
+ * Fix `servers update --compatibility-mode` switch.
19
+
20
+ Changes:
21
+
22
+ * Added a `ignore_default` option to GLI DSL, by monkey patching, to prevent
23
+ unexpected switches from interfering with API calls. In some cases it was
24
+ impossible to determine if `--feature` or `--no-feature` had been used in the
25
+ command OR added as a default in GLI. This meant `update` commands would always
26
+ send `feature: false` in API requests even when updating names and other fields.
27
+ This could clear setting unexpectedly due to the behaviour.
28
+ * Test `servers create --compatibility-mode` switch.
29
+ * Test `cloudips update --delete-reverse-dns` switch.
30
+ * Test `sql instances --remove-snapshots-schedule` switch.
31
+
1
32
  ### v4.3.1 / 2023-01-11
2
33
 
3
34
  [Full Changelog](https://github.com/brightbox/brightbox-cli/compare/v4.3.0...v4.3.1)
data/Gemfile.lock CHANGED
@@ -1,9 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- brightbox-cli (4.3.1)
4
+ brightbox-cli (4.4.0)
5
5
  dry-inflector (= 0.2.0)
6
- fog-brightbox (>= 1.9.1)
6
+ fog-brightbox (>= 1.10.0)
7
7
  fog-core (< 2.0)
8
8
  gli (~> 2.21)
9
9
  highline (~> 2.0)
@@ -20,13 +20,13 @@ GEM
20
20
  ast (2.4.2)
21
21
  builder (3.2.4)
22
22
  coderay (1.1.3)
23
- concurrent-ruby (1.1.10)
23
+ concurrent-ruby (1.2.0)
24
24
  crack (0.4.5)
25
25
  rexml
26
26
  diff-lcs (1.5.0)
27
27
  dry-inflector (0.2.0)
28
- excon (0.97.0)
29
- fog-brightbox (1.9.1)
28
+ excon (0.97.2)
29
+ fog-brightbox (1.10.0)
30
30
  dry-inflector
31
31
  fog-core (>= 1.45, < 3.0)
32
32
  fog-json
@@ -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.9.1"
24
+ s.add_dependency "fog-brightbox", ">= 1.10.0"
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,183 @@
1
+ module Brightbox
2
+ desc I18n.t("configmaps.desc")
3
+ command [:configmaps] do |cmd|
4
+ cmd.default_command :list
5
+
6
+ cmd.desc I18n.t("configmaps.create.desc")
7
+ cmd.arg_name I18n.t("configmaps.args.one")
8
+ cmd.command [:create] do |c|
9
+ c.desc I18n.t("options.name.desc")
10
+ c.flag %i[n name]
11
+
12
+ c.desc I18n.t("configmaps.options.data_string")
13
+ c.flag %i[d data]
14
+
15
+ c.desc I18n.t("configmaps.options.data_file")
16
+ c.flag [:"data-file"]
17
+
18
+ c.action do |global_options, options, _args|
19
+ map_data = parse_configmap_data_options(options)
20
+
21
+ raise I18n.t("configmaps.create.data_required") if map_data.nil?
22
+
23
+ # Attempt to parse data as JSON but do not update
24
+ begin
25
+ JSON.parse(map_data)
26
+ rescue StandardError
27
+ raise I18n.t("configmaps.options.bad_data")
28
+ end
29
+
30
+ params = {
31
+ data: map_data
32
+ }
33
+ params[:name] = options[:name] if options[:name]
34
+
35
+ info I18n.t("configmaps.create.acting")
36
+ config_map = ConfigMap.create(params)
37
+
38
+ render_table([config_map], global_options)
39
+ end
40
+ end
41
+
42
+ cmd.desc I18n.t("configmaps.destroy.desc")
43
+ cmd.arg_name I18n.t("configmaps.args.many")
44
+ cmd.command [:destroy] do |c|
45
+ c.action do |_global_options, _options, args|
46
+ raise I18n.t("configmaps.args.specify_many_ids") if args.empty?
47
+
48
+ config_maps = ConfigMap.find_or_call(args) do |id|
49
+ raise I18n.t("configmaps.args.unknown_id", config_map: id)
50
+ end
51
+
52
+ config_maps.each do |config_map|
53
+ info I18n.t("configmaps.destroy.acting", config_map: config_map)
54
+
55
+ begin
56
+ config_map.destroy
57
+ rescue Brightbox::Api::Conflict
58
+ error I18n.t("configmaps.destroy.failed", config_map: id)
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ cmd.desc I18n.t("configmaps.list.desc")
65
+ cmd.arg_name I18n.t("configmaps.args.optional")
66
+ cmd.command [:list] do |c|
67
+ c.action do |global_options, _options, args|
68
+ config_maps = ConfigMap.find_all_or_warn(args)
69
+
70
+ render_table(config_maps, global_options)
71
+ end
72
+ end
73
+
74
+ cmd.desc I18n.t("configmaps.show.desc")
75
+ cmd.arg_name I18n.t("configmaps.args.optional")
76
+ cmd.command [:show] do |c|
77
+ c.desc I18n.t("configmaps.options.data_output")
78
+ c.switch [:data], negatable: false, default: false
79
+
80
+ c.desc I18n.t("configmaps.options.data_format")
81
+ c.flag [:format]
82
+
83
+ c.action do |global_options, options, args|
84
+ if options[:data]
85
+ unless args.length == 1
86
+ raise I18n.t("configmaps.options.data_args")
87
+ end
88
+
89
+ cfg_id = args[0]
90
+
91
+ if cfg_id.nil? || !cfg_id.start_with?("cfg-")
92
+ raise I18n.t("configmaps.args.specify_one_id_first")
93
+ end
94
+
95
+ config_map = ConfigMap.find(cfg_id)
96
+ data(config_map.format_data(options[:format] || "json"))
97
+ else
98
+ if options[:format] && !options[:data]
99
+ raise I18n.t("configmaps.options.format_no_data")
100
+ end
101
+
102
+ config_maps = ConfigMap.find_all_or_warn(args)
103
+
104
+ table_opts = global_options.merge(
105
+ vertical: true
106
+ )
107
+ render_table(config_maps, table_opts)
108
+ end
109
+ end
110
+ end
111
+
112
+ cmd.desc I18n.t("configmaps.update.desc")
113
+ cmd.arg_name I18n.t("configmaps.args.one")
114
+ cmd.command [:update] do |c|
115
+ c.desc I18n.t("options.name.desc")
116
+ c.flag %i[n name]
117
+
118
+ c.desc I18n.t("configmaps.options.data_string")
119
+ c.flag %i[d data]
120
+
121
+ c.desc I18n.t("configmaps.options.data_file")
122
+ c.flag [:"data-file"]
123
+
124
+ c.action do |global_options, options, args|
125
+ cfg_id = args[0]
126
+
127
+ if cfg_id.nil? || !cfg_id.start_with?("cfg-")
128
+ raise I18n.t("configmaps.args.specify_one_id_first")
129
+ end
130
+
131
+ params = {}
132
+ params[:name] = options[:name] if options[:name]
133
+
134
+ map_data = parse_configmap_data_options(options)
135
+
136
+ if map_data
137
+ begin
138
+ map_data = JSON.parse(map_data)
139
+ rescue StandardError
140
+ raise I18n.t("configmaps.options.bad_data")
141
+ end
142
+
143
+ params[:data] = map_data
144
+ end
145
+
146
+ config_map = ConfigMap.find(cfg_id)
147
+
148
+ unless params.empty?
149
+ info I18n.t("configmaps.update.acting", config_map: config_map)
150
+ config_map.update(params)
151
+ end
152
+
153
+ render_table([config_map], global_options)
154
+ end
155
+ end
156
+ end
157
+
158
+ def parse_configmap_data_options(options)
159
+ if options[:data] && options[:"data-file"]
160
+ raise I18n.t("configmaps.options.multiple_data")
161
+ end
162
+
163
+ map_data = options[:data]
164
+ data_filename = options[:"data-file"]
165
+
166
+ if data_filename
167
+ file_handler = lambda do |file|
168
+ map_data = file.read
169
+ end
170
+
171
+ if data_filename == "-"
172
+ file_handler[$stdin]
173
+ else
174
+ File.open(data_filename, "r", &file_handler)
175
+ end
176
+
177
+ raise map_data.inspect if map_data.nil? || map_data == ""
178
+ end
179
+
180
+ map_data
181
+ end
182
+ module_function :parse_configmap_data_options
183
+ end
@@ -50,7 +50,7 @@ module Brightbox
50
50
  c.switch ["remove-ssl"], :negatable => false
51
51
 
52
52
  c.desc "Enable SSL v3 support"
53
- c.switch ["sslv3"]
53
+ c.switch ["sslv3"], ignore_default: true
54
54
 
55
55
  c.action do |global_options, options, args|
56
56
  lb_id = args.shift
@@ -28,7 +28,6 @@ module Brightbox
28
28
  c.switch %i[e base64], :negatable => true
29
29
 
30
30
  c.desc "Enable encryption at rest for disk"
31
- c.default_value false
32
31
  c.switch ["disk-encrypted"], :negatable => false
33
32
 
34
33
  c.desc "Server groups to place server in - comma delimited list"
@@ -17,7 +17,7 @@ module Brightbox
17
17
  c.switch %i[e base64], :negatable => true
18
18
 
19
19
  c.desc "Use compatibility mode"
20
- c.switch [:"compatibility-mode"], :negatable => true
20
+ c.switch [:"compatibility-mode"], ignore_default: true
21
21
 
22
22
  c.desc "Server groups to place server in - comma delimited list"
23
23
  c.flag [:g, "server-groups"]
@@ -1,4 +1,5 @@
1
1
  module Brightbox
2
+ desc I18n.t("volumes.desc")
2
3
  command [:volumes] do |cmd|
3
4
  cmd.desc I18n.t("volumes.attach.desc")
4
5
  cmd.arg_name I18n.t("volumes.attach.args")
@@ -8,8 +8,7 @@ module Brightbox
8
8
  c.flag %i[d description]
9
9
 
10
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
11
+ c.switch [:"delete-with-server"], ignore_default: true
13
12
 
14
13
  c.desc I18n.t("options.name.desc")
15
14
  c.flag %i[n name]
@@ -28,8 +27,8 @@ module Brightbox
28
27
 
29
28
  # Switches will always appear in the options so we need a non-boolean
30
29
  # 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"]
30
+ unless options[:"delete-with-server"].nil?
31
+ params[:delete_with_server] = options[:"delete-with-server"]
33
32
  end
34
33
 
35
34
  params[:description] = options[:description] if options[:description]
@@ -0,0 +1,53 @@
1
+ module Brightbox
2
+ class ConfigMap < Api
3
+ def self.require_account?; true; end
4
+
5
+ def self.all
6
+ conn.config_maps
7
+ end
8
+
9
+ def self.create(options)
10
+ new(conn.config_maps.create(options))
11
+ end
12
+
13
+ def self.get(id)
14
+ conn.config_maps.get(id)
15
+ end
16
+
17
+ def self.default_field_order
18
+ %i[id name]
19
+ end
20
+
21
+ def self.detailed_fields
22
+ %i[
23
+ id
24
+ name
25
+ ]
26
+ end
27
+
28
+ def format_data(format)
29
+ case format.to_sym
30
+ when :text
31
+ attributes[:data].map do |key, value|
32
+ "#{key.to_s.rjust(16)}: #{value}"
33
+ end.join("\n")
34
+ else
35
+ JSON.dump(data)
36
+ end
37
+ end
38
+
39
+ def to_row
40
+ {
41
+ id: attributes[:id],
42
+ name: attributes[:name],
43
+ data: attributes[:data]
44
+ }
45
+ end
46
+
47
+ def update(options)
48
+ self.class.conn.update_config_map(id, options)
49
+ reload
50
+ self
51
+ end
52
+ end
53
+ end
@@ -1,3 +1,3 @@
1
1
  module Brightbox
2
- VERSION = "4.3.1".freeze unless defined?(Brightbox::VERSION)
2
+ VERSION = "4.4.0".freeze unless defined?(Brightbox::VERSION)
3
3
  end
data/lib/brightbox_cli.rb CHANGED
@@ -23,6 +23,7 @@ end
23
23
  require "multi_json"
24
24
  require "date"
25
25
  require "gli"
26
+ require "gli_patches"
26
27
  require "i18n"
27
28
  require "fog/brightbox"
28
29
 
@@ -52,6 +53,7 @@ module Brightbox
52
53
  autoload :FirewallRule, File.expand_path("brightbox-cli/firewall_rule", __dir__)
53
54
  autoload :FirewallRules, File.expand_path("brightbox-cli/firewall_rules", __dir__)
54
55
  autoload :Collaboration, File.expand_path("brightbox-cli/collaboration", __dir__)
56
+ autoload :ConfigMap, File.expand_path("brightbox-cli/config_map", __dir__)
55
57
  autoload :UserCollaboration, File.expand_path("brightbox-cli/user_collaboration", __dir__)
56
58
  autoload :DatabaseType, File.expand_path("brightbox-cli/database_type", __dir__)
57
59
  autoload :DatabaseServer, File.expand_path("brightbox-cli/database_server", __dir__)
@@ -0,0 +1,50 @@
1
+ require "gli/dsl"
2
+ require "gli/command_line_option"
3
+ require "gli/option_parser_factory"
4
+
5
+ module GLI
6
+ module DSL
7
+ def extract_options(names)
8
+ options = {}
9
+ options = names.pop if names.last.kind_of? Hash
10
+ options = {
11
+ :desc => @next_desc,
12
+ :long_desc => @next_long_desc,
13
+ :default_value => @next_default_value,
14
+ :ignore_default => @ignore_default,
15
+ :arg_name => @next_arg_name
16
+ }.merge(options)
17
+ end
18
+ end
19
+
20
+ class CommandLineOption
21
+ def initialize(names, options = {})
22
+ # Disable returning a default for this option (needed for boolean updates)
23
+ # which should NOT be sent unless added by the user
24
+ @ignore_default = !!options[:ignore_default]
25
+
26
+ super(names, options[:desc], options[:long_desc])
27
+ @default_value = options[:default_value]
28
+ end
29
+
30
+ def ignore_default?
31
+ @ignore_default
32
+ end
33
+ end
34
+
35
+ class OptionParserFactory
36
+ private
37
+
38
+ def set_defaults(options_by_name,options_hash)
39
+ options_by_name.values.each do |option|
40
+ option.names_and_aliases.each do |option_name|
41
+ [option_name,option_name.to_sym].each do |name|
42
+ next if option.ignore_default?
43
+
44
+ options_hash[name] = option.default_value if options_hash[name].nil?
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
data/locales/en.yml CHANGED
@@ -51,6 +51,39 @@ en:
51
51
  desc: Remove an API client from config
52
52
  user_add:
53
53
  desc: Add new user credentials to config
54
+ configmaps:
55
+ desc: Manage config maps
56
+ args:
57
+ one: <configmap>
58
+ optional: "[<configmap>...]"
59
+ many: <configmap>...
60
+ specify_one_id_first: You must specify the config map ID as the first argument
61
+ specify_many_ids: You must specify config map IDs as arguments
62
+ unknown_id: Couldn't find %{config_map}
63
+ options:
64
+ data_args: You can only access data for a single config map at a time
65
+ data_file: A path to a file contain a JSON object containing key/values, or '-' for STDIO
66
+ data_string: String representing a valid JSON object
67
+ data_output: Return the config map data key/values
68
+ data_format: "Format to return 'data' in: 'json' (default) or 'text'"
69
+ format_no_data: The 'format' option can only be used with 'data'
70
+ bad_data: Config map data was not valid JSON
71
+ multiple_data: Config map data can only be passed by either 'data' or 'data-file'
72
+ create:
73
+ desc: Create a config map
74
+ acting: Creating config map
75
+ data_required: Config map data is required as 'data' option
76
+ destroy:
77
+ desc: Destroy config maps
78
+ acting: Destroying %{config_map}
79
+ failed: Failed to destroy %{config_map}
80
+ list:
81
+ desc: List config maps
82
+ show:
83
+ desc: Show config maps
84
+ update:
85
+ desc: Update a config map
86
+ acting: Updating %{config_map}
54
87
  firewall:
55
88
  policies:
56
89
  desc: Manage firewall policies