morpheus-cli 4.2.8 → 4.2.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Dockerfile +1 -1
- data/lib/morpheus/api.rb +1 -1
- data/lib/morpheus/api/activity_interface.rb +9 -0
- data/lib/morpheus/api/api_client.rb +83 -27
- data/lib/morpheus/api/apps_interface.rb +21 -0
- data/lib/morpheus/api/dashboard_interface.rb +5 -21
- data/lib/morpheus/api/instances_interface.rb +3 -10
- data/lib/morpheus/api/invoice_line_items_interface.rb +14 -0
- data/lib/morpheus/api/invoices_interface.rb +7 -12
- data/lib/morpheus/api/library_layouts_interface.rb +8 -0
- data/lib/morpheus/api/ping_interface.rb +20 -0
- data/lib/morpheus/api/projects_interface.rb +33 -0
- data/lib/morpheus/api/setup_interface.rb +19 -36
- data/lib/morpheus/api/user_settings_interface.rb +0 -6
- data/lib/morpheus/api/whoami_interface.rb +4 -8
- data/lib/morpheus/benchmarking.rb +16 -26
- data/lib/morpheus/cli.rb +10 -5
- data/lib/morpheus/cli/access_token_command.rb +5 -8
- data/lib/morpheus/cli/activity_command.rb +146 -0
- data/lib/morpheus/cli/apps.rb +312 -121
- data/lib/morpheus/cli/archives_command.rb +1 -1
- data/lib/morpheus/cli/auth_command.rb +4 -11
- data/lib/morpheus/cli/blueprints_command.rb +196 -137
- data/lib/morpheus/cli/change_password_command.rb +1 -1
- data/lib/morpheus/cli/cli_command.rb +225 -72
- data/lib/morpheus/cli/cli_registry.rb +2 -2
- data/lib/morpheus/cli/cloud_datastores_command.rb +1 -1
- data/lib/morpheus/cli/clouds.rb +5 -20
- data/lib/morpheus/cli/clusters.rb +4 -28
- data/lib/morpheus/cli/commands/standard/alias_command.rb +2 -9
- data/lib/morpheus/cli/commands/standard/benchmark_command.rb +2 -0
- data/lib/morpheus/cli/commands/standard/curl_command.rb +2 -3
- data/lib/morpheus/cli/commands/standard/history_command.rb +3 -6
- data/lib/morpheus/cli/commands/standard/man_command.rb +10 -7
- data/lib/morpheus/cli/commands/standard/ssl_verification_command.rb +10 -9
- data/lib/morpheus/cli/containers_command.rb +3 -3
- data/lib/morpheus/cli/credentials.rb +13 -16
- data/lib/morpheus/cli/error_handler.rb +18 -12
- data/lib/morpheus/cli/errors.rb +45 -0
- data/lib/morpheus/cli/execute_schedules_command.rb +1 -1
- data/lib/morpheus/cli/execution_request_command.rb +4 -4
- data/lib/morpheus/cli/groups.rb +84 -132
- data/lib/morpheus/cli/hosts.rb +6 -16
- data/lib/morpheus/cli/instances.rb +100 -183
- data/lib/morpheus/cli/invoices_command.rb +505 -71
- data/lib/morpheus/cli/library_layouts_command.rb +254 -166
- data/lib/morpheus/cli/library_option_lists_command.rb +0 -87
- data/lib/morpheus/cli/library_option_types_command.rb +0 -96
- data/lib/morpheus/cli/license.rb +3 -0
- data/lib/morpheus/cli/login.rb +17 -37
- data/lib/morpheus/cli/logout.rb +9 -5
- data/lib/morpheus/cli/mixins/accounts_helper.rb +83 -7
- data/lib/morpheus/cli/mixins/operations_helper.rb +41 -0
- data/lib/morpheus/cli/mixins/option_source_helper.rb +255 -0
- data/lib/morpheus/cli/mixins/print_helper.rb +18 -4
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +222 -13
- data/lib/morpheus/cli/mixins/remote_helper.rb +139 -0
- data/lib/morpheus/cli/monitoring_checks_command.rb +11 -3
- data/lib/morpheus/cli/network_groups_command.rb +8 -2
- data/lib/morpheus/cli/option_types.rb +1 -1
- data/lib/morpheus/cli/ping.rb +252 -0
- data/lib/morpheus/cli/price_sets_command.rb +16 -27
- data/lib/morpheus/cli/prices_command.rb +34 -27
- data/lib/morpheus/cli/processes_command.rb +81 -7
- data/lib/morpheus/cli/projects_command.rb +607 -0
- data/lib/morpheus/cli/recent_activity_command.rb +87 -65
- data/lib/morpheus/cli/remote.rb +965 -974
- data/lib/morpheus/cli/reports_command.rb +3 -15
- data/lib/morpheus/cli/roles.rb +8 -31
- data/lib/morpheus/cli/service_plans_command.rb +25 -31
- data/lib/morpheus/cli/setup.rb +392 -0
- data/lib/morpheus/cli/shell.rb +144 -56
- data/lib/morpheus/cli/subnets_command.rb +71 -11
- data/lib/morpheus/cli/tasks.rb +3 -3
- data/lib/morpheus/cli/user_sources_command.rb +4 -4
- data/lib/morpheus/cli/users.rb +135 -109
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/whitelabel_settings_command.rb +7 -7
- data/lib/morpheus/cli/whoami.rb +90 -129
- data/lib/morpheus/cli/wiki_command.rb +2 -14
- data/lib/morpheus/ext/rest_client.rb +36 -0
- data/lib/morpheus/formatters.rb +42 -5
- data/lib/morpheus/rest_client.rb +0 -10
- data/lib/morpheus/terminal.rb +41 -1
- data/lib/morpheus/util.rb +24 -0
- metadata +16 -3
- data/lib/morpheus/cli/command_error.rb +0 -22
@@ -65,7 +65,7 @@ class Morpheus::Cli::ChangePasswordCommand
|
|
65
65
|
raise_command_error "No current appliance, see `remote use`."
|
66
66
|
end
|
67
67
|
if !@current_remote[:username]
|
68
|
-
raise_command_error "You are not currently logged in to #{@current_remote[:name]
|
68
|
+
raise_command_error "You are not currently logged in to #{display_appliance(@current_remote[:name], @current_remote[:url])}"
|
69
69
|
end
|
70
70
|
username = @current_remote[:username]
|
71
71
|
end
|
@@ -97,8 +97,12 @@ module Morpheus
|
|
97
97
|
@no_prompt != true
|
98
98
|
end
|
99
99
|
|
100
|
-
def raise_command_error(msg)
|
101
|
-
raise Morpheus::Cli::CommandError.new(msg)
|
100
|
+
def raise_command_error(msg, args=[], optparse=nil, exit_code=nil)
|
101
|
+
raise Morpheus::Cli::CommandError.new(msg, args, optparse, exit_code)
|
102
|
+
end
|
103
|
+
|
104
|
+
def raise_args_error(msg, args=[], optparse=nil, exit_code=nil)
|
105
|
+
raise Morpheus::Cli::CommandArgumentsError.new(msg, args, optparse, exit_code)
|
102
106
|
end
|
103
107
|
|
104
108
|
# parse_id_list splits returns the given id_list with its values split on a comma
|
@@ -128,6 +132,11 @@ module Morpheus
|
|
128
132
|
raise_command_error "Invalid value for #{option} option"
|
129
133
|
end
|
130
134
|
|
135
|
+
# this returns all the options passed in by -O, parsed all nicely into objects.
|
136
|
+
def parse_passed_options(options)
|
137
|
+
passed_options = options[:options] ? options[:options].reject {|k,v| k.is_a?(Symbol) } : {}
|
138
|
+
return passed_options
|
139
|
+
end
|
131
140
|
# Appends Array of OptionType definitions to an OptionParser instance
|
132
141
|
# This adds an option like --fieldContext.fieldName="VALUE"
|
133
142
|
# @param opts [OptionParser]
|
@@ -216,24 +225,39 @@ module Morpheus
|
|
216
225
|
opts
|
217
226
|
end
|
218
227
|
|
219
|
-
|
220
|
-
build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run, :remote] + includes, excludes)
|
221
|
-
end
|
228
|
+
## the standard options for a command that makes api requests (most of them)
|
222
229
|
|
223
230
|
def build_standard_get_options(opts, options, includes=[], excludes=[])
|
224
|
-
build_common_options(opts, options, [:query, :json, :yaml, :csv, :fields, :dry_run, :remote] + includes, excludes)
|
231
|
+
build_common_options(opts, options, [:query, :json, :yaml, :csv, :fields, :quiet, :dry_run, :remote] + includes, excludes)
|
232
|
+
end
|
233
|
+
|
234
|
+
def build_standard_post_options(opts, options, includes=[], excludes=[])
|
235
|
+
build_common_options(opts, options, [:options, :payload, :json, :quiet, :dry_run, :remote] + includes, excludes)
|
236
|
+
end
|
237
|
+
|
238
|
+
def build_standard_put_options(opts, options, includes=[], excludes=[])
|
239
|
+
build_standard_post_options(opts, options, includes, excludes)
|
240
|
+
end
|
241
|
+
|
242
|
+
def build_standard_delete_options(opts, options, includes=[], excludes=[])
|
243
|
+
build_common_options(opts, options, [:auto_confirm, :query, :json, :quiet, :dry_run, :remote] + includes, excludes)
|
244
|
+
end
|
245
|
+
|
246
|
+
# list is GET that supports phrase,max,offset,sort,direction
|
247
|
+
def build_standard_list_options(opts, options, includes=[], excludes=[])
|
248
|
+
build_standard_get_options(opts, options, [:list] + includes, excludes=[])
|
225
249
|
end
|
226
250
|
|
227
251
|
def build_standard_add_options(opts, options, includes=[], excludes=[])
|
228
|
-
|
252
|
+
build_standard_post_options(opts, options, includes, excludes)
|
229
253
|
end
|
230
254
|
|
231
255
|
def build_standard_update_options(opts, options, includes=[], excludes=[])
|
232
|
-
|
256
|
+
build_standard_put_options(opts, options, includes, excludes)
|
233
257
|
end
|
234
258
|
|
235
259
|
def build_standard_remove_options(opts, options, includes=[], excludes=[])
|
236
|
-
|
260
|
+
build_standard_delete_options(opts, options, includes, excludes)
|
237
261
|
end
|
238
262
|
|
239
263
|
# appends to the passed OptionParser all the generic options
|
@@ -494,12 +518,33 @@ module Morpheus
|
|
494
518
|
opts.on( '-T', '--token TOKEN', "Access token for authentication with --remote. Saved credentials are used by default." ) do |val|
|
495
519
|
options[:remote_token] = val
|
496
520
|
end unless excludes.include?(:remote_token)
|
521
|
+
opts.on( '--token-file FILE', String, "Token File, read a file containing the access token." ) do |val|
|
522
|
+
token_file = File.expand_path(val)
|
523
|
+
if !File.exists?(token_file) || !File.file?(token_file)
|
524
|
+
raise ::OptionParser::InvalidOption.new("File not found: #{token_file}")
|
525
|
+
end
|
526
|
+
options[:remote_token] = File.read(token_file).to_s.split("\n").first.strip
|
527
|
+
end
|
528
|
+
opts.add_hidden_option('--token-file') if opts.is_a?(Morpheus::Cli::OptionParser)
|
497
529
|
opts.on( '-U', '--username USERNAME', "Username for authentication." ) do |val|
|
498
530
|
options[:remote_username] = val
|
499
531
|
end unless excludes.include?(:remote_username)
|
500
|
-
|
501
|
-
|
502
|
-
|
532
|
+
|
533
|
+
|
534
|
+
unless excludes.include?(:remote_password)
|
535
|
+
opts.on( '-P', '--password PASSWORD', "Password for authentication." ) do |val|
|
536
|
+
options[:remote_password] = val
|
537
|
+
end
|
538
|
+
opts.on( '--password-file FILE', String, "Password File, read a file containing the password for authentication." ) do |val|
|
539
|
+
password_file = File.expand_path(val)
|
540
|
+
if !File.exists?(password_file) || !File.file?(password_file)
|
541
|
+
raise ::OptionParser::InvalidOption.new("File not found: #{password_file}")
|
542
|
+
end
|
543
|
+
file_content = File.read(password_file) #.strip
|
544
|
+
options[:remote_password] = File.read(password_file).to_s.split("\n").first
|
545
|
+
end
|
546
|
+
opts.add_hidden_option('--password-file') if opts.is_a?(Morpheus::Cli::OptionParser)
|
547
|
+
end
|
503
548
|
|
504
549
|
# todo: also require this for talking to plain old HTTP
|
505
550
|
opts.on('-I','--insecure', "Allow insecure HTTPS communication. i.e. bad SSL certificate.") do |val|
|
@@ -622,7 +667,7 @@ module Morpheus
|
|
622
667
|
end
|
623
668
|
#opts.add_hidden_option('--all-fields') if opts.is_a?(Morpheus::Cli::OptionParser)
|
624
669
|
opts.on(nil, '--wrap', "Wrap table columns instead hiding them when terminal is not wide enough.") do
|
625
|
-
options[:
|
670
|
+
options[:wrap] = true
|
626
671
|
end
|
627
672
|
when :thin
|
628
673
|
opts.on( '--thin', '--thin', "Format headers and columns with thin borders." ) do |val|
|
@@ -701,7 +746,8 @@ module Morpheus
|
|
701
746
|
|
702
747
|
|
703
748
|
# Benchmark this command?
|
704
|
-
|
749
|
+
# Also useful for seeing exit status for every command.
|
750
|
+
opts.on('-B','--benchmark', "Print benchmark time and exit/error after the command is finished.") do
|
705
751
|
options[:benchmark] = true
|
706
752
|
# this is hacky, but working!
|
707
753
|
# shell handles returning to false
|
@@ -725,6 +771,15 @@ module Morpheus
|
|
725
771
|
# end
|
726
772
|
end
|
727
773
|
|
774
|
+
# A way to ensure debugging is off, it should go back on after the command is complete.
|
775
|
+
opts.on('--no-debug','--no-debug', "Disable debugging.") do
|
776
|
+
options[:debug] = false
|
777
|
+
Morpheus::Logging.set_log_level(Morpheus::Logging::Logger::INFO)
|
778
|
+
::RestClient.log = Morpheus::Logging.debug? ? Morpheus::Logging::DarkPrinter.instance : nil
|
779
|
+
end
|
780
|
+
opts.add_hidden_option('--no-debug') if opts.is_a?(Morpheus::Cli::OptionParser)
|
781
|
+
|
782
|
+
|
728
783
|
opts.on('-h', '--help', "Print this help" ) do
|
729
784
|
puts opts
|
730
785
|
exit # return 0 maybe?
|
@@ -741,6 +796,10 @@ module Morpheus
|
|
741
796
|
self.class.subcommands
|
742
797
|
end
|
743
798
|
|
799
|
+
def visible_subcommands
|
800
|
+
self.class.visible_subcommands
|
801
|
+
end
|
802
|
+
|
744
803
|
def subcommand_aliases
|
745
804
|
self.class.subcommand_aliases
|
746
805
|
end
|
@@ -821,10 +880,8 @@ module Morpheus
|
|
821
880
|
end
|
822
881
|
cmd_method = subcommands[subcommand_name]
|
823
882
|
if !cmd_method
|
824
|
-
|
825
|
-
|
826
|
-
puts_error "'#{subcommand_name}' is not recognized.\n#{full_command_usage}"
|
827
|
-
return 127
|
883
|
+
error_msg = "'#{command_name} #{subcommand_name}' is not a morpheus command.\n#{full_command_usage}"
|
884
|
+
raise CommandNotFoundError.new(error_msg)
|
828
885
|
end
|
829
886
|
self.send(cmd_method, args[1..-1])
|
830
887
|
end
|
@@ -857,96 +914,129 @@ module Morpheus
|
|
857
914
|
return failed_result ? failed_result : cmd_results.last
|
858
915
|
end
|
859
916
|
|
917
|
+
# def connect(options={})
|
918
|
+
# Morpheus::Logging::DarkPrinter.puts "#{command_name} has not defined connect()" if Morpheus::Logging.debug?
|
919
|
+
# end
|
920
|
+
|
860
921
|
# This supports the simple remote option eg. `instances add --remote "qa"`
|
861
922
|
# It will establish a connection to the pre-configured appliance named "qa"
|
862
|
-
#
|
863
|
-
# Otherwise, the current active appliance is used...
|
923
|
+
# By default it will connect to the active (current) remote appliance
|
864
924
|
# This returns a new instance of Morpheus::APIClient (and sets @access_token, and @appliance)
|
865
925
|
# Your command should be ready to make api requests after this.
|
926
|
+
# This will prompt for credentials if none are found, use :skip_login
|
927
|
+
# Credentials will be saved unless --remote-url or --token is being used.
|
866
928
|
def establish_remote_appliance_connection(options)
|
867
929
|
# todo: probably refactor and don't rely on this method to set these instance vars
|
930
|
+
@remote_appliance = nil
|
868
931
|
@appliance_name, @appliance_url, @access_token = nil, nil, nil
|
869
932
|
@api_client = nil
|
870
|
-
|
871
|
-
|
872
|
-
if options[:
|
933
|
+
@do_save_credentials = true
|
934
|
+
# skip saving if --remote-url or --username or --password are passed in
|
935
|
+
if options[:remote_url] || options[:remote_token] || options[:remote_username] || options[:remote_password]
|
936
|
+
@do_save_credentials = false
|
937
|
+
end
|
938
|
+
appliance = nil
|
939
|
+
if options[:remote_url]
|
940
|
+
# --remote-url means use an arbitrary url, do not save any appliance config
|
941
|
+
# appliance = {name:'remote-url', url:options[:remote_url]}
|
942
|
+
appliance = {url:options[:remote_url]}
|
943
|
+
appliance[:temporary] = true
|
944
|
+
#appliance[:status] = "ready" # or "unknown"
|
945
|
+
# appliance[:last_check] = nil
|
946
|
+
elsif options[:remote]
|
947
|
+
# --remote means use the specified remote
|
873
948
|
appliance = ::Morpheus::Cli::Remote.load_remote(options[:remote])
|
874
|
-
if
|
949
|
+
if appliance.nil?
|
875
950
|
if ::Morpheus::Cli::Remote.appliances.empty?
|
876
|
-
raise_command_error "
|
951
|
+
raise_command_error "No remote appliances exist, see the command `remote add`."
|
877
952
|
else
|
878
|
-
raise_command_error "Remote appliance not found by the name '#{options[:remote]}'"
|
953
|
+
raise_command_error "Remote appliance not found by the name '#{options[:remote]}', see `remote list`"
|
879
954
|
end
|
880
955
|
end
|
881
956
|
else
|
957
|
+
# use active remote
|
882
958
|
appliance = ::Morpheus::Cli::Remote.load_active_remote()
|
883
959
|
if !appliance
|
884
960
|
if ::Morpheus::Cli::Remote.appliances.empty?
|
885
|
-
raise_command_error "
|
961
|
+
raise_command_error "No remote appliances exist, see the command `remote add`"
|
886
962
|
else
|
887
|
-
raise_command_error "
|
963
|
+
raise_command_error "#{command_name} requires a remote to be specified, try the option -r [remote] or see the command `remote use`"
|
888
964
|
end
|
889
965
|
end
|
890
966
|
end
|
967
|
+
@remote_appliance = appliance
|
891
968
|
@appliance_name = appliance[:name]
|
892
|
-
@appliance_url = appliance[:
|
893
|
-
|
969
|
+
@appliance_url = appliance[:url] || appliance[:host] # it used to store :host in the YAML
|
970
|
+
# set enable_ssl_verification
|
894
971
|
# instead of toggling this global value
|
895
972
|
# this should just be an attribute of the api client
|
896
973
|
# for now, this fixes the issue where passing --insecure or --remote
|
897
974
|
# would then apply to all subsequent commands...
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
end
|
975
|
+
allow_insecure = false
|
976
|
+
if options[:insecure] || appliance[:insecure] || Morpheus::Cli::Shell.insecure
|
977
|
+
allow_insecure = true
|
978
|
+
end
|
979
|
+
# Morpheus::RestClient.enable_ssl_verification = allow_insecure != true
|
980
|
+
if allow_insecure && Morpheus::RestClient.ssl_verification_enabled?
|
981
|
+
Morpheus::RestClient.enable_ssl_verification = false
|
982
|
+
elsif !allow_insecure && !Morpheus::RestClient.ssl_verification_enabled?
|
983
|
+
Morpheus::RestClient.enable_ssl_verification = true
|
908
984
|
end
|
909
985
|
|
910
|
-
#
|
986
|
+
# always support accepting --username and --password on the command line
|
911
987
|
# it's probably better not to do that tho, just so it stays out of history files
|
912
|
-
|
913
988
|
|
914
989
|
# if !@appliance_name && !@appliance_url
|
915
990
|
# raise_command_error "Please specify a remote appliance with -r or see the command `remote use`"
|
916
991
|
# end
|
917
992
|
|
918
|
-
Morpheus::Logging::DarkPrinter.puts "establishing connection to
|
919
|
-
#puts "#{dark} #=> establishing connection to [#{@appliance_name}] #{@appliance_url}#{reset}\n" if options[:debug]
|
993
|
+
Morpheus::Logging::DarkPrinter.puts "establishing connection to remote #{display_appliance(@appliance_name, @appliance_url)}" if Morpheus::Logging.debug?
|
920
994
|
|
995
|
+
if options[:no_authorization]
|
996
|
+
# maybe handle this here..
|
997
|
+
options[:skip_login] = true
|
998
|
+
options[:skip_verify_access_token] = true
|
999
|
+
end
|
921
1000
|
|
922
1001
|
# ok, get some credentials.
|
923
|
-
#
|
924
|
-
#
|
925
|
-
# passing --
|
1002
|
+
# use saved credentials by default or prompts for username, password.
|
1003
|
+
# passing --remote-url will skip loading saved credentials and prompt for login to use with the url
|
1004
|
+
# passing --token skips login prompting and uses the provided token.
|
1005
|
+
# passing --token or --username will skip saving credentials to appliance config, they are just used for one command
|
1006
|
+
# ideally this should not prompt now and wait until the client is used on a protected endpoint.
|
1007
|
+
# @wallet = nil
|
926
1008
|
if options[:remote_token]
|
927
|
-
@
|
1009
|
+
@wallet = {'access_token' => options[:remote_token]} #'username' => 'anonymous'
|
1010
|
+
elsif options[:remote_url]
|
1011
|
+
credentials = Morpheus::Cli::Credentials.new(@appliance_name, @appliance_url)
|
1012
|
+
unless options[:skip_login]
|
1013
|
+
@wallet = credentials.request_credentials(options, @do_save_credentials)
|
1014
|
+
end
|
928
1015
|
else
|
929
1016
|
credentials = Morpheus::Cli::Credentials.new(@appliance_name, @appliance_url)
|
930
|
-
#
|
931
|
-
|
932
|
-
if options[:remote_token]
|
933
|
-
@wallet = credentials.request_credentials(options, false)
|
934
|
-
elsif options[:remote_url] || options[:remote_username]
|
935
|
-
@wallet = credentials.request_credentials(options, false)
|
936
|
-
else
|
937
|
-
#@wallet = credentials.request_credentials(options)
|
1017
|
+
# use saved credentials unless --username or passed
|
1018
|
+
unless options[:remote_username]
|
938
1019
|
@wallet = credentials.load_saved_credentials()
|
939
1020
|
end
|
940
|
-
|
941
|
-
#
|
942
|
-
#
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
1021
|
+
# using active remote OR --remote flag
|
1022
|
+
# used saved credentials or login
|
1023
|
+
# ideally this sould not prompt now and wait until the client is used on a protected endpoint.
|
1024
|
+
|
1025
|
+
|
1026
|
+
if @wallet.nil? || @wallet['access_token'].nil?
|
1027
|
+
unless options[:skip_login]
|
1028
|
+
@wallet = credentials.request_credentials(options, @do_save_credentials)
|
1029
|
+
end
|
1030
|
+
end
|
1031
|
+
|
1032
|
+
end
|
1033
|
+
@access_token = @wallet ? @wallet['access_token'] : nil
|
1034
|
+
|
1035
|
+
# validate we have a token
|
1036
|
+
# hrm...
|
1037
|
+
unless options[:skip_verify_access_token]
|
1038
|
+
if @access_token.empty?
|
1039
|
+
raise AuthorizationRequiredError.new("Failed to acquire access token for #{display_appliance(@appliance_name, @appliance_url)}. Verify your credentials are correct.")
|
950
1040
|
end
|
951
1041
|
end
|
952
1042
|
|
@@ -956,9 +1046,29 @@ module Morpheus
|
|
956
1046
|
return api_client
|
957
1047
|
end
|
958
1048
|
|
959
|
-
|
960
|
-
|
961
|
-
|
1049
|
+
# verify_args! verifies that the right number of commands were passed
|
1050
|
+
# and raises a command error if not.
|
1051
|
+
# Example: verify_args!(args:args, count:1, optparse:optparse)
|
1052
|
+
# this could go be done in optparse.parse instead perhaps
|
1053
|
+
def verify_args!(opts={})
|
1054
|
+
args = opts[:args] || []
|
1055
|
+
if opts[:count]
|
1056
|
+
if args.count < opts[:count]
|
1057
|
+
raise_args_error("not enough arguments, expected #{opts[:count]} and got #{args.count == 0 ? '0' : args.count.to_s + ': '}#{args.join(', ')}", args, opts[:optparse])
|
1058
|
+
elsif args.count > opts[:count]
|
1059
|
+
raise_args_error("too many arguments, expected #{opts[:count]} and got #{args.count == 0 ? '0' : args.count.to_s + ': '}#{args.join(', ')}", args, opts[:optparse])
|
1060
|
+
end
|
1061
|
+
else
|
1062
|
+
if opts[:min]
|
1063
|
+
if args.count < opts[:min]
|
1064
|
+
raise_args_error("not many arguments, expected #{opts[:min] || '0'}-#{opts[:max] || 'N'} and got #{args.count == 0 ? '0' : args.count.to_s + ': '}#{args.join(', ')}", args, opts[:optparse])
|
1065
|
+
end
|
1066
|
+
end
|
1067
|
+
if opts[:max]
|
1068
|
+
if args.count > opts[:max]
|
1069
|
+
raise_args_error("too many arguments, expected #{opts[:min] || '0'}-#{opts[:max] || 'N'} and got #{args.count == 0 ? '0' : args.count.to_s + ': '}#{args.join(', ')}", args, opts[:optparse])
|
1070
|
+
end
|
1071
|
+
end
|
962
1072
|
end
|
963
1073
|
true
|
964
1074
|
end
|
@@ -1042,9 +1152,22 @@ module Morpheus
|
|
1042
1152
|
payload
|
1043
1153
|
end
|
1044
1154
|
|
1045
|
-
|
1155
|
+
def render_response(json_response, options, object_key=nil, &block)
|
1156
|
+
render_result = render_with_format(json_response, options, object_key)
|
1157
|
+
if render_result
|
1158
|
+
return 0, nil
|
1159
|
+
else
|
1160
|
+
if block_given?
|
1161
|
+
return yield
|
1162
|
+
else
|
1163
|
+
return 0, nil
|
1164
|
+
end
|
1165
|
+
end
|
1166
|
+
end
|
1167
|
+
|
1168
|
+
# basic rendering for options :json, :yml, :csv, :quiet, and :outfile
|
1046
1169
|
# returns the string rendered, or nil if nothing was rendered.
|
1047
|
-
def render_with_format(json_response, options, object_key=nil)
|
1170
|
+
def render_with_format(json_response, options, object_key=nil, &block)
|
1048
1171
|
output = nil
|
1049
1172
|
if options[:json]
|
1050
1173
|
output = as_json(json_response, options, object_key)
|
@@ -1060,7 +1183,7 @@ module Morpheus
|
|
1060
1183
|
elsif options[:quiet]
|
1061
1184
|
# note: returning non nil means the calling function knows to return rght away.. kinda weird..
|
1062
1185
|
# but means we need less if options[:quiet] blocks in every action.
|
1063
|
-
|
1186
|
+
return ""
|
1064
1187
|
end
|
1065
1188
|
if output
|
1066
1189
|
if options[:outfile]
|
@@ -1068,6 +1191,17 @@ module Morpheus
|
|
1068
1191
|
else
|
1069
1192
|
puts output
|
1070
1193
|
end
|
1194
|
+
else
|
1195
|
+
if block_given?
|
1196
|
+
# invoke the user given block to render (print output)
|
1197
|
+
# hope it returned something well formed, there's a parse method for that..
|
1198
|
+
cmd_render_result = yield
|
1199
|
+
# could try to support writing output to options[:outfile] here too..
|
1200
|
+
# output is already printed inside block though
|
1201
|
+
# if cmd_render_result
|
1202
|
+
# return output
|
1203
|
+
# end
|
1204
|
+
end
|
1071
1205
|
end
|
1072
1206
|
return output
|
1073
1207
|
end
|
@@ -1099,6 +1233,14 @@ module Morpheus
|
|
1099
1233
|
!!@hidden_command
|
1100
1234
|
end
|
1101
1235
|
|
1236
|
+
def set_subcommands_hidden(*cmds)
|
1237
|
+
@hidden_subcommands ||= []
|
1238
|
+
cmds.flatten.each do |cmd|
|
1239
|
+
@hidden_subcommands << cmd.to_sym
|
1240
|
+
end
|
1241
|
+
@hidden_subcommands
|
1242
|
+
end
|
1243
|
+
|
1102
1244
|
def command_description
|
1103
1245
|
@command_description
|
1104
1246
|
end
|
@@ -1153,6 +1295,17 @@ module Morpheus
|
|
1153
1295
|
@subcommands ||= {}
|
1154
1296
|
end
|
1155
1297
|
|
1298
|
+
def visible_subcommands
|
1299
|
+
cmds = subcommands.clone
|
1300
|
+
if @hidden_subcommands && !@hidden_subcommands.empty?
|
1301
|
+
@hidden_subcommands.each do |hidden_cmd|
|
1302
|
+
cmds.delete(hidden_cmd.to_s)
|
1303
|
+
cmds.delete(hidden_cmd.to_sym)
|
1304
|
+
end
|
1305
|
+
end
|
1306
|
+
cmds
|
1307
|
+
end
|
1308
|
+
|
1156
1309
|
def has_subcommand?(cmd_name)
|
1157
1310
|
return false if cmd_name.empty?
|
1158
1311
|
@subcommands && @subcommands[cmd_name.to_s]
|