morpheus-cli 3.3.1.4 → 3.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/lib/morpheus/api/api_client.rb +28 -0
  3. data/lib/morpheus/api/instance_types_interface.rb +12 -10
  4. data/lib/morpheus/api/instances_interface.rb +4 -0
  5. data/lib/morpheus/api/library_container_scripts_interface.rb +49 -0
  6. data/lib/morpheus/api/library_container_templates_interface.rb +49 -0
  7. data/lib/morpheus/api/library_container_types_interface.rb +65 -0
  8. data/lib/morpheus/api/library_container_upgrades_interface.rb +66 -0
  9. data/lib/morpheus/api/library_instance_types_interface.rb +59 -0
  10. data/lib/morpheus/api/library_layouts_interface.rb +65 -0
  11. data/lib/morpheus/api/servers_interface.rb +4 -0
  12. data/lib/morpheus/api/user_sources_interface.rb +120 -0
  13. data/lib/morpheus/api/virtual_images_interface.rb +7 -0
  14. data/lib/morpheus/cli.rb +12 -1
  15. data/lib/morpheus/cli/accounts.rb +35 -9
  16. data/lib/morpheus/cli/cli_command.rb +82 -2
  17. data/lib/morpheus/cli/curl_command.rb +1 -1
  18. data/lib/morpheus/cli/echo_command.rb +1 -1
  19. data/lib/morpheus/cli/hosts.rb +40 -14
  20. data/lib/morpheus/cli/instance_types.rb +106 -64
  21. data/lib/morpheus/cli/instances.rb +39 -15
  22. data/lib/morpheus/cli/library.rb +1 -1184
  23. data/lib/morpheus/cli/library_container_scripts_command.rb +437 -0
  24. data/lib/morpheus/cli/library_container_templates_command.rb +397 -0
  25. data/lib/morpheus/cli/library_container_types_command.rb +653 -0
  26. data/lib/morpheus/cli/library_instance_types_command.rb +491 -0
  27. data/lib/morpheus/cli/library_layouts_command.rb +650 -0
  28. data/lib/morpheus/cli/library_option_lists_command.rb +476 -0
  29. data/lib/morpheus/cli/library_option_types_command.rb +549 -0
  30. data/lib/morpheus/cli/library_upgrades_command.rb +604 -0
  31. data/lib/morpheus/cli/mixins/library_helper.rb +123 -0
  32. data/lib/morpheus/cli/mixins/print_helper.rb +21 -22
  33. data/lib/morpheus/cli/mixins/provisioning_helper.rb +56 -11
  34. data/lib/morpheus/cli/network_services_command.rb +1 -1
  35. data/lib/morpheus/cli/option_types.rb +12 -2
  36. data/lib/morpheus/cli/power_scheduling_command.rb +1 -1
  37. data/lib/morpheus/cli/shell.rb +120 -22
  38. data/lib/morpheus/cli/sleep_command.rb +45 -0
  39. data/lib/morpheus/cli/user_sources_command.rb +963 -0
  40. data/lib/morpheus/cli/users.rb +33 -2
  41. data/lib/morpheus/cli/version.rb +1 -1
  42. data/lib/morpheus/cli/version_command.rb +1 -1
  43. data/lib/morpheus/cli/virtual_images.rb +93 -39
  44. data/lib/morpheus/formatters.rb +37 -27
  45. data/lib/morpheus/terminal.rb +1 -1
  46. metadata +20 -2
@@ -0,0 +1,476 @@
1
+ require 'io/console'
2
+ require 'optparse'
3
+ require 'filesize'
4
+ require 'morpheus/cli/cli_command'
5
+ require 'morpheus/cli/mixins/library_helper'
6
+
7
+ class Morpheus::Cli::LibraryOptionListsCommand
8
+ include Morpheus::Cli::CliCommand
9
+ include Morpheus::Cli::LibraryHelper
10
+
11
+ set_command_name :'library-option-lists'
12
+ register_subcommands :list, :get, :add, :update, :remove
13
+
14
+ def initialize()
15
+ # @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
16
+ end
17
+
18
+ def connect(opts)
19
+ @api_client = establish_remote_appliance_connection(opts)
20
+ @library_instance_types_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).library_instance_types
21
+ @provision_types_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).provision_types
22
+ @option_types_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).option_types
23
+ @option_type_lists_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).option_type_lists
24
+ end
25
+
26
+ def handle(args)
27
+ handle_subcommand(args)
28
+ end
29
+
30
+ def list(args)
31
+ options = {}
32
+ optparse = Morpheus::Cli::OptionParser.new do|opts|
33
+ opts.banner = subcommand_usage()
34
+ build_common_options(opts, options, [:list, :query, :dry_run, :json, :remote])
35
+ opts.footer = "This outputs a list of custom Option List records."
36
+ end
37
+ optparse.parse!(args)
38
+ connect(options)
39
+ begin
40
+ params = {}
41
+ params.merge!(parse_list_options(options))
42
+
43
+ if options[:dry_run]
44
+ print_dry_run @option_type_lists_interface.dry.list(params)
45
+ return
46
+ end
47
+
48
+ json_response = @option_type_lists_interface.list(params)
49
+
50
+ if options[:json]
51
+ print JSON.pretty_generate(json_response), "\n"
52
+ return
53
+ end
54
+
55
+ option_type_lists = json_response['optionTypeLists']
56
+ subtitles = []
57
+ subtitles += parse_list_subtitles(options)
58
+ print_h1 "Morpheus Option Lists", subtitles
59
+ if option_type_lists.empty?
60
+ print cyan,"No option lists found.",reset,"\n"
61
+ else
62
+ rows = option_type_lists.collect do |option_type_list|
63
+ {
64
+ id: option_type_list['id'],
65
+ name: option_type_list['name'],
66
+ description: option_type_list['description'],
67
+ type: option_type_list['type'],
68
+ size: option_type_list['listItems'] ? option_type_list['listItems'].size : ''
69
+ }
70
+ end
71
+ print cyan
72
+ tp rows, [
73
+ :id,
74
+ :name,
75
+ :description,
76
+ :type,
77
+ :size
78
+ ]
79
+ print reset
80
+ print_results_pagination(json_response)
81
+ end
82
+ print reset,"\n"
83
+ rescue RestClient::Exception => e
84
+ print_rest_exception(e, options)
85
+ exit 1
86
+ end
87
+ end
88
+
89
+ def get(args)
90
+ options = {}
91
+ optparse = Morpheus::Cli::OptionParser.new do|opts|
92
+ opts.banner = subcommand_usage("[name]")
93
+ build_common_options(opts, options, [:json, :dry_run, :remote])
94
+ opts.footer = "This outputs details about a particular Option List."
95
+ end
96
+ optparse.parse!(args)
97
+ if args.count < 1
98
+ puts optparse
99
+ exit 1
100
+ end
101
+
102
+ connect(options)
103
+ begin
104
+ if options[:dry_run]
105
+ if args[0].to_s =~ /\A\d{1,}\Z/
106
+ print_dry_run @option_type_lists_interface.dry.get(args[0].to_i)
107
+ else
108
+ print_dry_run @option_type_lists_interface.dry.list({name: args[0]})
109
+ end
110
+ return
111
+ end
112
+ option_type_list = find_option_type_list_by_name_or_id(args[0])
113
+ exit 1 if option_type_list.nil?
114
+
115
+ if options[:json]
116
+ print JSON.pretty_generate({optionTypeList: option_type_list}), "\n"
117
+ return
118
+ end
119
+
120
+ print_h1 "Option List Details"
121
+ print cyan
122
+ if option_type_list['type'] == 'manual'
123
+ print_description_list({
124
+ "ID" => 'id',
125
+ "Name" => 'name',
126
+ "Description" => 'description',
127
+ "Type" => lambda {|it| it['type'].to_s.capitalize },
128
+ }, option_type_list)
129
+ # print_h2 "Initial Dataset"
130
+ # print bright_black,"#{option_type_list['initialDataset']}","\n",reset
131
+ else
132
+ print_description_list({
133
+ "ID" => 'id',
134
+ "Name" => 'name',
135
+ "Description" => 'description',
136
+ "Type" => lambda {|it| it['type'].to_s.capitalize },
137
+ "Source URL" => 'sourceUrl',
138
+ "Ignore SSL Errors" => lambda {|it| format_boolean it['ignoreSSLErrors'] },
139
+ "Source Method" => lambda {|it| it['sourceMethod'].to_s.upcase },
140
+ }, option_type_list)
141
+ if !option_type_list['initialDataset'].empty?
142
+ print_h2 "Initial Dataset"
143
+ print bright_black," #{option_type_list['initialDataset']}","\n",reset
144
+ end
145
+ if !option_type_list['translationScript'].empty?
146
+ print_h2 "Translation Script"
147
+ print bright_black," #{option_type_list['translationScript']}","\n",reset
148
+ end
149
+ end
150
+
151
+ print_h2 "List Items"
152
+ if option_type_list['listItems']
153
+ # puts "\tNAME\tVALUE"
154
+ # option_type_list['listItems'].each do |list_item|
155
+ # puts "\t#{list_item['name']}\t#{list_item['value']}"
156
+ # end
157
+ print cyan
158
+ tp option_type_list['listItems'], ['name', 'value']
159
+ else
160
+ puts "No data"
161
+ end
162
+ print reset,"\n"
163
+
164
+ rescue RestClient::Exception => e
165
+ print_rest_exception(e, options)
166
+ exit 1
167
+ end
168
+ end
169
+
170
+ def add(args)
171
+ # JD: this is annoying because our option_types (for prompting and help)
172
+ # are the same type of object being managed here.., options options options
173
+ options = {}
174
+ my_option_types = nil
175
+ list_type = nil
176
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
177
+ opts.banner = subcommand_usage("[type] [options]")
178
+ opts.on( '-t', '--type TYPE', "Option List Type. (rest, manual)" ) do |val|
179
+ list_type = val
180
+ # options[:options] ||= {}
181
+ # options[:options]['type'] = val
182
+ end
183
+ build_option_type_options(opts, options, new_option_type_list_option_types())
184
+ build_common_options(opts, options, [:options, :json, :dry_run, :remote])
185
+ end
186
+ optparse.parse!(args)
187
+
188
+ if !list_type
189
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'type', 'fieldLabel' => 'Type', 'type' => 'select', 'selectOptions' => get_available_option_list_types, 'defaultValue' => 'rest', 'required' => true}], options[:options], @api_client, {})
190
+ list_type = v_prompt['type']
191
+ end
192
+
193
+ connect(options)
194
+ begin
195
+ params = Morpheus::Cli::OptionTypes.prompt(new_option_type_list_option_types(list_type), options[:options], @api_client, options[:params])
196
+ if params.key?('required')
197
+ params['required'] = ['on','true'].include?(params['required'].to_s)
198
+ end
199
+ params['type'] = list_type
200
+ list_payload = params
201
+ payload = {'optionTypeList' => list_payload}
202
+ if options[:dry_run]
203
+ print_dry_run @option_type_lists_interface.dry.create(payload)
204
+ return
205
+ end
206
+ json_response = @option_type_lists_interface.create(payload)
207
+ if options[:json]
208
+ print JSON.pretty_generate(json_response), "\n"
209
+ return
210
+ end
211
+ print_green_success "Added Option List #{list_payload['name']}"
212
+ #list([])
213
+ option_type_list = json_response['optionTypeList']
214
+ if option_type_list
215
+ get([option_type_list['id']])
216
+ end
217
+ rescue RestClient::Exception => e
218
+ print_rest_exception(e, options)
219
+ exit 1
220
+ end
221
+ end
222
+
223
+ def update(args)
224
+ # JD: this is annoying because our option_types (for prompting and help)
225
+ # are the same type of object being managed here.., options options options
226
+ options = {}
227
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
228
+ opts.banner = subcommand_usage("[name] [options]")
229
+ build_option_type_options(opts, options, update_option_type_list_option_types())
230
+ build_common_options(opts, options, [:options, :json, :dry_run, :remote])
231
+ end
232
+ optparse.parse!(args)
233
+ connect(options)
234
+ begin
235
+ option_type_list = find_option_type_list_by_name_or_id(args[0])
236
+ exit 1 if option_type_list.nil?
237
+
238
+ list_type = option_type_list['type']
239
+ prompt_options = update_option_type_list_option_types(list_type)
240
+ #params = options[:options] || {}
241
+ params = Morpheus::Cli::OptionTypes.no_prompt(prompt_options, options[:options], @api_client, options[:params])
242
+ if params.empty?
243
+ print_red_alert "Specify atleast one option to update"
244
+ puts optparse
245
+ exit 1
246
+ end
247
+ if params.key?('required')
248
+ params['required'] = ['on','true'].include?(params['required'].to_s)
249
+ end
250
+ list_payload = params
251
+ payload = {optionTypeList: list_payload}
252
+ if options[:dry_run]
253
+ print_dry_run @option_type_lists_interface.dry.update(option_type_list['id'], payload)
254
+ return
255
+ end
256
+ json_response = @option_type_lists_interface.update(option_type_list['id'], payload)
257
+ if options[:json]
258
+ print JSON.pretty_generate(json_response), "\n"
259
+ return
260
+ end
261
+ print_green_success "Updated Option List #{list_payload['name']}"
262
+ #list([])
263
+ get([option_type_list['id']])
264
+ rescue RestClient::Exception => e
265
+ print_rest_exception(e, options)
266
+ exit 1
267
+ end
268
+ end
269
+
270
+ def remove(args)
271
+ options = {}
272
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
273
+ opts.banner = subcommand_usage("[name]")
274
+ build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :remote])
275
+ end
276
+ optparse.parse!(args)
277
+ if args.count < 1
278
+ puts optparse
279
+ exit 1
280
+ end
281
+ connect(options)
282
+
283
+ begin
284
+ option_type_list = find_option_type_list_by_name_or_id(args[0])
285
+ exit 1 if option_type_list.nil?
286
+
287
+ unless Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the option type #{option_type_list['name']}?", options)
288
+ exit
289
+ end
290
+ if options[:dry_run]
291
+ print_dry_run @option_type_lists_interface.dry.destroy(option_type_list['id'])
292
+ return
293
+ end
294
+ json_response = @option_type_lists_interface.destroy(option_type_list['id'])
295
+
296
+ if options[:json]
297
+ print JSON.pretty_generate(json_response), "\n"
298
+ return
299
+ end
300
+
301
+ print_green_success "Removed Option List #{option_type_list['name']}"
302
+ #list([])
303
+ rescue RestClient::Exception => e
304
+ print_rest_exception(e, options)
305
+ exit 1
306
+ end
307
+ end
308
+
309
+ private
310
+
311
+ def find_instance_type_by_name_or_id(val)
312
+ if val.to_s =~ /\A\d{1,}\Z/
313
+ return find_instance_type_by_id(val)
314
+ else
315
+ return find_instance_type_by_name(val)
316
+ end
317
+ end
318
+
319
+ def find_instance_type_by_id(id)
320
+ begin
321
+ json_response = @library_instance_types_interface.get(id.to_i)
322
+ return json_response['instanceType']
323
+ rescue RestClient::Exception => e
324
+ if e.response && e.response.code == 404
325
+ print_red_alert "Instance Type not found by id #{id}"
326
+ else
327
+ raise e
328
+ end
329
+ end
330
+ end
331
+
332
+ def find_instance_type_by_name(name)
333
+ json_response = @library_instance_types_interface.list({name: name.to_s})
334
+ instance_types = json_response['instanceTypes']
335
+ if instance_types.empty?
336
+ print_red_alert "Instance Type not found by name #{name}"
337
+ return nil
338
+ elsif instance_types.size > 1
339
+ print_red_alert "#{instance_types.size} instance types found by name #{name}"
340
+ print_instance_types_table(instance_types, {color: red})
341
+ print_red_alert "Try using ID instead"
342
+ print reset,"\n"
343
+ return nil
344
+ else
345
+ return instance_types[0]
346
+ end
347
+ end
348
+
349
+ def print_instance_types_table(instance_types, opts={})
350
+ columns = [
351
+ {"ID" => lambda {|instance_type| instance_type['id'] } },
352
+ {"NAME" => lambda {|instance_type| instance_type['name'] } },
353
+ {"CODE" => lambda {|instance_type| instance_type['code'] } },
354
+ {"TECHNOLOGY" => lambda {|instance_type| format_instance_type_technology(instance_type) } },
355
+ {"CATEGORY" => lambda {|instance_type| instance_type['category'].to_s.capitalize } },
356
+ {"FEATURED" => lambda {|instance_type| format_boolean instance_type['featured'] } },
357
+ {"OWNER" => lambda {|instance_type| instance_type['account'] ? instance_type['account']['name'] : '' } },
358
+ ]
359
+ if opts[:include_fields]
360
+ columns = opts[:include_fields]
361
+ end
362
+ print as_pretty_table(instance_types, columns, opts)
363
+ end
364
+
365
+ def format_instance_type_technology(instance_type)
366
+ if instance_type
367
+ instance_type['provisionTypeCode'].to_s.capitalize
368
+ else
369
+ ""
370
+ end
371
+ end
372
+
373
+ def add_instance_type_option_types
374
+ [
375
+ {'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'displayOrder' => 1},
376
+ {'fieldName' => 'code', 'fieldLabel' => 'Code', 'type' => 'text', 'required' => true, 'displayOrder' => 2, 'description' => 'Useful shortcode for provisioning naming schemes and export reference.'},
377
+ {'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'displayOrder' => 3},
378
+ {'fieldName' => 'category', 'fieldLabel' => 'Category', 'type' => 'select', 'optionSource' => 'categories', 'required' => true, 'displayOrder' => 4},
379
+ {'fieldName' => 'logo', 'fieldLabel' => 'Icon File', 'type' => 'text', 'displayOrder' => 5},
380
+ {'fieldName' => 'visibility', 'fieldLabel' => 'Visibility', 'type' => 'select', 'selectOptions' => [{'name' => 'Private', 'value' => 'private'}, {'name' => 'Public', 'value' => 'public'}], 'defaultValue' => 'private', 'displayOrder' => 6},
381
+ {'fieldName' => 'environmentPrefix', 'fieldLabel' => 'Environment Prefix', 'type' => 'text', 'displayOrder' => 7, 'description' => 'Used for exportable environment variables when tying instance types together in app contexts. If not specified a name will be generated.'},
382
+ {'fieldName' => 'hasSettings', 'fieldLabel' => 'Enable Settings', 'type' => 'checkbox', 'displayOrder' => 8},
383
+ {'fieldName' => 'hasAutoScale', 'fieldLabel' => 'Enable Scaling (Horizontal)', 'type' => 'checkbox', 'displayOrder' => 9},
384
+ {'fieldName' => 'hasDeployment', 'fieldLabel' => 'Supports Deployments', 'type' => 'checkbox', 'displayOrder' => 10, 'description' => 'Requires a data volume be configured on each version. Files will be copied into this location.'}
385
+ ]
386
+ end
387
+
388
+ def update_instance_type_option_types(instance_type=nil)
389
+ opts = add_instance_type_option_types
390
+ opts = opts.reject {|it| ["logo"].include? it['fieldName'] }
391
+ if instance_type
392
+ opts = add_instance_type_option_types
393
+ opts.find {|opt| opt['fieldName'] == 'name'}['defaultValue'] = instance_type['name']
394
+ end
395
+ opts
396
+ end
397
+
398
+ def find_option_type_list_by_name_or_id(val)
399
+ if val.to_s =~ /\A\d{1,}\Z/
400
+ return find_option_type_list_by_id(val)
401
+ else
402
+ return find_option_type_list_by_name(val)
403
+ end
404
+ end
405
+
406
+ def find_option_type_list_by_id(id)
407
+ begin
408
+ json_response = @option_type_lists_interface.get(id.to_i)
409
+ return json_response['optionTypeList']
410
+ rescue RestClient::Exception => e
411
+ if e.response && e.response.code == 404
412
+ print_red_alert "Option List not found by id #{id}"
413
+ exit 1
414
+ else
415
+ raise e
416
+ end
417
+ end
418
+ end
419
+
420
+ def find_option_type_list_by_name(name)
421
+ json_results = @option_type_lists_interface.list({name: name.to_s})
422
+ if json_results['optionTypeLists'].empty?
423
+ print_red_alert "Option List not found by name #{name}"
424
+ exit 1
425
+ end
426
+ option_type_list = json_results['optionTypeLists'][0]
427
+ return option_type_list
428
+ end
429
+
430
+ def get_available_option_list_types
431
+ [
432
+ {'name' => 'Rest', 'value' => 'rest'},
433
+ {'name' => 'Manual', 'value' => 'manual'}
434
+ ]
435
+ end
436
+
437
+ def find_option_list_type(code)
438
+ get_available_option_list_types.find {|it| code == it['value'] || code == it['name'] }
439
+ end
440
+
441
+ def new_option_type_list_option_types(list_type='rest')
442
+ if list_type.to_s.downcase == 'rest'
443
+ [
444
+ {'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'displayOrder' => 1},
445
+ {'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'displayOrder' => 2},
446
+ #{'fieldName' => 'type', 'fieldLabel' => 'Type', 'type' => 'select', 'selectOptions' => get_available_option_list_types, 'defaultValue' => 'rest', 'required' => true, 'displayOrder' => 3},
447
+ {'fieldName' => 'sourceUrl', 'fieldLabel' => 'Source Url', 'type' => 'text', 'required' => true, 'description' => "A REST URL can be used to fetch list data and is cached in the appliance database.", 'displayOrder' => 4},
448
+ {'fieldName' => 'ignoreSSLErrors', 'fieldLabel' => 'Ignore SSL Errors', 'type' => 'checkbox', 'defaultValue' => 'off', 'displayOrder' => 5},
449
+ {'fieldName' => 'sourceMethod', 'fieldLabel' => 'Source Method', 'type' => 'select', 'selectOptions' => [{'name' => 'GET', 'value' => 'GET'}, {'name' => 'POST', 'value' => 'POST'}], 'defaultValue' => 'GET', 'required' => true, 'displayOrder' => 6},
450
+ {'fieldName' => 'initialDataset', 'fieldLabel' => 'Initial Dataset', 'type' => 'code-editor', 'description' => "Create an initial json dataset to be used as the collection for this option list. It should be a list containing objects with properties 'name', and 'value'. However, if there is a translation script, that will also be passed through.", 'displayOrder' => 7},
451
+ {'fieldName' => 'translationScript', 'fieldLabel' => 'Translation Script', 'type' => 'code-editor', 'description' => "Create a js script to translate the result data object into an Array containing objects with properties name, and value. The input data is provided as data and the result should be put on the global variable results.", 'displayOrder' => 8},
452
+ ]
453
+ elsif list_type.to_s.downcase == 'manual'
454
+ [
455
+ {'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'displayOrder' => 1},
456
+ {'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'displayOrder' => 2},
457
+ #{'fieldName' => 'type', 'fieldLabel' => 'Type', 'type' => 'select', 'selectOptions' => [{'name' => 'Rest', 'value' => 'rest'}, {'name' => 'Manual', 'value' => 'manual'}], 'defaultValue' => 'rest', 'required' => true, 'displayOrder' => 3},
458
+ {'fieldName' => 'initialDataset', 'fieldLabel' => 'Dataset', 'type' => 'code-editor', 'required' => true, 'description' => "Create an initial JSON or CSV dataset to be used as the collection for this option list. It should be a list containing objects with properties 'name', and 'value'.", 'displayOrder' => 4},
459
+ ]
460
+ else
461
+ print_red_alert "Unknown Option List type '#{list_type}'"
462
+ exit 1
463
+ end
464
+ end
465
+
466
+ def update_option_type_list_option_types(list_type='rest')
467
+ list = new_option_type_list_option_types(list_type)
468
+ list.each {|it|
469
+ it.delete('required')
470
+ it.delete('defaultValue')
471
+ it.delete('skipSingleOption')
472
+ }
473
+ list
474
+ end
475
+
476
+ end