morpheus-cli 6.3.0 → 6.3.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -76,7 +76,8 @@ module Morpheus
76
76
  option_type['type'] = 'multiText'
77
77
  end
78
78
  # swap types to multiSelect when flag is set..
79
- if option_type["config"] && ["true","on"].include?(option_type["config"]["multiSelect"].to_s)
79
+ config_multi_select = option_type["config"] && ["true","on"].include?(option_type["config"]["multiSelect"].to_s)
80
+ if config_multi_select
80
81
  if option_type["type"] == "typeahead"
81
82
  option_type["type"] = "multiTypeahead"
82
83
  elsif option_type["type"] == "select"
@@ -175,10 +176,9 @@ module Morpheus
175
176
  }
176
177
  end
177
178
 
179
+ depends_on_field_key = depends_on_code
178
180
  if depends_on_option_type
179
181
  depends_on_field_key = depends_on_option_type['fieldContext'].nil? || depends_on_option_type['fieldContext'].empty? ? "#{depends_on_option_type['fieldName']}" : "#{depends_on_option_type['fieldContext']}.#{depends_on_option_type['fieldName']}"
180
- else
181
- depends_on_field_key = depends_on_code
182
182
  end
183
183
 
184
184
  field_value = get_object_value(results, depends_on_field_key) ||
@@ -198,6 +198,53 @@ module Morpheus
198
198
  next if !found_dep_value
199
199
  end
200
200
 
201
+ # respect optionType.requireOnCode
202
+ require_option_check_value = option_type['requireOnCode']
203
+ if !require_option_check_value.to_s.empty?
204
+ # require_on_code = check_require_on_code(option_type, option_types, options)
205
+
206
+ match_type = 'any'
207
+
208
+ if require_option_check_value.include?('::')
209
+ match_type = 'all' if require_option_check_value.start_with?('matchAll')
210
+ require_option_check_value = require_option_check_value[require_option_check_value.index('::') + 2..-1]
211
+ end
212
+
213
+ found_dep_value = match_type == 'all' ? true : false
214
+ require_option_check_value.sub(',', ' ').split(' ').each do |value|
215
+ parts = value.split(':')
216
+ depends_on_code = parts[0]
217
+ depends_on_value = parts.count > 1 ? parts[1].to_s.strip : nil
218
+ depends_on_option_type = option_types.find {|it| it["code"] == depends_on_code }
219
+ if !depends_on_option_type
220
+ depends_on_option_type = option_types.find {|it|
221
+ (it['fieldContext'] ? "#{it['fieldContext']}.#{it['fieldName']}" : it['fieldName']) == depends_on_code
222
+ }
223
+ end
224
+
225
+ depends_on_field_key = depends_on_code
226
+ if depends_on_option_type
227
+ depends_on_field_key = depends_on_option_type['fieldContext'].nil? || depends_on_option_type['fieldContext'].empty? ? "#{depends_on_option_type['fieldName']}" : "#{depends_on_option_type['fieldContext']}.#{depends_on_option_type['fieldName']}"
228
+ end
229
+
230
+ field_value = get_object_value(results, depends_on_field_key) ||
231
+ get_object_value(options, depends_on_field_key) ||
232
+ get_object_value(api_params, depends_on_field_key)
233
+
234
+ if field_value.nil? && !options['_object_key'].nil?
235
+ field_value = get_object_value({options['_object_key'] => results}, depends_on_field_key)
236
+ end
237
+
238
+ if !field_value.nil? && (depends_on_value.nil? || depends_on_value.empty? || field_value.to_s.match?(depends_on_value))
239
+ found_dep_value = true if match_type != 'all'
240
+ else
241
+ found_dep_value = false if match_type == 'all'
242
+ end
243
+ end
244
+
245
+ option_type = option_type.merge({'required' => found_dep_value})
246
+ end
247
+
201
248
  # build parameters for option source api request
202
249
  option_params = (option_type['noParams'] ? {} : (api_params || {}).deep_merge(results))
203
250
  option_params.merge!(option_type['optionParams']) if option_type['optionParams']
@@ -217,6 +264,12 @@ module Morpheus
217
264
  context_map = context_map[ns.to_s]
218
265
  end
219
266
 
267
+ # CLI only options that need some do some inflection to decide how to prompt
268
+ # defaultValue is it right now..
269
+ if option_type[:preprocesser].is_a?(Proc)
270
+ option_type[:preprocesser].call(option_type, api_client, option_params)
271
+ end
272
+
220
273
  # credential type
221
274
  handle_credential_type = -> {
222
275
  credential_type = select_prompt(option_type.merge({'defaultValue' => value}), api_client, option_params.merge({'credentialTypes' => option_type['config']['credentialTypes']}), !value.nil?, nil, paging_enabled, ignore_empty, options[:edit_mode])
@@ -310,6 +363,23 @@ module Morpheus
310
363
  value = typeahead_prompt(option_type, api_client, option_params, true)
311
364
  value_found = !!value
312
365
  end
366
+ if option_type['type'] == 'hidden'
367
+ if option_type['optionSource'].nil?
368
+ value = option_type['defaultValue']
369
+ else
370
+ select_options = load_source_options(option_type['optionSource'], option_type['optionSourceType'], api_client, option_params)
371
+ config_multi_select = option_type["config"] && ["true","on"].include?(option_type["config"]["multiSelect"].to_s)
372
+ if config_multi_select
373
+ value = select_options.collect { |it| it['value'] }
374
+ elsif select_options.is_a?(Array)
375
+ value = select_options[0] ? select_options[0]['value'] : nil
376
+ elsif select_options.is_a?(Hash)
377
+ value = select_options['value']
378
+ else
379
+ value = select_options
380
+ end
381
+ end
382
+ end
313
383
  if !value_found && !ignore_empty
314
384
  if option_type['required']
315
385
  print Term::ANSIColor.red, "\nMissing Required Option\n\n", Term::ANSIColor.reset
@@ -326,7 +396,9 @@ module Morpheus
326
396
  end
327
397
 
328
398
  if !value_found
329
- if option_type['type'] == 'number'
399
+ if option_type['type'] == 'text'
400
+ value = generic_prompt(option_type)
401
+ elsif option_type['type'] == 'number'
330
402
  value = number_prompt(option_type)
331
403
  elsif option_type['type'] == 'password'
332
404
  value = password_prompt(option_type)
@@ -376,12 +448,24 @@ module Morpheus
376
448
  if option_type['optionSource'].nil?
377
449
  value = option_type['defaultValue']
378
450
  else
379
- value = load_source_options(option_type['optionSource'], option_type['optionSourceType'], api_client, api_params || {})
451
+ select_options = load_source_options(option_type['optionSource'], option_type['optionSourceType'], api_client, option_params)
452
+ config_multi_select = option_type["config"] && ["true","on"].include?(option_type["config"]["multiSelect"].to_s)
453
+ if config_multi_select
454
+ value = select_options.collect { |it| it['value'] }
455
+ elsif select_options.is_a?(Array)
456
+ value = select_options[0] ? select_options[0]['value'] : nil
457
+ elsif select_options.is_a?(Hash)
458
+ value = select_options['value']
459
+ else
460
+ value = select_options
461
+ end
380
462
  end
381
463
  elsif option_type['type'] == 'file'
382
464
  value = file_prompt(option_type)
383
- elsif option_type['type'] == 'file-content'
465
+ elsif option_type['type'] == 'file-content' || option_type['type'] == 'fileContent'
384
466
  value = file_content_prompt(option_type, options, api_client, {})
467
+ elsif option_type['type'] == 'logoSelector'
468
+ value = file_prompt(option_type)
385
469
  elsif option_type['type'] == 'multiText'
386
470
  value = multitext_prompt(option_type)
387
471
  elsif option_type['type'] == 'azureMarketplace'
@@ -396,7 +480,6 @@ module Morpheus
396
480
  value = generic_prompt(option_type)
397
481
  end
398
482
  end
399
-
400
483
  # --labels x,y,z uses processValue proc to convert strings to an array
401
484
  if option_type['processValue'].is_a?(Proc)
402
485
  value = option_type['processValue'].call(value)
@@ -409,6 +492,61 @@ module Morpheus
409
492
  if value && value.is_a?(String)
410
493
  value = value.split(",").collect {|it| it.strip }
411
494
  end
495
+ # todo: Handle these types added with the new form fields:
496
+ #
497
+ # byteSize
498
+ # code-editor
499
+ # fileContent
500
+ # logoSelector
501
+ # keyValue
502
+ # textArray
503
+ # typeahead
504
+ # group
505
+ # cloud
506
+ # environment
507
+ # diskManager
508
+ # layout
509
+ # networkManager
510
+ # plan
511
+ # resourcePool
512
+ # secGroup
513
+ # tag
514
+ # httpHeader
515
+ elsif option_type['type'] == 'byteSize'
516
+ if value.to_s.empty?
517
+ value = 0 # nil
518
+ elsif value.is_a?(String)
519
+ if value.to_s.upcase.include?("G")
520
+ value = value.to_i * 1024 * 1024 * 1024
521
+ elsif value.to_s.upcase.include?("M")
522
+ value = value * 1024 * 1024
523
+ else
524
+ # assume bytes by default..
525
+ value = value.to_i
526
+ end
527
+ end
528
+ elsif option_type['type'] == 'keyValue'
529
+ value = try_as_json(value)
530
+ if value.is_a?(String)
531
+ map = {}
532
+ value.split(",").each do |it|
533
+ pair = it.split("=");
534
+ map[pair[0].to_s.strip] = pair[1..-1].join("=").strip
535
+ end
536
+ value = map
537
+ end
538
+ elsif option_type['type'] == 'textArray'
539
+ value = try_as_json(value)
540
+ if value.is_a?(String)
541
+ value = value.split(",").collect {|it| it.to_s.strip }
542
+ end
543
+ else
544
+ # default translation
545
+ # for non text inputs, try to parse value as JSON
546
+ # if option_type['type'] == 'group' || option_type['type'] == 'cloud' etc..
547
+ if value.is_a?(String) && option_type['type'] != 'text'
548
+ value = try_as_json(value)
549
+ end
412
550
  end
413
551
  context_map[field_name] = value if !(value.nil? || (value.is_a?(Hash) && value.empty?))
414
552
  parent_context_map.reject! {|k,v| k == parent_ns && (v.nil? || (v.is_a?(Hash) && v.empty?))}
@@ -526,7 +664,12 @@ module Morpheus
526
664
  if matched_options.size > 1
527
665
  print Term::ANSIColor.red, "\nInvalid Option #{option_type['fieldLabel']}: [#{use_value}]\n\n", Term::ANSIColor.reset
528
666
  print Term::ANSIColor.red, " * #{option_type['fieldLabel']} [-O #{option_type['fieldContext'] ? (option_type['fieldContext']+'.') : ''}#{option_type['fieldName']}=] - #{option_type['description']}\n", Term::ANSIColor.reset
529
- display_select_options(option_type, matched_options)
667
+ if matched_options && matched_options.size > 10
668
+ display_select_options(option_type, matched_options.first(10))
669
+ puts " (#{matched_options.size-10} more)"
670
+ else
671
+ display_select_options(option_type, matched_options)
672
+ end
530
673
  print "The value '#{input}' matched #{matched_options.size()} options.\n"
531
674
  # print "Perhaps you meant one of these? #{ored_list(matched_options.collect {|i|i[value_field]}, 3)}\n"
532
675
  print "Try using value instead of name.\n"
@@ -595,7 +738,12 @@ module Morpheus
595
738
  if matched_options.size > 1
596
739
  print Term::ANSIColor.red, "\nInvalid Option #{option_type['fieldLabel']}: [#{default_value}]\n\n", Term::ANSIColor.reset
597
740
  print Term::ANSIColor.red, " * #{option_type['fieldLabel']} [-O #{option_type['fieldContext'] ? (option_type['fieldContext']+'.') : ''}#{option_type['fieldName']}=] - #{option_type['description']}\n", Term::ANSIColor.reset
598
- display_select_options(option_type, matched_options)
741
+ if matched_options && matched_options.size > 10
742
+ display_select_options(option_type, matched_options.first(10))
743
+ puts " (#{matched_options.size-10} more)"
744
+ else
745
+ display_select_options(option_type, matched_options)
746
+ end
599
747
  print "The value '#{default_value}' matched #{matched_options.size()} options.\n"
600
748
  # print "Perhaps you meant one of these? #{ored_list(matched_options.collect {|i|i[value_field]}, 3)}\n"
601
749
  print "Try using value instead of name.\n"
@@ -679,7 +827,12 @@ module Morpheus
679
827
  if matched_options.size > 1
680
828
  print Term::ANSIColor.red, "\nInvalid Option #{option_type['fieldLabel']}: [#{input}]\n\n", Term::ANSIColor.reset
681
829
  print Term::ANSIColor.red, " * #{option_type['fieldLabel']} [-O #{option_type['fieldContext'] ? (option_type['fieldContext']+'.') : ''}#{option_type['fieldName']}=] - #{option_type['description']}\n", Term::ANSIColor.reset
682
- display_select_options(option_type, matched_options)
830
+ if matched_options && matched_options.size > 10
831
+ display_select_options(option_type, matched_options.first(10))
832
+ puts " (#{matched_options.size-10} more)"
833
+ else
834
+ display_select_options(option_type, matched_options)
835
+ end
683
836
  print "The value '#{input}' matched #{matched_options.size()} options.\n"
684
837
  # print "Perhaps you meant one of these? #{ored_list(matched_options.collect {|i|i[value_field]}, 3)}\n"
685
838
  print "Try using value instead of name.\n"
@@ -867,7 +1020,12 @@ module Morpheus
867
1020
  exit 1
868
1021
  else
869
1022
  #help_prompt(option_type)
870
- display_select_options(option_type, select_options)
1023
+ if select_options && select_options.size > 10
1024
+ display_select_options(option_type, select_options.first(10))
1025
+ puts " (#{select_options.size-10} more)"
1026
+ else
1027
+ display_select_options(option_type, select_options)
1028
+ end
871
1029
  print "\n"
872
1030
  if select_options.empty?
873
1031
  print "The value '#{input}' matched 0 options.\n"
@@ -1381,6 +1539,19 @@ module Morpheus
1381
1539
  end
1382
1540
  rtn
1383
1541
  end
1542
+
1543
+ def self.try_as_json(val)
1544
+ if val.is_a?(String)
1545
+ if (val.to_s[0] == '{' && val.to_s[-1] == '}') || (val.to_s[0] == '[' && val.to_s[-1] == ']')
1546
+ begin
1547
+ val = JSON.parse(val)
1548
+ rescue
1549
+ Morpheus::Logging::DarkPrinter.puts "Failed to parse option value '#{val}' as JSON" if Morpheus::Logging.debug?
1550
+ end
1551
+ end
1552
+ end
1553
+ return val
1554
+ end
1384
1555
  end
1385
1556
  end
1386
1557
  end
@@ -1,6 +1,6 @@
1
1
 
2
2
  module Morpheus
3
3
  module Cli
4
- VERSION = "6.3.0"
4
+ VERSION = "6.3.2"
5
5
  end
6
6
  end
@@ -50,9 +50,12 @@ module Morpheus::Routes
50
50
  "#!app-templates", # App Blueprints (blueprints)
51
51
  "#!catalog-items",
52
52
  "#!compute-type-layouts", # Cluster Layouts
53
+ "#!compute-type-packages", # Cluster Packages
53
54
  ],
54
55
  :'virtual-images' => {},
55
56
  options: [
57
+ "#!forms", # Forms
58
+ "#!option-types", # Inputs
56
59
  "#!option-type-lists", # Option Lists
57
60
  ],
58
61
  templates: [
@@ -181,6 +184,12 @@ module Morpheus::Routes
181
184
 
182
185
  # map well known aliases
183
186
  case(path.dasherize.pluralize)
187
+ # when "forms"
188
+ # path = "/library/options/#!forms"
189
+ when "inputs"
190
+ path = "/library/options/#!option-types"
191
+ when "option-lists"
192
+ path = "/library/options/#!option-type-lists"
184
193
  when "backups"
185
194
  path = id ? "/backups/show" : "/backups/list"
186
195
  when "backup-jobs"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: morpheus-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.3.0
4
+ version: 6.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Estes
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2023-10-30 00:00:00.000000000 Z
14
+ date: 2023-12-14 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler
@@ -251,6 +251,7 @@ files:
251
251
  - lib/morpheus/api/jobs_interface.rb
252
252
  - lib/morpheus/api/key_pairs_interface.rb
253
253
  - lib/morpheus/api/library_cluster_layouts_interface.rb
254
+ - lib/morpheus/api/library_cluster_packages_interface.rb
254
255
  - lib/morpheus/api/library_container_scripts_interface.rb
255
256
  - lib/morpheus/api/library_container_templates_interface.rb
256
257
  - lib/morpheus/api/library_container_types_interface.rb
@@ -301,6 +302,7 @@ files:
301
302
  - lib/morpheus/api/network_subnets_interface.rb
302
303
  - lib/morpheus/api/network_types_interface.rb
303
304
  - lib/morpheus/api/networks_interface.rb
305
+ - lib/morpheus/api/option_type_forms_interface.rb
304
306
  - lib/morpheus/api/option_type_lists_interface.rb
305
307
  - lib/morpheus/api/option_types_interface.rb
306
308
  - lib/morpheus/api/options_interface.rb
@@ -430,9 +432,11 @@ files:
430
432
  - lib/morpheus/cli/commands/jobs_command.rb
431
433
  - lib/morpheus/cli/commands/key_pairs.rb
432
434
  - lib/morpheus/cli/commands/library_cluster_layouts_command.rb
435
+ - lib/morpheus/cli/commands/library_cluster_packages_command.rb
433
436
  - lib/morpheus/cli/commands/library_container_scripts_command.rb
434
437
  - lib/morpheus/cli/commands/library_container_templates_command.rb
435
438
  - lib/morpheus/cli/commands/library_container_types_command.rb
439
+ - lib/morpheus/cli/commands/library_forms_command.rb
436
440
  - lib/morpheus/cli/commands/library_instance_types_command.rb
437
441
  - lib/morpheus/cli/commands/library_layouts_command.rb
438
442
  - lib/morpheus/cli/commands/library_option_lists_command.rb
@@ -507,6 +511,7 @@ files:
507
511
  - lib/morpheus/cli/commands/security_package_types.rb
508
512
  - lib/morpheus/cli/commands/security_packages.rb
509
513
  - lib/morpheus/cli/commands/security_scans.rb
514
+ - lib/morpheus/cli/commands/self_service_command.rb
510
515
  - lib/morpheus/cli/commands/service_catalog_command.rb
511
516
  - lib/morpheus/cli/commands/service_plans_command.rb
512
517
  - lib/morpheus/cli/commands/set_prompt_command.rb