morpheus-cli 2.10.3 → 2.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/morpheus +5 -96
- data/lib/morpheus/api/api_client.rb +23 -1
- data/lib/morpheus/api/checks_interface.rb +106 -0
- data/lib/morpheus/api/incidents_interface.rb +102 -0
- data/lib/morpheus/api/monitoring_apps_interface.rb +47 -0
- data/lib/morpheus/api/monitoring_contacts_interface.rb +47 -0
- data/lib/morpheus/api/monitoring_groups_interface.rb +47 -0
- data/lib/morpheus/api/monitoring_interface.rb +36 -0
- data/lib/morpheus/api/option_type_lists_interface.rb +47 -0
- data/lib/morpheus/api/option_types_interface.rb +47 -0
- data/lib/morpheus/api/roles_interface.rb +0 -1
- data/lib/morpheus/api/setup_interface.rb +19 -9
- data/lib/morpheus/cli.rb +20 -1
- data/lib/morpheus/cli/accounts.rb +8 -3
- data/lib/morpheus/cli/app_templates.rb +19 -11
- data/lib/morpheus/cli/apps.rb +52 -37
- data/lib/morpheus/cli/cli_command.rb +229 -53
- data/lib/morpheus/cli/cli_registry.rb +48 -40
- data/lib/morpheus/cli/clouds.rb +55 -26
- data/lib/morpheus/cli/command_error.rb +12 -0
- data/lib/morpheus/cli/credentials.rb +68 -26
- data/lib/morpheus/cli/curl_command.rb +98 -0
- data/lib/morpheus/cli/dashboard_command.rb +2 -7
- data/lib/morpheus/cli/deployments.rb +4 -4
- data/lib/morpheus/cli/deploys.rb +1 -2
- data/lib/morpheus/cli/dot_file.rb +5 -8
- data/lib/morpheus/cli/error_handler.rb +179 -15
- data/lib/morpheus/cli/groups.rb +21 -13
- data/lib/morpheus/cli/hosts.rb +220 -110
- data/lib/morpheus/cli/instance_types.rb +2 -2
- data/lib/morpheus/cli/instances.rb +257 -167
- data/lib/morpheus/cli/key_pairs.rb +15 -9
- data/lib/morpheus/cli/library.rb +673 -27
- data/lib/morpheus/cli/license.rb +2 -2
- data/lib/morpheus/cli/load_balancers.rb +4 -4
- data/lib/morpheus/cli/log_level_command.rb +6 -4
- data/lib/morpheus/cli/login.rb +17 -3
- data/lib/morpheus/cli/logout.rb +25 -11
- data/lib/morpheus/cli/man_command.rb +388 -0
- data/lib/morpheus/cli/mixins/accounts_helper.rb +1 -1
- data/lib/morpheus/cli/mixins/monitoring_helper.rb +434 -0
- data/lib/morpheus/cli/mixins/print_helper.rb +620 -112
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +1 -1
- data/lib/morpheus/cli/monitoring_apps_command.rb +29 -0
- data/lib/morpheus/cli/monitoring_checks_command.rb +427 -0
- data/lib/morpheus/cli/monitoring_contacts_command.rb +373 -0
- data/lib/morpheus/cli/monitoring_groups_command.rb +29 -0
- data/lib/morpheus/cli/monitoring_incidents_command.rb +711 -0
- data/lib/morpheus/cli/option_types.rb +10 -1
- data/lib/morpheus/cli/recent_activity_command.rb +2 -5
- data/lib/morpheus/cli/remote.rb +874 -134
- data/lib/morpheus/cli/roles.rb +54 -27
- data/lib/morpheus/cli/security_group_rules.rb +2 -2
- data/lib/morpheus/cli/security_groups.rb +23 -19
- data/lib/morpheus/cli/set_prompt_command.rb +50 -0
- data/lib/morpheus/cli/shell.rb +222 -157
- data/lib/morpheus/cli/tasks.rb +19 -15
- data/lib/morpheus/cli/users.rb +27 -17
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/virtual_images.rb +28 -13
- data/lib/morpheus/cli/whoami.rb +131 -52
- data/lib/morpheus/cli/workflows.rb +24 -9
- data/lib/morpheus/formatters.rb +195 -3
- data/lib/morpheus/logging.rb +86 -0
- data/lib/morpheus/terminal.rb +371 -0
- data/scripts/generate_morpheus_commands_help.morpheus +60 -0
- metadata +21 -2
@@ -50,7 +50,7 @@ class Morpheus::Cli::KeyPairs
|
|
50
50
|
print JSON.pretty_generate(json_response)
|
51
51
|
print "\n"
|
52
52
|
else
|
53
|
-
title = "Morpheus
|
53
|
+
title = "Morpheus Key Pairs"
|
54
54
|
subtitles = []
|
55
55
|
if account
|
56
56
|
subtitles << "Account: #{account['name']}".strip
|
@@ -58,8 +58,7 @@ class Morpheus::Cli::KeyPairs
|
|
58
58
|
if params[:phrase]
|
59
59
|
subtitles << "Search: #{params[:phrase]}".strip
|
60
60
|
end
|
61
|
-
|
62
|
-
print "\n" ,cyan, bold, title, (subtitle.empty? ? "" : " - #{subtitle}"), "\n", "==================", reset, "\n\n"
|
61
|
+
print_h1 title, subtitles
|
63
62
|
if key_pairs.empty?
|
64
63
|
puts yellow,"No key pairs found.",reset
|
65
64
|
else
|
@@ -100,13 +99,20 @@ class Morpheus::Cli::KeyPairs
|
|
100
99
|
print JSON.pretty_generate({keyPair: key_pair})
|
101
100
|
print "\n"
|
102
101
|
else
|
103
|
-
|
102
|
+
print_h1 "Key Pair Details"
|
104
103
|
print cyan
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
104
|
+
if account
|
105
|
+
# print_description_list({"Account" => lambda {|it| it['account'] ? it['account']['name'] : '' } }, key_pair)
|
106
|
+
print_description_list({"Account" => lambda {|it| account['name'] } }, key_pair)
|
107
|
+
end
|
108
|
+
print_description_list({
|
109
|
+
"ID" => 'id',
|
110
|
+
"Name" => 'name',
|
111
|
+
"MD5" => 'md5',
|
112
|
+
# "Account" => lambda {|it| it['account'] ? it['account']['name'] : '' },
|
113
|
+
"Created" => lambda {|it| format_local_dt(it['dateCreated']) }
|
114
|
+
#"Updated" => lambda {|it| format_local_dt(it['lastUpdated']) }
|
115
|
+
}, key_pair)
|
110
116
|
print reset,"\n"
|
111
117
|
|
112
118
|
# todo: show public key
|
data/lib/morpheus/cli/library.rb
CHANGED
@@ -8,6 +8,8 @@ class Morpheus::Cli::Library
|
|
8
8
|
|
9
9
|
register_subcommands :list, :get, :add, :update, :remove, :'add-version'
|
10
10
|
alias_subcommand :details, :get
|
11
|
+
register_subcommands({:'option-types' => :option_types_list}, :option_types_get, :option_types_add, :option_types_update, :option_types_remove)
|
12
|
+
register_subcommands({:'option-lists' => :option_lists_list}, :option_lists_get, :option_lists_add, :option_lists_update, :option_lists_remove)
|
11
13
|
|
12
14
|
def initialize()
|
13
15
|
# @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
|
@@ -17,6 +19,8 @@ class Morpheus::Cli::Library
|
|
17
19
|
@api_client = establish_remote_appliance_connection(opts)
|
18
20
|
@custom_instance_types_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).custom_instance_types
|
19
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
|
20
24
|
end
|
21
25
|
|
22
26
|
def handle(args)
|
@@ -51,7 +55,7 @@ class Morpheus::Cli::Library
|
|
51
55
|
end
|
52
56
|
|
53
57
|
instance_types = json_response['instanceTypes']
|
54
|
-
|
58
|
+
print_h1 "Morpheus Custom Instance Types"
|
55
59
|
if instance_types.empty?
|
56
60
|
puts yellow,"No instance types currently configured.",reset
|
57
61
|
else
|
@@ -99,18 +103,13 @@ class Morpheus::Cli::Library
|
|
99
103
|
print JSON.pretty_generate({instanceType: instance_type}), "\n"
|
100
104
|
return
|
101
105
|
end
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
print
|
107
|
-
versions = instance_type['versions'].join(', ')
|
108
|
-
print cyan, "= #{instance_type['name']} (#{instance_type['code']}) - #{versions}\n"
|
109
|
-
instance_type['instanceTypeLayouts'].each do |layout|
|
110
|
-
print green, " - #{layout['name']}\n",reset
|
111
|
-
end
|
112
|
-
print reset,"\n"
|
106
|
+
print_h1 "Custom Instance Type Details"
|
107
|
+
versions = instance_type['versions'].join(', ')
|
108
|
+
print cyan, "= #{instance_type['name']} (#{instance_type['code']}) - #{versions}\n"
|
109
|
+
instance_type['instanceTypeLayouts'].each do |layout|
|
110
|
+
print green, " - #{layout['name']}\n",reset
|
113
111
|
end
|
112
|
+
print reset,"\n"
|
114
113
|
|
115
114
|
rescue RestClient::Exception => e
|
116
115
|
print_rest_exception(e, options)
|
@@ -402,6 +401,521 @@ class Morpheus::Cli::Library
|
|
402
401
|
end
|
403
402
|
|
404
403
|
|
404
|
+
#### Option Type actions
|
405
|
+
|
406
|
+
def option_types_list(args)
|
407
|
+
options = {}
|
408
|
+
optparse = OptionParser.new do|opts|
|
409
|
+
opts.banner = subcommand_usage()
|
410
|
+
build_common_options(opts, options, [:list, :dry_run, :json])
|
411
|
+
end
|
412
|
+
optparse.parse!(args)
|
413
|
+
connect(options)
|
414
|
+
begin
|
415
|
+
params = {}
|
416
|
+
[:phrase, :offset, :max, :sort, :direction].each do |k|
|
417
|
+
params[k] = options[k] unless options[k].nil?
|
418
|
+
end
|
419
|
+
|
420
|
+
if options[:dry_run]
|
421
|
+
print_dry_run @option_types_interface.dry.list(params)
|
422
|
+
return
|
423
|
+
end
|
424
|
+
|
425
|
+
json_response = @option_types_interface.list(params)
|
426
|
+
|
427
|
+
if options[:json]
|
428
|
+
print JSON.pretty_generate(json_response), "\n"
|
429
|
+
return
|
430
|
+
end
|
431
|
+
|
432
|
+
option_types = json_response['optionTypes']
|
433
|
+
print_h1 "Morpheus Option Types"
|
434
|
+
if option_types.empty?
|
435
|
+
print cyan,"No option types found.",reset,"\n"
|
436
|
+
else
|
437
|
+
rows = option_types.collect do |option_type|
|
438
|
+
{
|
439
|
+
id: option_type['id'],
|
440
|
+
name: option_type['name'],
|
441
|
+
type: option_type['type'],
|
442
|
+
fieldLabel: option_type['fieldLabel'],
|
443
|
+
fieldName: option_type['fieldName'],
|
444
|
+
default: option_type['defaultValue'],
|
445
|
+
required: option_type['required'] ? 'yes' : 'no'
|
446
|
+
}
|
447
|
+
end
|
448
|
+
print cyan
|
449
|
+
tp rows, [
|
450
|
+
:id,
|
451
|
+
:name,
|
452
|
+
:type,
|
453
|
+
{:fieldLabel => {:display_name => "Field Label"} },
|
454
|
+
{:fieldName => {:display_name => "Field Name"} },
|
455
|
+
:default,
|
456
|
+
:required
|
457
|
+
]
|
458
|
+
print reset
|
459
|
+
print_results_pagination(json_response)
|
460
|
+
end
|
461
|
+
print reset,"\n"
|
462
|
+
rescue RestClient::Exception => e
|
463
|
+
print_rest_exception(e, options)
|
464
|
+
exit 1
|
465
|
+
end
|
466
|
+
end
|
467
|
+
|
468
|
+
def option_types_get(args)
|
469
|
+
options = {}
|
470
|
+
optparse = OptionParser.new do|opts|
|
471
|
+
opts.banner = subcommand_usage("[name]")
|
472
|
+
build_common_options(opts, options, [:json, :dry_run])
|
473
|
+
end
|
474
|
+
optparse.parse!(args)
|
475
|
+
if args.count < 1
|
476
|
+
puts optparse
|
477
|
+
exit 1
|
478
|
+
end
|
479
|
+
|
480
|
+
connect(options)
|
481
|
+
begin
|
482
|
+
if options[:dry_run]
|
483
|
+
if args[0].to_s =~ /\A\d{1,}\Z/
|
484
|
+
print_dry_run @option_types_interface.dry.get(args[0].to_i)
|
485
|
+
else
|
486
|
+
print_dry_run @option_types_interface.dry.list({name: args[0]})
|
487
|
+
end
|
488
|
+
return
|
489
|
+
end
|
490
|
+
option_type = find_option_type_by_name_or_id(args[0])
|
491
|
+
exit 1 if option_type.nil?
|
492
|
+
|
493
|
+
if options[:json]
|
494
|
+
print JSON.pretty_generate({optionType: option_type}), "\n"
|
495
|
+
return
|
496
|
+
end
|
497
|
+
|
498
|
+
print_h1 "Option Type Details"
|
499
|
+
print cyan
|
500
|
+
print_description_list({
|
501
|
+
"ID" => 'id',
|
502
|
+
"Name" => 'name',
|
503
|
+
"Description" => 'description',
|
504
|
+
"Field Name" => 'fieldName',
|
505
|
+
"Type" => lambda {|it| it['type'].to_s.capitalize },
|
506
|
+
"Label" => 'fieldLabel',
|
507
|
+
"Placeholder" => 'placeHolder',
|
508
|
+
"Default Value" => 'defaultValue'
|
509
|
+
}, option_type)
|
510
|
+
print reset,"\n"
|
511
|
+
|
512
|
+
rescue RestClient::Exception => e
|
513
|
+
print_rest_exception(e, options)
|
514
|
+
exit 1
|
515
|
+
end
|
516
|
+
end
|
517
|
+
|
518
|
+
def option_types_add(args)
|
519
|
+
# JD: this is annoying because our option_types (for prompting and help)
|
520
|
+
# are the same type of object being managed here.., options options options
|
521
|
+
options = {}
|
522
|
+
optparse = OptionParser.new do|opts|
|
523
|
+
opts.banner = subcommand_usage("[options]")
|
524
|
+
build_option_type_options(opts, options, new_option_type_option_types)
|
525
|
+
build_common_options(opts, options, [:options, :json, :dry_run])
|
526
|
+
end
|
527
|
+
optparse.parse!(args)
|
528
|
+
connect(options)
|
529
|
+
begin
|
530
|
+
params = Morpheus::Cli::OptionTypes.prompt(new_option_type_option_types, options[:options], @api_client, options[:params])
|
531
|
+
if params.key?('required')
|
532
|
+
params['required'] = ['on','true'].include?(params['required'].to_s)
|
533
|
+
end
|
534
|
+
option_type_payload = params
|
535
|
+
payload = {optionType: option_type_payload}
|
536
|
+
if options[:dry_run]
|
537
|
+
print_dry_run @option_types_interface.dry.create(payload)
|
538
|
+
return
|
539
|
+
end
|
540
|
+
json_response = @option_types_interface.create(payload)
|
541
|
+
if options[:json]
|
542
|
+
print JSON.pretty_generate(json_response), "\n"
|
543
|
+
return
|
544
|
+
end
|
545
|
+
print_green_success "Added Option Type #{option_type_payload['name']}"
|
546
|
+
#option_types_list([])
|
547
|
+
option_types_get([option_type['id']])
|
548
|
+
rescue RestClient::Exception => e
|
549
|
+
print_rest_exception(e, options)
|
550
|
+
exit 1
|
551
|
+
end
|
552
|
+
end
|
553
|
+
|
554
|
+
def option_types_update(args)
|
555
|
+
# JD: this is annoying because our option_types (for prompting and help)
|
556
|
+
# are the same type of object being managed here.., options options options
|
557
|
+
options = {}
|
558
|
+
optparse = OptionParser.new do|opts|
|
559
|
+
opts.banner = subcommand_usage("[name] [options]")
|
560
|
+
build_option_type_options(opts, options, update_option_type_option_types)
|
561
|
+
build_common_options(opts, options, [:options, :json, :dry_run])
|
562
|
+
end
|
563
|
+
optparse.parse!(args)
|
564
|
+
connect(options)
|
565
|
+
begin
|
566
|
+
option_type = find_option_type_by_name_or_id(args[0])
|
567
|
+
exit 1 if option_type.nil?
|
568
|
+
|
569
|
+
#params = options[:options] || {}
|
570
|
+
params = Morpheus::Cli::OptionTypes.no_prompt(update_option_type_option_types, options[:options], @api_client, options[:params])
|
571
|
+
if params.empty?
|
572
|
+
print_red_alert "Specify atleast one option to update"
|
573
|
+
puts optparse
|
574
|
+
exit 1
|
575
|
+
end
|
576
|
+
if params.key?('required')
|
577
|
+
params['required'] = ['on','true'].include?(params['required'].to_s)
|
578
|
+
end
|
579
|
+
option_type_payload = params
|
580
|
+
payload = {optionType: option_type_payload}
|
581
|
+
if options[:dry_run]
|
582
|
+
print_dry_run @option_types_interface.dry.update(option_type['id'], payload)
|
583
|
+
return
|
584
|
+
end
|
585
|
+
json_response = @option_types_interface.update(option_type['id'], payload)
|
586
|
+
if options[:json]
|
587
|
+
print JSON.pretty_generate(json_response), "\n"
|
588
|
+
return
|
589
|
+
end
|
590
|
+
print_green_success "Updated Option Type #{option_type_payload['name']}"
|
591
|
+
#option_types_list([])
|
592
|
+
option_types_get([option_type['id']])
|
593
|
+
rescue RestClient::Exception => e
|
594
|
+
print_rest_exception(e, options)
|
595
|
+
exit 1
|
596
|
+
end
|
597
|
+
end
|
598
|
+
|
599
|
+
def option_types_remove(args)
|
600
|
+
options = {}
|
601
|
+
optparse = OptionParser.new do|opts|
|
602
|
+
opts.banner = subcommand_usage("[name]")
|
603
|
+
build_common_options(opts, options, [:auto_confirm, :json, :dry_run])
|
604
|
+
end
|
605
|
+
optparse.parse!(args)
|
606
|
+
if args.count < 1
|
607
|
+
puts optparse
|
608
|
+
exit 1
|
609
|
+
end
|
610
|
+
connect(options)
|
611
|
+
|
612
|
+
begin
|
613
|
+
option_type = find_option_type_by_name_or_id(args[0])
|
614
|
+
exit 1 if option_type.nil?
|
615
|
+
|
616
|
+
unless Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the option type #{option_type['name']}?", options)
|
617
|
+
exit
|
618
|
+
end
|
619
|
+
if options[:dry_run]
|
620
|
+
print_dry_run @option_types_interface.dry.destroy(option_type['id'])
|
621
|
+
return
|
622
|
+
end
|
623
|
+
json_response = @option_types_interface.destroy(option_type['id'])
|
624
|
+
|
625
|
+
if options[:json]
|
626
|
+
print JSON.pretty_generate(json_response), "\n"
|
627
|
+
return
|
628
|
+
end
|
629
|
+
|
630
|
+
print_green_success "Removed Option Type #{option_type['name']}"
|
631
|
+
#list([])
|
632
|
+
rescue RestClient::Exception => e
|
633
|
+
print_rest_exception(e, options)
|
634
|
+
exit 1
|
635
|
+
end
|
636
|
+
end
|
637
|
+
|
638
|
+
#### Option Type List actions
|
639
|
+
|
640
|
+
def option_lists_list(args)
|
641
|
+
options = {}
|
642
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
643
|
+
opts.banner = subcommand_usage()
|
644
|
+
build_common_options(opts, options, [:list, :dry_run, :json])
|
645
|
+
opts.footer = "This outputs a list of custom Option List records."
|
646
|
+
end
|
647
|
+
optparse.parse!(args)
|
648
|
+
connect(options)
|
649
|
+
begin
|
650
|
+
params = {}
|
651
|
+
[:phrase, :offset, :max, :sort, :direction].each do |k|
|
652
|
+
params[k] = options[k] unless options[k].nil?
|
653
|
+
end
|
654
|
+
|
655
|
+
if options[:dry_run]
|
656
|
+
print_dry_run @option_type_lists_interface.dry.list(params)
|
657
|
+
return
|
658
|
+
end
|
659
|
+
|
660
|
+
json_response = @option_type_lists_interface.list(params)
|
661
|
+
|
662
|
+
if options[:json]
|
663
|
+
print JSON.pretty_generate(json_response), "\n"
|
664
|
+
return
|
665
|
+
end
|
666
|
+
|
667
|
+
option_type_lists = json_response['optionTypeLists']
|
668
|
+
print_h1 "Morpheus Option Lists"
|
669
|
+
if option_type_lists.empty?
|
670
|
+
print cyan,"No option lists found.",reset,"\n"
|
671
|
+
else
|
672
|
+
rows = option_type_lists.collect do |option_type_list|
|
673
|
+
{
|
674
|
+
id: option_type_list['id'],
|
675
|
+
name: option_type_list['name'],
|
676
|
+
description: option_type_list['description'],
|
677
|
+
type: option_type_list['type'],
|
678
|
+
size: option_type_list['listItems'] ? option_type_list['listItems'].size : ''
|
679
|
+
}
|
680
|
+
end
|
681
|
+
print cyan
|
682
|
+
tp rows, [
|
683
|
+
:id,
|
684
|
+
:name,
|
685
|
+
:description,
|
686
|
+
:type,
|
687
|
+
:size
|
688
|
+
]
|
689
|
+
print reset
|
690
|
+
print_results_pagination(json_response)
|
691
|
+
end
|
692
|
+
print reset,"\n"
|
693
|
+
rescue RestClient::Exception => e
|
694
|
+
print_rest_exception(e, options)
|
695
|
+
exit 1
|
696
|
+
end
|
697
|
+
end
|
698
|
+
|
699
|
+
def option_lists_get(args)
|
700
|
+
options = {}
|
701
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
702
|
+
opts.banner = subcommand_usage("[name]")
|
703
|
+
build_common_options(opts, options, [:json, :dry_run])
|
704
|
+
opts.footer = "This outputs details about a particular Option List."
|
705
|
+
end
|
706
|
+
optparse.parse!(args)
|
707
|
+
if args.count < 1
|
708
|
+
puts optparse
|
709
|
+
exit 1
|
710
|
+
end
|
711
|
+
|
712
|
+
connect(options)
|
713
|
+
begin
|
714
|
+
if options[:dry_run]
|
715
|
+
if args[0].to_s =~ /\A\d{1,}\Z/
|
716
|
+
print_dry_run @option_type_lists_interface.dry.get(args[0].to_i)
|
717
|
+
else
|
718
|
+
print_dry_run @option_type_lists_interface.dry.list({name: args[0]})
|
719
|
+
end
|
720
|
+
return
|
721
|
+
end
|
722
|
+
option_type_list = find_option_type_list_by_name_or_id(args[0])
|
723
|
+
exit 1 if option_type_list.nil?
|
724
|
+
|
725
|
+
if options[:json]
|
726
|
+
print JSON.pretty_generate({optionTypeList: option_type_list}), "\n"
|
727
|
+
return
|
728
|
+
end
|
729
|
+
|
730
|
+
print_h1 "Option List Details"
|
731
|
+
print cyan
|
732
|
+
if option_type_list['type'] == 'manual'
|
733
|
+
print_description_list({
|
734
|
+
"ID" => 'id',
|
735
|
+
"Name" => 'name',
|
736
|
+
"Description" => 'description',
|
737
|
+
"Type" => lambda {|it| it['type'].to_s.capitalize },
|
738
|
+
}, option_type_list)
|
739
|
+
print_h2 "Initial Dataset"
|
740
|
+
print bright_black," #{option_type_list['initialDataset']}","\n",reset
|
741
|
+
else
|
742
|
+
print_description_list({
|
743
|
+
"ID" => 'id',
|
744
|
+
"Name" => 'name',
|
745
|
+
"Description" => 'description',
|
746
|
+
"Type" => lambda {|it| it['type'].to_s.capitalize },
|
747
|
+
"Source URL" => 'sourceUrl',
|
748
|
+
"Ignore SSL Errors" => lambda {|it| format_boolean it['ignoreSSLErrors'] },
|
749
|
+
"Source Method" => lambda {|it| it['sourceMethod'].to_s.upcase },
|
750
|
+
}, option_type_list)
|
751
|
+
if !option_type_list['initialDataset'].empty?
|
752
|
+
print_h2 "Initial Dataset"
|
753
|
+
print bright_black," #{option_type_list['initialDataset']}","\n",reset
|
754
|
+
end
|
755
|
+
if !option_type_list['translationScript'].empty?
|
756
|
+
print_h2 "Translation Script"
|
757
|
+
print bright_black," #{option_type_list['translationScript']}","\n",reset
|
758
|
+
end
|
759
|
+
end
|
760
|
+
|
761
|
+
print_h2 "List Items"
|
762
|
+
if option_type_list['listItems']
|
763
|
+
# puts "\tNAME\tVALUE"
|
764
|
+
# option_type_list['listItems'].each do |list_item|
|
765
|
+
# puts "\t#{list_item['name']}\t#{list_item['value']}"
|
766
|
+
# end
|
767
|
+
print cyan
|
768
|
+
tp option_type_list['listItems'], ['name', 'value']
|
769
|
+
else
|
770
|
+
puts "No data"
|
771
|
+
end
|
772
|
+
print reset,"\n"
|
773
|
+
|
774
|
+
rescue RestClient::Exception => e
|
775
|
+
print_rest_exception(e, options)
|
776
|
+
exit 1
|
777
|
+
end
|
778
|
+
end
|
779
|
+
|
780
|
+
def option_lists_add(args)
|
781
|
+
# JD: this is annoying because our option_types (for prompting and help)
|
782
|
+
# are the same type of object being managed here.., options options options
|
783
|
+
options = {}
|
784
|
+
my_option_types = nil
|
785
|
+
list_type = nil
|
786
|
+
optparse = OptionParser.new do|opts|
|
787
|
+
opts.banner = subcommand_usage("[type] [options]")
|
788
|
+
opts.on( '-t', '--type TYPE', "Option List Type. (rest, manual)" ) do |val|
|
789
|
+
list_type = val
|
790
|
+
# options[:options] ||= {}
|
791
|
+
# options[:options]['type'] = val
|
792
|
+
end
|
793
|
+
build_option_type_options(opts, options, new_option_type_list_option_types())
|
794
|
+
build_common_options(opts, options, [:options, :json, :dry_run])
|
795
|
+
end
|
796
|
+
optparse.parse!(args)
|
797
|
+
|
798
|
+
if !list_type
|
799
|
+
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, {})
|
800
|
+
list_type = v_prompt['type']
|
801
|
+
end
|
802
|
+
|
803
|
+
connect(options)
|
804
|
+
begin
|
805
|
+
params = Morpheus::Cli::OptionTypes.prompt(new_option_type_list_option_types(list_type), options[:options], @api_client, options[:params])
|
806
|
+
if params.key?('required')
|
807
|
+
params['required'] = ['on','true'].include?(params['required'].to_s)
|
808
|
+
end
|
809
|
+
params['type'] = list_type
|
810
|
+
list_payload = params
|
811
|
+
payload = {'optionTypeList' => list_payload}
|
812
|
+
if options[:dry_run]
|
813
|
+
print_dry_run @option_type_lists_interface.dry.create(payload)
|
814
|
+
return
|
815
|
+
end
|
816
|
+
json_response = @option_type_lists_interface.create(payload)
|
817
|
+
if options[:json]
|
818
|
+
print JSON.pretty_generate(json_response), "\n"
|
819
|
+
return
|
820
|
+
end
|
821
|
+
print_green_success "Added Option List #{list_payload['name']}"
|
822
|
+
#option_lists_list([])
|
823
|
+
option_type_list = json_response['optionTypeList']
|
824
|
+
if option_type_list
|
825
|
+
option_lists_get([option_type_list['id']])
|
826
|
+
end
|
827
|
+
rescue RestClient::Exception => e
|
828
|
+
print_rest_exception(e, options)
|
829
|
+
exit 1
|
830
|
+
end
|
831
|
+
end
|
832
|
+
|
833
|
+
def option_lists_update(args)
|
834
|
+
# JD: this is annoying because our option_types (for prompting and help)
|
835
|
+
# are the same type of object being managed here.., options options options
|
836
|
+
options = {}
|
837
|
+
optparse = OptionParser.new do|opts|
|
838
|
+
opts.banner = subcommand_usage("[name] [options]")
|
839
|
+
build_option_type_options(opts, options, update_option_type_list_option_types())
|
840
|
+
build_common_options(opts, options, [:options, :json, :dry_run])
|
841
|
+
end
|
842
|
+
optparse.parse!(args)
|
843
|
+
connect(options)
|
844
|
+
begin
|
845
|
+
option_type_list = find_option_type_list_by_name_or_id(args[0])
|
846
|
+
exit 1 if option_type_list.nil?
|
847
|
+
|
848
|
+
list_type = option_type_list['type']
|
849
|
+
prompt_options = update_option_type_list_option_types(list_type)
|
850
|
+
#params = options[:options] || {}
|
851
|
+
params = Morpheus::Cli::OptionTypes.no_prompt(prompt_options, options[:options], @api_client, options[:params])
|
852
|
+
if params.empty?
|
853
|
+
print_red_alert "Specify atleast one option to update"
|
854
|
+
puts optparse
|
855
|
+
exit 1
|
856
|
+
end
|
857
|
+
if params.key?('required')
|
858
|
+
params['required'] = ['on','true'].include?(params['required'].to_s)
|
859
|
+
end
|
860
|
+
list_payload = params
|
861
|
+
payload = {optionTypeList: list_payload}
|
862
|
+
if options[:dry_run]
|
863
|
+
print_dry_run @option_type_lists_interface.dry.update(option_type_list['id'], payload)
|
864
|
+
return
|
865
|
+
end
|
866
|
+
json_response = @option_type_lists_interface.update(option_type_list['id'], payload)
|
867
|
+
if options[:json]
|
868
|
+
print JSON.pretty_generate(json_response), "\n"
|
869
|
+
return
|
870
|
+
end
|
871
|
+
print_green_success "Updated Option List #{list_payload['name']}"
|
872
|
+
#option_lists_list([])
|
873
|
+
option_lists_get([option_type_list['id']])
|
874
|
+
rescue RestClient::Exception => e
|
875
|
+
print_rest_exception(e, options)
|
876
|
+
exit 1
|
877
|
+
end
|
878
|
+
end
|
879
|
+
|
880
|
+
def option_lists_remove(args)
|
881
|
+
options = {}
|
882
|
+
optparse = OptionParser.new do|opts|
|
883
|
+
opts.banner = subcommand_usage("[name]")
|
884
|
+
build_common_options(opts, options, [:auto_confirm, :json, :dry_run])
|
885
|
+
end
|
886
|
+
optparse.parse!(args)
|
887
|
+
if args.count < 1
|
888
|
+
puts optparse
|
889
|
+
exit 1
|
890
|
+
end
|
891
|
+
connect(options)
|
892
|
+
|
893
|
+
begin
|
894
|
+
option_type_list = find_option_type_list_by_name_or_id(args[0])
|
895
|
+
exit 1 if option_type_list.nil?
|
896
|
+
|
897
|
+
unless Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the option type #{option_type_list['name']}?", options)
|
898
|
+
exit
|
899
|
+
end
|
900
|
+
if options[:dry_run]
|
901
|
+
print_dry_run @option_type_lists_interface.dry.destroy(option_type_list['id'])
|
902
|
+
return
|
903
|
+
end
|
904
|
+
json_response = @option_type_lists_interface.destroy(option_type_list['id'])
|
905
|
+
|
906
|
+
if options[:json]
|
907
|
+
print JSON.pretty_generate(json_response), "\n"
|
908
|
+
return
|
909
|
+
end
|
910
|
+
|
911
|
+
print_green_success "Removed Option List #{option_type_list['name']}"
|
912
|
+
#option_lists_list([])
|
913
|
+
rescue RestClient::Exception => e
|
914
|
+
print_rest_exception(e, options)
|
915
|
+
exit 1
|
916
|
+
end
|
917
|
+
end
|
918
|
+
|
405
919
|
private
|
406
920
|
|
407
921
|
def find_custom_instance_type_by_code(code)
|
@@ -509,30 +1023,162 @@ class Morpheus::Cli::Library
|
|
509
1023
|
has_another_port = options[:options] && options[:options]["exposedPort#{port_index}"]
|
510
1024
|
add_another_port = has_another_port || (!no_prompt && Morpheus::Cli::OptionTypes.confirm("Add an exposed port?"))
|
511
1025
|
while add_another_port do
|
512
|
-
|
1026
|
+
field_context = "exposedPort#{port_index}"
|
513
1027
|
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
1028
|
+
port = {}
|
1029
|
+
#port['name'] ||= "Port #{port_index}"
|
1030
|
+
port_label = port_index == 0 ? "Port" : "Port [#{port_index+1}]"
|
1031
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => field_context, 'fieldName' => 'name', 'type' => 'text', 'fieldLabel' => "#{port_label} Name", 'required' => false, 'description' => 'Choose a name for this port.', 'defaultValue' => port['name']}], options[:options])
|
1032
|
+
port['name'] = v_prompt[field_context]['name']
|
519
1033
|
|
520
|
-
|
521
|
-
|
1034
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => field_context, 'fieldName' => 'port', 'type' => 'number', 'fieldLabel' => "#{port_label} Number", 'required' => true, 'description' => 'A port number. eg. 8001', 'defaultValue' => (port['port'] ? port['port'].to_i : nil)}], options[:options])
|
1035
|
+
port['port'] = v_prompt[field_context]['port']
|
522
1036
|
|
523
|
-
|
524
|
-
|
1037
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => field_context, 'fieldName' => 'loadBalanceProtocol', 'type' => 'select', 'fieldLabel' => "#{port_label} LB", 'selectOptions' => load_balance_protocols, 'required' => false, 'skipSingleOption' => true, 'description' => 'Choose a load balance protocol.', 'defaultValue' => port['loadBalanceProtocol']}], options[:options])
|
1038
|
+
port['loadBalanceProtocol'] = v_prompt[field_context]['loadBalanceProtocol']
|
1039
|
+
|
1040
|
+
ports << port
|
1041
|
+
port_index += 1
|
1042
|
+
has_another_port = options[:options] && options[:options]["exposedPort#{port_index}"]
|
1043
|
+
add_another_port = has_another_port || (!no_prompt && Morpheus::Cli::OptionTypes.confirm("Add another exposed port?"))
|
1044
|
+
|
1045
|
+
end
|
525
1046
|
|
526
|
-
ports << port
|
527
|
-
port_index += 1
|
528
|
-
has_another_port = options[:options] && options[:options]["exposedPort#{port_index}"]
|
529
|
-
add_another_port = has_another_port || (!no_prompt && Morpheus::Cli::OptionTypes.confirm("Add another exposed port?"))
|
530
1047
|
|
1048
|
+
return ports
|
1049
|
+
end
|
1050
|
+
|
1051
|
+
def find_option_type_by_name_or_id(val)
|
1052
|
+
if val.to_s =~ /\A\d{1,}\Z/
|
1053
|
+
return find_option_type_by_id(val)
|
1054
|
+
else
|
1055
|
+
return find_option_type_by_name(val)
|
1056
|
+
end
|
1057
|
+
end
|
1058
|
+
|
1059
|
+
def find_option_type_by_id(id)
|
1060
|
+
begin
|
1061
|
+
json_response = @option_types_interface.get(id.to_i)
|
1062
|
+
return json_response['optionType']
|
1063
|
+
rescue RestClient::Exception => e
|
1064
|
+
if e.response && e.response.code == 404
|
1065
|
+
print_red_alert "Option Type not found by id #{id}"
|
1066
|
+
exit 1
|
1067
|
+
else
|
1068
|
+
raise e
|
531
1069
|
end
|
1070
|
+
end
|
1071
|
+
end
|
1072
|
+
|
1073
|
+
def find_option_type_by_name(name)
|
1074
|
+
json_results = @option_types_interface.list({name: name.to_s})
|
1075
|
+
if json_results['optionTypes'].empty?
|
1076
|
+
print_red_alert "Option Type not found by name #{name}"
|
1077
|
+
exit 1
|
1078
|
+
end
|
1079
|
+
option_type = json_results['optionTypes'][0]
|
1080
|
+
return option_type
|
1081
|
+
end
|
532
1082
|
|
1083
|
+
def new_option_type_option_types
|
1084
|
+
[
|
1085
|
+
{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'displayOrder' => 1},
|
1086
|
+
{'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'displayOrder' => 2},
|
1087
|
+
{'fieldName' => 'fieldName', 'fieldLabel' => 'Field Name', 'type' => 'text', 'required' => true, 'description' => 'This is the input fieldName property that the value gets assigned to.', 'displayOrder' => 3},
|
1088
|
+
{'fieldName' => 'type', 'fieldLabel' => 'Type', 'type' => 'select', 'selectOptions' => [{'name' => 'Text', 'value' => 'text'}, {'name' => 'Password', 'value' => 'password'}, {'name' => 'Number', 'value' => 'number'}, {'name' => 'Checkbox', 'value' => 'checkbox'}, {'name' => 'Select', 'value' => 'select'}, {'name' => 'Hidden', 'value' => 'hidden'}], 'defaultValue' => 'text', 'required' => true, 'displayOrder' => 4},
|
1089
|
+
{'fieldName' => 'fieldLabel', 'fieldLabel' => 'Field Label', 'type' => 'text', 'required' => true, 'description' => 'This is the input label that shows typically to the left of a custom option.', 'displayOrder' => 5},
|
1090
|
+
{'fieldName' => 'placeHolder', 'fieldLabel' => 'Placeholder', 'type' => 'text', 'displayOrder' => 6},
|
1091
|
+
{'fieldName' => 'defaultValue', 'fieldLabel' => 'Default Value', 'type' => 'text', 'displayOrder' => 7},
|
1092
|
+
{'fieldName' => 'required', 'fieldLabel' => 'Required', 'type' => 'checkbox', 'defaultValue' => 'off', 'displayOrder' => 8},
|
1093
|
+
]
|
1094
|
+
end
|
533
1095
|
|
534
|
-
|
1096
|
+
def update_option_type_option_types
|
1097
|
+
list = new_option_type_option_types
|
1098
|
+
list.each {|it|
|
1099
|
+
it.delete('required')
|
1100
|
+
it.delete('defaultValue')
|
1101
|
+
it.delete('skipSingleOption')
|
1102
|
+
}
|
1103
|
+
list
|
1104
|
+
end
|
1105
|
+
|
1106
|
+
def find_option_type_list_by_name_or_id(val)
|
1107
|
+
if val.to_s =~ /\A\d{1,}\Z/
|
1108
|
+
return find_option_type_list_by_id(val)
|
1109
|
+
else
|
1110
|
+
return find_option_type_list_by_name(val)
|
535
1111
|
end
|
1112
|
+
end
|
536
1113
|
|
1114
|
+
def find_option_type_list_by_id(id)
|
1115
|
+
begin
|
1116
|
+
json_response = @option_type_lists_interface.get(id.to_i)
|
1117
|
+
return json_response['optionTypeList']
|
1118
|
+
rescue RestClient::Exception => e
|
1119
|
+
if e.response && e.response.code == 404
|
1120
|
+
print_red_alert "Option List not found by id #{id}"
|
1121
|
+
exit 1
|
1122
|
+
else
|
1123
|
+
raise e
|
1124
|
+
end
|
1125
|
+
end
|
1126
|
+
end
|
537
1127
|
|
1128
|
+
def find_option_type_list_by_name(name)
|
1129
|
+
json_results = @option_type_lists_interface.list({name: name.to_s})
|
1130
|
+
if json_results['optionTypeLists'].empty?
|
1131
|
+
print_red_alert "Option List not found by name #{name}"
|
1132
|
+
exit 1
|
1133
|
+
end
|
1134
|
+
option_type_list = json_results['optionTypeLists'][0]
|
1135
|
+
return option_type_list
|
1136
|
+
end
|
1137
|
+
|
1138
|
+
def get_available_option_list_types
|
1139
|
+
[
|
1140
|
+
{'name' => 'Rest', 'value' => 'rest'},
|
1141
|
+
{'name' => 'Manual', 'value' => 'manual'}
|
1142
|
+
]
|
538
1143
|
end
|
1144
|
+
|
1145
|
+
def find_option_list_type(code)
|
1146
|
+
get_available_option_list_types.find {|it| code == it['value'] || code == it['name'] }
|
1147
|
+
end
|
1148
|
+
|
1149
|
+
def new_option_type_list_option_types(list_type='rest')
|
1150
|
+
if list_type.to_s.downcase == 'rest'
|
1151
|
+
[
|
1152
|
+
{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'displayOrder' => 1},
|
1153
|
+
{'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'displayOrder' => 2},
|
1154
|
+
#{'fieldName' => 'type', 'fieldLabel' => 'Type', 'type' => 'select', 'selectOptions' => get_available_option_list_types, 'defaultValue' => 'rest', 'required' => true, 'displayOrder' => 3},
|
1155
|
+
{'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},
|
1156
|
+
{'fieldName' => 'ignoreSSLErrors', 'fieldLabel' => 'Ignore SSL Errors', 'type' => 'checkbox', 'defaultValue' => 'off', 'displayOrder' => 5},
|
1157
|
+
{'fieldName' => 'sourceMethod', 'fieldLabel' => 'Source Method', 'type' => 'select', 'selectOptions' => [{'name' => 'GET', 'value' => 'GET'}, {'name' => 'POST', 'value' => 'POST'}], 'defaultValue' => 'GET', 'required' => true, 'displayOrder' => 6},
|
1158
|
+
{'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},
|
1159
|
+
{'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},
|
1160
|
+
]
|
1161
|
+
elsif list_type.to_s.downcase == 'manual'
|
1162
|
+
[
|
1163
|
+
{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'displayOrder' => 1},
|
1164
|
+
{'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'displayOrder' => 2},
|
1165
|
+
#{'fieldName' => 'type', 'fieldLabel' => 'Type', 'type' => 'select', 'selectOptions' => [{'name' => 'Rest', 'value' => 'rest'}, {'name' => 'Manual', 'value' => 'manual'}], 'defaultValue' => 'rest', 'required' => true, 'displayOrder' => 3},
|
1166
|
+
{'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},
|
1167
|
+
]
|
1168
|
+
else
|
1169
|
+
print_red_alert "Unknown Option List type '#{list_type}'"
|
1170
|
+
exit 1
|
1171
|
+
end
|
1172
|
+
end
|
1173
|
+
|
1174
|
+
def update_option_type_list_option_types(list_type='rest')
|
1175
|
+
list = new_option_type_list_option_types(list_type)
|
1176
|
+
list.each {|it|
|
1177
|
+
it.delete('required')
|
1178
|
+
it.delete('defaultValue')
|
1179
|
+
it.delete('skipSingleOption')
|
1180
|
+
}
|
1181
|
+
list
|
1182
|
+
end
|
1183
|
+
|
1184
|
+
end
|