morpheus-cli 3.6.8 → 3.6.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/morpheus/api/account_groups_interface.rb +2 -2
- data/lib/morpheus/api/accounts_interface.rb +4 -7
- data/lib/morpheus/api/api_client.rb +207 -70
- data/lib/morpheus/api/app_templates_interface.rb +7 -28
- data/lib/morpheus/api/apps_interface.rb +14 -21
- data/lib/morpheus/api/archive_buckets_interface.rb +2 -2
- data/lib/morpheus/api/archive_files_interface.rb +6 -6
- data/lib/morpheus/api/auth_interface.rb +14 -1
- data/lib/morpheus/api/blueprints_interface.rb +9 -16
- data/lib/morpheus/api/cloud_datastores_interface.rb +1 -1
- data/lib/morpheus/api/cloud_policies_interface.rb +1 -1
- data/lib/morpheus/api/clouds_interface.rb +18 -21
- data/lib/morpheus/api/cypher_interface.rb +19 -28
- data/lib/morpheus/api/file_copy_request_interface.rb +1 -1
- data/lib/morpheus/api/group_policies_interface.rb +1 -1
- data/lib/morpheus/api/groups_interface.rb +4 -4
- data/lib/morpheus/api/image_builder_boot_scripts_interface.rb +1 -1
- data/lib/morpheus/api/image_builder_image_builds_interface.rb +2 -2
- data/lib/morpheus/api/image_builder_preseed_scripts_interface.rb +1 -1
- data/lib/morpheus/api/instances_interface.rb +17 -23
- data/lib/morpheus/api/logs_interface.rb +7 -10
- data/lib/morpheus/api/network_domains_interface.rb +1 -1
- data/lib/morpheus/api/network_groups_interface.rb +1 -1
- data/lib/morpheus/api/network_pool_servers_interface.rb +1 -1
- data/lib/morpheus/api/network_pools_interface.rb +1 -1
- data/lib/morpheus/api/network_proxies_interface.rb +1 -1
- data/lib/morpheus/api/network_services_interface.rb +1 -1
- data/lib/morpheus/api/networks_interface.rb +1 -1
- data/lib/morpheus/api/old_cypher_interface.rb +55 -0
- data/lib/morpheus/api/packages_interface.rb +1 -1
- data/lib/morpheus/api/policies_interface.rb +1 -1
- data/lib/morpheus/api/setup_interface.rb +1 -1
- data/lib/morpheus/api/storage_providers_interface.rb +1 -1
- data/lib/morpheus/api/whoami_interface.rb +1 -1
- data/lib/morpheus/benchmarking.rb +277 -0
- data/lib/morpheus/cli.rb +6 -22
- data/lib/morpheus/cli/access_token_command.rb +172 -0
- data/lib/morpheus/cli/accounts.rb +5 -0
- data/lib/morpheus/cli/apps.rb +93 -37
- data/lib/morpheus/cli/archives_command.rb +0 -2
- data/lib/morpheus/cli/auth_command.rb +112 -0
- data/lib/morpheus/cli/blueprints_command.rb +50 -13
- data/lib/morpheus/cli/change_password_command.rb +148 -0
- data/lib/morpheus/cli/cli_command.rb +173 -49
- data/lib/morpheus/cli/clouds.rb +15 -5
- data/lib/morpheus/cli/command_error.rb +7 -1
- data/lib/morpheus/cli/{alias_command.rb → commands/standard/alias_command.rb} +79 -51
- data/lib/morpheus/cli/commands/standard/benchmark_command.rb +399 -0
- data/lib/morpheus/cli/commands/standard/coloring_command.rb +60 -0
- data/lib/morpheus/cli/{curl_command.rb → commands/standard/curl_command.rb} +0 -7
- data/lib/morpheus/cli/commands/standard/debug_command.rb +61 -0
- data/lib/morpheus/cli/{echo_command.rb → commands/standard/echo_command.rb} +1 -1
- data/lib/morpheus/cli/{edit_profile_command.rb → commands/standard/edit_profile_command.rb} +0 -0
- data/lib/morpheus/cli/{edit_rc_command.rb → commands/standard/edit_rc_command.rb} +0 -0
- data/lib/morpheus/cli/commands/standard/get_prompt_command.rb +39 -0
- data/lib/morpheus/cli/commands/standard/history_command.rb +76 -0
- data/lib/morpheus/cli/{log_level_command.rb → commands/standard/log_level_command.rb} +1 -1
- data/lib/morpheus/cli/{man_command.rb → commands/standard/man_command.rb} +2 -2
- data/lib/morpheus/cli/commands/standard/rm_command.rb +14 -0
- data/lib/morpheus/cli/commands/standard/set_prompt_command.rb +54 -0
- data/lib/morpheus/cli/{sleep_command.rb → commands/standard/sleep_command.rb} +0 -0
- data/lib/morpheus/cli/{source_command.rb → commands/standard/source_command.rb} +0 -0
- data/lib/morpheus/cli/{ssl_verification_command.rb → commands/standard/ssl_verification_command.rb} +1 -1
- data/lib/morpheus/cli/commands/standard/tee_command.rb +14 -0
- data/lib/morpheus/cli/{version_command.rb → commands/standard/version_command.rb} +0 -0
- data/lib/morpheus/cli/credentials.rb +276 -87
- data/lib/morpheus/cli/cypher_command.rb +333 -214
- data/lib/morpheus/cli/error_handler.rb +12 -2
- data/lib/morpheus/cli/groups.rb +44 -20
- data/lib/morpheus/cli/hosts.rb +39 -16
- data/lib/morpheus/cli/instances.rb +114 -62
- data/lib/morpheus/cli/login.rb +74 -21
- data/lib/morpheus/cli/logout.rb +3 -4
- data/lib/morpheus/cli/mixins/accounts_helper.rb +50 -18
- data/lib/morpheus/cli/mixins/print_helper.rb +207 -42
- data/lib/morpheus/cli/old_cypher_command.rb +414 -0
- data/lib/morpheus/cli/option_parser.rb +6 -1
- data/lib/morpheus/cli/processes_command.rb +3 -0
- data/lib/morpheus/cli/remote.rb +11 -17
- data/lib/morpheus/cli/roles.rb +17 -17
- data/lib/morpheus/cli/security_groups.rb +47 -17
- data/lib/morpheus/cli/shell.rb +139 -79
- data/lib/morpheus/cli/tenants_command.rb +353 -0
- data/lib/morpheus/cli/users.rb +26 -18
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/whoami.rb +14 -10
- data/lib/morpheus/formatters.rb +4 -4
- data/lib/morpheus/logging.rb +16 -8
- data/lib/morpheus/terminal.rb +63 -34
- metadata +28 -15
- data/lib/morpheus/cli/coloring_command.rb +0 -45
- data/lib/morpheus/cli/set_prompt_command.rb +0 -51
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
require 'optparse'
|
|
2
|
+
require 'morpheus/cli/cli_command'
|
|
3
|
+
require 'json'
|
|
4
|
+
|
|
5
|
+
# This is for use in dotfile scripts
|
|
6
|
+
# It allows you to turn colors on or off globally
|
|
7
|
+
class Morpheus::Cli::ColoringCommand
|
|
8
|
+
include Morpheus::Cli::CliCommand
|
|
9
|
+
set_command_name :coloring
|
|
10
|
+
set_command_hidden
|
|
11
|
+
|
|
12
|
+
def handle(args)
|
|
13
|
+
append_newline = true
|
|
14
|
+
options = {}
|
|
15
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
|
16
|
+
opts.banner = "Usage: morpheus #{command_name} [on|off]"
|
|
17
|
+
#build_common_options(opts, options, [])
|
|
18
|
+
opts.on('-h', '--help', "Print this help" ) do
|
|
19
|
+
puts opts
|
|
20
|
+
exit
|
|
21
|
+
end
|
|
22
|
+
opts.footer = "Enable [on] or Disable [off] ANSI Colors for all output.\n" +
|
|
23
|
+
"Use [on?] or [off?] to print the current value and exit accordingly." + "\n" +
|
|
24
|
+
"Pass no arguments to just print the current value."
|
|
25
|
+
end
|
|
26
|
+
optparse.parse!(args)
|
|
27
|
+
if args.count > 1
|
|
28
|
+
raise_command_error "wrong number of arguments, expected 0-1 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
exit_code = 0
|
|
32
|
+
|
|
33
|
+
if args.count == 0
|
|
34
|
+
# just print
|
|
35
|
+
else
|
|
36
|
+
subcmd = args[0].to_s.strip
|
|
37
|
+
if subcmd == "on"
|
|
38
|
+
Term::ANSIColor::coloring = true
|
|
39
|
+
elsif subcmd == "off"
|
|
40
|
+
Term::ANSIColor::coloring = false
|
|
41
|
+
elsif subcmd == "on?"
|
|
42
|
+
exit_code = Term::ANSIColor::coloring? ? 0 : 1
|
|
43
|
+
elsif subcmd == "off?"
|
|
44
|
+
exit_code = Term::ANSIColor::coloring? ? 1 : 0
|
|
45
|
+
else
|
|
46
|
+
puts optparse
|
|
47
|
+
return 127
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
unless options[:quiet]
|
|
51
|
+
if Term::ANSIColor::coloring?
|
|
52
|
+
puts "#{cyan}coloring: #{bold}#{green}on#{reset}"
|
|
53
|
+
else
|
|
54
|
+
puts "coloring: off"
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
return exit_code
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
end
|
|
@@ -53,13 +53,6 @@ EOT
|
|
|
53
53
|
curl_args.unshift "--inescure"
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
-
# @access_token = Morpheus::Cli::Credentials.new(@appliance_name, @appliance_url).load_saved_credentials()
|
|
57
|
-
# if !@access_token
|
|
58
|
-
# print yellow,"You are not currently logged in to #{display_appliance(@appliance_name, @appliance_url)}",reset,"\n"
|
|
59
|
-
# print yellow,"Use the 'login' command.",reset,"\n"
|
|
60
|
-
# return 0
|
|
61
|
-
# end
|
|
62
|
-
|
|
63
56
|
if !@appliance_url
|
|
64
57
|
raise "Unable to determine remote appliance url"
|
|
65
58
|
print "#{red}Unable to determine remote appliance url.#{reset}\n"
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
require 'morpheus/cli/cli_command'
|
|
2
|
+
require 'morpheus/logging'
|
|
3
|
+
|
|
4
|
+
# This is for use in dotfile scripts
|
|
5
|
+
# It allows you to turn colors on or off globally
|
|
6
|
+
class Morpheus::Cli::DebugCommand
|
|
7
|
+
include Morpheus::Cli::CliCommand
|
|
8
|
+
set_command_name :debug
|
|
9
|
+
set_command_hidden
|
|
10
|
+
|
|
11
|
+
def handle(args)
|
|
12
|
+
append_newline = true
|
|
13
|
+
options = {}
|
|
14
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
|
15
|
+
opts.banner = "Usage: morpheus #{command_name} [on|off]"
|
|
16
|
+
#build_common_options(opts, options, [])
|
|
17
|
+
opts.on('-h', '--help', "Print this help" ) do
|
|
18
|
+
puts opts
|
|
19
|
+
exit
|
|
20
|
+
end
|
|
21
|
+
opts.footer = "Enable [on] or Disable [off] debugging for all output.\n" +
|
|
22
|
+
"Use [on?] or [off?] to print the current value and exit accordingly." + "\n" +
|
|
23
|
+
"Pass no arguments to just print the current value."
|
|
24
|
+
end
|
|
25
|
+
optparse.parse!(args)
|
|
26
|
+
if args.count > 1
|
|
27
|
+
raise_command_error "wrong number of arguments, expected 0-1 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
exit_code = 0
|
|
31
|
+
|
|
32
|
+
if args.count == 0
|
|
33
|
+
# just print
|
|
34
|
+
else
|
|
35
|
+
subcmd = args[0].to_s.strip
|
|
36
|
+
if subcmd == "on"
|
|
37
|
+
Morpheus::Logging.set_log_level(Morpheus::Logging::Logger::DEBUG)
|
|
38
|
+
::RestClient.log = Morpheus::Logging.debug? ? Morpheus::Logging::DarkPrinter.instance : nil
|
|
39
|
+
elsif subcmd == "off"
|
|
40
|
+
Morpheus::Logging.set_log_level(Morpheus::Logging::Logger::INFO)
|
|
41
|
+
::RestClient.log = Morpheus::Logging.debug? ? Morpheus::Logging::DarkPrinter.instance : nil
|
|
42
|
+
elsif subcmd == "on?"
|
|
43
|
+
exit_code = Morpheus::Logging.debug? ? 0 : 1
|
|
44
|
+
elsif subcmd == "off?"
|
|
45
|
+
exit_code = Morpheus::Logging.debug? ? 1 : 0
|
|
46
|
+
else
|
|
47
|
+
puts optparse
|
|
48
|
+
return 127
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
unless options[:quiet]
|
|
52
|
+
if Morpheus::Logging.debug?
|
|
53
|
+
puts "#{cyan}debug: #{green}on#{reset}"
|
|
54
|
+
else
|
|
55
|
+
puts "#{cyan}debug: #{dark}off#{reset}"
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
return exit_code
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
end
|
|
@@ -23,7 +23,7 @@ class Morpheus::Cli::Echo
|
|
|
23
23
|
var_map.merge!(DEFAULT_VARIABLE_MAP)
|
|
24
24
|
appliance = ::Morpheus::Cli::Remote.load_active_remote()
|
|
25
25
|
if appliance
|
|
26
|
-
var_map.merge!({'%remote' => appliance[:name], '%remote_url' => appliance[:host].to_s, '%username' => appliance[:username].to_s})
|
|
26
|
+
var_map.merge!({'%remote' => appliance[:name], '%remote_url' => (appliance[:host].to_s || appliance[:url].to_s), '%username' => appliance[:username].to_s})
|
|
27
27
|
else
|
|
28
28
|
var_map.merge!({'%remote' => '', '%remote_url' => '', '%username' => ''})
|
|
29
29
|
end
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
require 'optparse'
|
|
2
|
+
require 'json'
|
|
3
|
+
require 'morpheus/logging'
|
|
4
|
+
require 'morpheus/cli/cli_command'
|
|
5
|
+
|
|
6
|
+
class Morpheus::Cli::GetPromptCommand
|
|
7
|
+
include Morpheus::Cli::CliCommand
|
|
8
|
+
set_command_name :'get-prompt'
|
|
9
|
+
set_command_hidden
|
|
10
|
+
|
|
11
|
+
def handle(args)
|
|
12
|
+
use_echo = false
|
|
13
|
+
options = {}
|
|
14
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
|
15
|
+
opts.banner = "Usage: morpheus #{command_name}"
|
|
16
|
+
build_common_options(opts, options, [])
|
|
17
|
+
opts.on('-e', '--echo', "Use echo to display the prompt, displaying ansi colors and variables." ) do
|
|
18
|
+
use_echo = true
|
|
19
|
+
end
|
|
20
|
+
opts.footer = <<-EOT
|
|
21
|
+
Display the current morpheus shell prompt value.
|
|
22
|
+
This value can be set using `set-prompt [shell-prompt]`.
|
|
23
|
+
EOT
|
|
24
|
+
end
|
|
25
|
+
optparse.parse!(args)
|
|
26
|
+
if args.count != 0
|
|
27
|
+
print_error Morpheus::Terminal.angry_prompt
|
|
28
|
+
puts_error "wrong number of arguments, expected 0 and got (#{args.count}) #{args.inspect}\n#{optparse}"
|
|
29
|
+
return 1
|
|
30
|
+
end
|
|
31
|
+
if use_echo
|
|
32
|
+
my_terminal.execute("echo #{my_terminal.prompt}")
|
|
33
|
+
else
|
|
34
|
+
puts self.my_terminal.prompt
|
|
35
|
+
end
|
|
36
|
+
return 0
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
require 'optparse'
|
|
2
|
+
require 'json'
|
|
3
|
+
require 'morpheus/logging'
|
|
4
|
+
require 'morpheus/cli/cli_command'
|
|
5
|
+
|
|
6
|
+
class Morpheus::Cli::HistoryCommand
|
|
7
|
+
include Morpheus::Cli::CliCommand
|
|
8
|
+
set_command_name :'history'
|
|
9
|
+
set_command_hidden
|
|
10
|
+
|
|
11
|
+
# todo: support all the other :list options too, not just max
|
|
12
|
+
# AND start logging every terminal command, not just shell...
|
|
13
|
+
def handle(args)
|
|
14
|
+
options = {}
|
|
15
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
|
16
|
+
opts.banner = "Usage: morpheus #{command_name}"
|
|
17
|
+
# opts.on( '-m', '--max MAX', "Max Results" ) do |max|
|
|
18
|
+
# options[:max] = max.to_i
|
|
19
|
+
# end
|
|
20
|
+
# opts.on( '-o', '--offset OFFSET', "Offset Results" ) do |offset|
|
|
21
|
+
# options[:offset] = offset.to_i.abs
|
|
22
|
+
# end
|
|
23
|
+
# opts.on( '-s', '--search PHRASE', "Search Phrase" ) do |phrase|
|
|
24
|
+
# options[:phrase] = phrase
|
|
25
|
+
# end
|
|
26
|
+
# opts.on( '-S', '--sort ORDER', "Sort Order" ) do |v|
|
|
27
|
+
# options[:sort] = v
|
|
28
|
+
# end
|
|
29
|
+
# opts.on( '-D', '--desc', "Reverse Sort Order" ) do |v|
|
|
30
|
+
# options[:direction] = "desc"
|
|
31
|
+
# end
|
|
32
|
+
opts.on( '-n', '--max-commands MAX', "Max Results. Default is 25" ) do |val|
|
|
33
|
+
options[:max] = val
|
|
34
|
+
end
|
|
35
|
+
opts.add_hidden_option('-n')
|
|
36
|
+
opts.on( nil, '--flush', "Flush history, purges entire shell history file." ) do |val|
|
|
37
|
+
options[:do_flush] = true
|
|
38
|
+
end
|
|
39
|
+
build_common_options(opts, options, [:list, :auto_confirm])
|
|
40
|
+
opts.footer = <<-EOT
|
|
41
|
+
Print command history.
|
|
42
|
+
The --flush option can be used to purge the history.
|
|
43
|
+
|
|
44
|
+
Examples:
|
|
45
|
+
history
|
|
46
|
+
history -m 100
|
|
47
|
+
history --flush
|
|
48
|
+
|
|
49
|
+
EOT
|
|
50
|
+
end
|
|
51
|
+
raw_cmd = "#{command_name} #{args.join(' ')}"
|
|
52
|
+
optparse.parse!(args)
|
|
53
|
+
if args.count != 0
|
|
54
|
+
print_error Morpheus::Terminal.angry_prompt
|
|
55
|
+
puts_error "wrong number of arguments, expected 0 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
|
|
56
|
+
return 1
|
|
57
|
+
end
|
|
58
|
+
if options[:do_flush]
|
|
59
|
+
unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to flush your command history?")
|
|
60
|
+
return 9, "aborted command"
|
|
61
|
+
end
|
|
62
|
+
Morpheus::Cli::Shell.instance.flush_history
|
|
63
|
+
return 0
|
|
64
|
+
else
|
|
65
|
+
max_commands = options[:max] || 25
|
|
66
|
+
Morpheus::Cli::Shell.instance.print_history(max_commands)
|
|
67
|
+
last_cmd = Morpheus::Cli::Shell.instance.last_command
|
|
68
|
+
# log history, but not consecutive log entries
|
|
69
|
+
if last_cmd.nil? || last_cmd[:command] != raw_cmd
|
|
70
|
+
Morpheus::Cli::Shell.instance.log_history_command(raw_cmd)
|
|
71
|
+
end
|
|
72
|
+
return 0
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
end
|
|
@@ -13,7 +13,7 @@ class Morpheus::Cli::LogLevelCommand
|
|
|
13
13
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
|
14
14
|
opts.banner = "Usage: morpheus #{command_name} [debug|info|0|1]"
|
|
15
15
|
#build_common_options(opts, options, [])
|
|
16
|
-
opts.on('-h', '--help', "
|
|
16
|
+
opts.on('-h', '--help', "Print this help" ) do
|
|
17
17
|
puts opts
|
|
18
18
|
exit
|
|
19
19
|
end
|
|
@@ -41,7 +41,7 @@ class Morpheus::Cli::ManCommand
|
|
|
41
41
|
Morpheus::Logging.set_log_level(Morpheus::Logging::Logger::DEBUG)
|
|
42
42
|
::RestClient.log = Morpheus::Logging.debug? ? Morpheus::Logging::DarkPrinter.instance : nil
|
|
43
43
|
end
|
|
44
|
-
opts.on('-h', '--help', "
|
|
44
|
+
opts.on('-h', '--help', "Print this help" ) do
|
|
45
45
|
puts opts
|
|
46
46
|
exit
|
|
47
47
|
end
|
|
@@ -184,7 +184,7 @@ EOT
|
|
|
184
184
|
--noprofile Do not read and execute the personal initialization script .morpheus_profile
|
|
185
185
|
-C, --nocolor Disable ANSI coloring
|
|
186
186
|
-V, --debug Print extra output for debugging.
|
|
187
|
-
-h, --help
|
|
187
|
+
-h, --help Print this help
|
|
188
188
|
|
|
189
189
|
## COMMON OPTIONS
|
|
190
190
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require 'morpheus/cli/cli_command'
|
|
2
|
+
|
|
3
|
+
# This is for deleting files and directories!
|
|
4
|
+
class Morpheus::Cli::RemoveFileCommand
|
|
5
|
+
include Morpheus::Cli::CliCommand
|
|
6
|
+
set_command_name :rm
|
|
7
|
+
set_command_hidden
|
|
8
|
+
|
|
9
|
+
def handle(args)
|
|
10
|
+
print_red_alert "#{command_name} is not yet supported"
|
|
11
|
+
return -1
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require 'optparse'
|
|
2
|
+
require 'json'
|
|
3
|
+
require 'morpheus/logging'
|
|
4
|
+
require 'morpheus/cli/cli_command'
|
|
5
|
+
|
|
6
|
+
class Morpheus::Cli::SetPromptCommand
|
|
7
|
+
include Morpheus::Cli::CliCommand
|
|
8
|
+
set_command_name :'set-prompt'
|
|
9
|
+
set_command_hidden
|
|
10
|
+
|
|
11
|
+
def handle(args)
|
|
12
|
+
options = {}
|
|
13
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
|
14
|
+
opts.banner = "Usage: morpheus #{command_name} [prompt]"
|
|
15
|
+
opts.on('-h', '--help', "Print this help" ) do
|
|
16
|
+
puts opts
|
|
17
|
+
exit
|
|
18
|
+
end
|
|
19
|
+
variable_map = Morpheus::Cli::Echo.variable_map
|
|
20
|
+
formatted_variable_map = " " + variable_map.keys.join(' ')
|
|
21
|
+
opts.footer = <<-EOT
|
|
22
|
+
Customize your morpheus shell prompt.
|
|
23
|
+
|
|
24
|
+
[prompt] is required. This is the string the terminal prints when you interact with it.
|
|
25
|
+
|
|
26
|
+
Examples:
|
|
27
|
+
set-prompt "morpheus $ "
|
|
28
|
+
set-prompt "%cyanmorpheus> "
|
|
29
|
+
set-prompt "[%magenta%remote%reset] %cyan%username> "
|
|
30
|
+
set-prompt "%green%username%reset@%remote morph %magenta> %reset"
|
|
31
|
+
set-prompt "%cyan%username%reset@%magenta%remote %cyanmorpheus> %reset"
|
|
32
|
+
|
|
33
|
+
The available variables are:
|
|
34
|
+
#{formatted_variable_map}
|
|
35
|
+
|
|
36
|
+
The default prompt is: "%cyanmorpheus> %reset"
|
|
37
|
+
The value may also be set through the enviroment variable MORPHEUS_PS1.
|
|
38
|
+
EOT
|
|
39
|
+
end
|
|
40
|
+
optparse.parse!(args)
|
|
41
|
+
if args.count != 1
|
|
42
|
+
print_error Morpheus::Terminal.angry_prompt
|
|
43
|
+
puts_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args.inspect}\n#{optparse}"
|
|
44
|
+
return 1
|
|
45
|
+
end
|
|
46
|
+
# do it
|
|
47
|
+
self.my_terminal.prompt = args[0]
|
|
48
|
+
# Morpheus::Terminal.instance.prompt = args[0]
|
|
49
|
+
Morpheus::Cli::Shell.instance.recalculate_prompt()
|
|
50
|
+
Morpheus::Cli::Echo.recalculate_variable_map()
|
|
51
|
+
return 0
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
end
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require 'morpheus/cli/cli_command'
|
|
2
|
+
|
|
3
|
+
# This is for writing STDIN to files(s)
|
|
4
|
+
class Morpheus::Cli::TeeCommand
|
|
5
|
+
include Morpheus::Cli::CliCommand
|
|
6
|
+
set_command_name :tee
|
|
7
|
+
set_command_hidden
|
|
8
|
+
|
|
9
|
+
def handle(args)
|
|
10
|
+
print_red_alert "#{command_name} is not yet supported"
|
|
11
|
+
return -1
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
end
|
|
File without changes
|
|
@@ -18,112 +18,183 @@ module Morpheus
|
|
|
18
18
|
@appliance_url = appliance_url
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
# request_credentials will fetch a credentials wallet (access_token, refresh_token, etc)
|
|
22
|
+
# By default this uses the saved credentials for the current appliance.
|
|
23
|
+
# If not logged in, it will prompt for username and password to
|
|
24
|
+
# authenticate with the /oauth/token API to receive an access_token.
|
|
25
|
+
# If :username and :password are passed, then
|
|
26
|
+
# Pass :remote_token to skip prompting and the auth api request.
|
|
27
|
+
# @param options - Hash of optional settings.
|
|
28
|
+
# :username - Username for prompt.
|
|
29
|
+
# :password - Password for prompt.
|
|
30
|
+
# :remote_url - Use this url instead of the one from the current appliance. Credentials will not be saved.
|
|
31
|
+
# :remote_token - Use this access_token, skip prompting and API request.
|
|
32
|
+
# :remote_username - Username for authentication with --remote, skips saving credentials
|
|
33
|
+
# :remote_password - Password for authentication with --remote, skips saving credentials
|
|
34
|
+
# :test_only - Test only. Saved credentials will not be updated.
|
|
35
|
+
# @return Hash wallet like {"access_token":"ec68be138765...", "refresh_token":"ec68be138765..."}
|
|
36
|
+
# or nil if unable to find credentials.
|
|
37
|
+
def request_credentials(options = {}, do_save=true)
|
|
38
|
+
#puts "request_credentials(#{options})"
|
|
23
39
|
username = nil
|
|
24
40
|
password = nil
|
|
25
|
-
|
|
26
|
-
|
|
41
|
+
wallet = nil
|
|
42
|
+
|
|
27
43
|
|
|
28
|
-
|
|
44
|
+
|
|
45
|
+
if options[:remote_token]
|
|
46
|
+
# user passed in a token to login with.
|
|
47
|
+
# this should get token info from /oauth/token
|
|
48
|
+
# OR whoami should return other wallet info like access token or maybe just the expiration date
|
|
49
|
+
# for now, it just stores the access token without other wallet info
|
|
29
50
|
begin
|
|
30
|
-
whoami_interface = Morpheus::WhoamiInterface.new(
|
|
51
|
+
whoami_interface = Morpheus::WhoamiInterface.new(options[:remote_token], nil, nil, @appliance_url)
|
|
52
|
+
if options[:dry_run]
|
|
53
|
+
print_dry_run whoami_interface.dry.get()
|
|
54
|
+
return nil
|
|
55
|
+
end
|
|
31
56
|
whoami_response = whoami_interface.get()
|
|
32
|
-
if
|
|
57
|
+
if options[:json]
|
|
33
58
|
print JSON.pretty_generate(whoami_response)
|
|
34
59
|
print reset, "\n"
|
|
35
60
|
end
|
|
36
|
-
|
|
61
|
+
# store mock /oauth/token auth_interface.login() result
|
|
62
|
+
json_response = {'access_token' => options[:remote_token], 'token_type' => 'bearer'}
|
|
37
63
|
username = whoami_response['user']['username']
|
|
38
|
-
|
|
39
|
-
|
|
64
|
+
login_date = Time.now
|
|
65
|
+
expire_date = nil
|
|
66
|
+
if json_response['expires_in']
|
|
67
|
+
expire_date = login_date.to_i + json_response['expires_in'].to_i
|
|
40
68
|
end
|
|
69
|
+
wallet = {
|
|
70
|
+
'username' => username,
|
|
71
|
+
'login_date' => login_date.to_i,
|
|
72
|
+
'expire_date' => expire_date ? expire_date.to_i : nil,
|
|
73
|
+
'access_token' => json_response['access_token'],
|
|
74
|
+
'refresh_token' => json_response['refresh_token'],
|
|
75
|
+
'token_type' => json_response['token_type']
|
|
76
|
+
}
|
|
41
77
|
rescue ::RestClient::Exception => e
|
|
42
78
|
#raise e
|
|
43
79
|
print_red_alert "Token not valid."
|
|
44
|
-
if
|
|
45
|
-
print_rest_exception(e,
|
|
80
|
+
if options[:debug] || options[:debug]
|
|
81
|
+
print_rest_exception(e, options)
|
|
46
82
|
end
|
|
47
|
-
|
|
83
|
+
wallet = nil
|
|
48
84
|
end
|
|
49
85
|
else
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
86
|
+
|
|
87
|
+
# ok prompt for creds..
|
|
88
|
+
username = options['username'] || options[:username] || nil
|
|
89
|
+
password = options['password'] || options[:password] || nil
|
|
90
|
+
|
|
91
|
+
if options[:remote_username]
|
|
92
|
+
username = options[:remote_username]
|
|
93
|
+
password = options[:remote_password]
|
|
94
|
+
if do_save == true
|
|
95
|
+
do_save = (options[:remote_url] ? false : true)
|
|
96
|
+
end
|
|
55
97
|
else
|
|
56
|
-
|
|
98
|
+
# maybe just if check if options[:test_only] != true
|
|
99
|
+
# if do_save == true
|
|
100
|
+
# wallet = load_saved_credentials
|
|
101
|
+
# end
|
|
57
102
|
end
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
103
|
+
|
|
104
|
+
if wallet.nil?
|
|
105
|
+
unless options[:quiet] || options[:no_prompt]
|
|
106
|
+
# if username.empty? || password.empty?
|
|
107
|
+
if options[:test_only]
|
|
108
|
+
print "Test Morpheus Credentials for #{display_appliance(@appliance_name, @appliance_url)}\n",reset
|
|
109
|
+
else
|
|
110
|
+
print "Enter Morpheus Credentials for #{display_appliance(@appliance_name, @appliance_url)}\n",reset
|
|
111
|
+
end
|
|
112
|
+
# end
|
|
113
|
+
if username.empty?
|
|
114
|
+
print "Username: #{required_blue_prompt} "
|
|
115
|
+
username = $stdin.gets.chomp!
|
|
116
|
+
else
|
|
117
|
+
print "Username: #{required_blue_prompt} #{username}\n"
|
|
118
|
+
end
|
|
119
|
+
if password.empty?
|
|
120
|
+
print "Password: #{required_blue_prompt} "
|
|
121
|
+
# wtf is this STDIN and $stdin and not my_terminal.stdin ?
|
|
122
|
+
password = STDIN.noecho(&:gets).chomp!
|
|
123
|
+
print "\n"
|
|
124
|
+
else
|
|
125
|
+
print "Password: #{required_blue_prompt} \n"
|
|
126
|
+
end
|
|
77
127
|
end
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
return nil
|
|
82
|
-
end
|
|
83
|
-
begin
|
|
84
|
-
auth_interface = Morpheus::AuthInterface.new(@appliance_url)
|
|
85
|
-
json_response = auth_interface.login(username, password)
|
|
86
|
-
if opts[:json]
|
|
87
|
-
print JSON.pretty_generate(json_response)
|
|
88
|
-
print reset, "\n"
|
|
128
|
+
if username.empty? || password.empty?
|
|
129
|
+
print_red_alert "Username and password are required to login."
|
|
130
|
+
return nil
|
|
89
131
|
end
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
132
|
+
begin
|
|
133
|
+
auth_interface = Morpheus::AuthInterface.new(@appliance_url)
|
|
134
|
+
auth_interface.setopts(options)
|
|
135
|
+
if options[:dry_run]
|
|
136
|
+
print_dry_run auth_interface.dry.login(username, password)
|
|
137
|
+
return nil
|
|
94
138
|
end
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
print_red_alert "Credentials not verified."
|
|
98
|
-
# return nil
|
|
99
|
-
end
|
|
100
|
-
rescue ::RestClient::Exception => e
|
|
101
|
-
#raise e
|
|
102
|
-
if (e.response && e.response.code == 400)
|
|
103
|
-
json_response = JSON.parse(e.response.to_s)
|
|
104
|
-
error_msg = json_response['error_description'] || "Credentials not verified."
|
|
105
|
-
print_red_alert error_msg
|
|
106
|
-
if opts[:json]
|
|
107
|
-
json_response = JSON.parse(e.response.to_s)
|
|
139
|
+
json_response = auth_interface.login(username, password)
|
|
140
|
+
if options[:json]
|
|
108
141
|
print JSON.pretty_generate(json_response)
|
|
109
142
|
print reset, "\n"
|
|
110
143
|
end
|
|
111
|
-
|
|
112
|
-
|
|
144
|
+
#wallet = json_response
|
|
145
|
+
login_date = Time.now
|
|
146
|
+
expire_date = nil
|
|
147
|
+
if json_response['expires_in']
|
|
148
|
+
expire_date = login_date.to_i + json_response['expires_in'].to_i
|
|
149
|
+
end
|
|
150
|
+
wallet = {
|
|
151
|
+
'username' => username,
|
|
152
|
+
'login_date' => login_date.to_i,
|
|
153
|
+
'expire_date' => expire_date ? expire_date.to_i : nil,
|
|
154
|
+
'access_token' => json_response['access_token'],
|
|
155
|
+
'refresh_token' => json_response['refresh_token'],
|
|
156
|
+
'token_type' => json_response['token_type']
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
rescue ::RestClient::Exception => e
|
|
160
|
+
#raise e
|
|
161
|
+
if (e.response && e.response.code == 400)
|
|
162
|
+
json_response = JSON.parse(e.response.to_s)
|
|
163
|
+
error_msg = json_response['error_description'] || "Credentials not verified."
|
|
164
|
+
print_red_alert error_msg
|
|
165
|
+
if options[:json]
|
|
166
|
+
json_response = JSON.parse(e.response.to_s)
|
|
167
|
+
print JSON.pretty_generate(json_response)
|
|
168
|
+
print reset, "\n"
|
|
169
|
+
end
|
|
170
|
+
else
|
|
171
|
+
print_rest_exception(e, options)
|
|
172
|
+
end
|
|
173
|
+
wallet = nil
|
|
113
174
|
end
|
|
114
|
-
access_token = nil
|
|
115
|
-
end
|
|
116
175
|
|
|
176
|
+
end
|
|
117
177
|
end
|
|
118
178
|
|
|
179
|
+
if do_save && @appliance_name
|
|
180
|
+
|
|
119
181
|
|
|
120
|
-
unless skip_save
|
|
121
182
|
begin
|
|
122
|
-
|
|
183
|
+
# save pertinent session info to the appliance
|
|
184
|
+
save_credentials(@appliance_name, wallet)
|
|
123
185
|
now = Time.now.to_i
|
|
124
186
|
appliance = ::Morpheus::Cli::Remote.load_remote(@appliance_name)
|
|
187
|
+
|
|
188
|
+
if wallet && wallet['access_token']
|
|
189
|
+
save_credentials(@appliance_name, wallet)
|
|
190
|
+
else
|
|
191
|
+
clear_saved_credentials(@appliance_name)
|
|
192
|
+
end
|
|
125
193
|
if appliance
|
|
126
|
-
if access_token
|
|
194
|
+
if wallet && wallet['access_token']
|
|
195
|
+
# save wallet to credentials file
|
|
196
|
+
save_credentials(@appliance_name, wallet)
|
|
197
|
+
# save appliances file
|
|
127
198
|
appliance = ::Morpheus::Cli::Remote.load_remote(@appliance_name)
|
|
128
199
|
appliance[:authenticated] = true
|
|
129
200
|
appliance[:username] = username
|
|
@@ -132,26 +203,37 @@ module Morpheus
|
|
|
132
203
|
appliance[:last_success_at] = now
|
|
133
204
|
::Morpheus::Cli::Remote.save_remote(@appliance_name, appliance)
|
|
134
205
|
else
|
|
206
|
+
# could be nice and not do this
|
|
207
|
+
#logout()
|
|
208
|
+
#save wallet to credentials file
|
|
209
|
+
clear_saved_credentials(@appliance_name)
|
|
135
210
|
now = Time.now.to_i
|
|
136
211
|
appliance = ::Morpheus::Cli::Remote.load_remote(@appliance_name)
|
|
137
212
|
appliance[:authenticated] = false
|
|
138
|
-
|
|
213
|
+
old_username = appliance.delete(:username)
|
|
214
|
+
appliance[:last_logout_at] = Time.now.to_i
|
|
139
215
|
#appliance[:last_login_at] = now
|
|
140
216
|
#appliance[:error] = "Credentials not verified"
|
|
217
|
+
appliance.delete(:username)
|
|
141
218
|
::Morpheus::Cli::Remote.save_remote(@appliance_name, appliance)
|
|
219
|
+
if old_username
|
|
220
|
+
print reset,"You have been automatically logged out. Goodbye #{old_username}!", reset, "\n"
|
|
221
|
+
end
|
|
142
222
|
end
|
|
223
|
+
|
|
143
224
|
end
|
|
144
225
|
rescue => e
|
|
145
|
-
|
|
226
|
+
Morpheus::Logging::DarkPrinter.puts "failed to update remote appliance config: (#{e.class}) #{e.message}"
|
|
227
|
+
ensure
|
|
228
|
+
#::Morpheus::Cli::Remote.recalculate_variable_map()
|
|
146
229
|
end
|
|
147
230
|
end
|
|
148
|
-
|
|
149
|
-
return
|
|
231
|
+
|
|
232
|
+
return wallet
|
|
150
233
|
end
|
|
151
234
|
|
|
152
|
-
def login(
|
|
153
|
-
|
|
154
|
-
request_credentials(opts)
|
|
235
|
+
def login(options = {}, do_save=true)
|
|
236
|
+
request_credentials(options, do_save)
|
|
155
237
|
end
|
|
156
238
|
|
|
157
239
|
def logout()
|
|
@@ -164,21 +246,123 @@ module Morpheus
|
|
|
164
246
|
appliance[:last_logout_at] = Time.now.to_i
|
|
165
247
|
::Morpheus::Cli::Remote.save_remote(@appliance_name, appliance)
|
|
166
248
|
end
|
|
249
|
+
::Morpheus::Cli::Remote.recalculate_variable_map()
|
|
167
250
|
true
|
|
168
251
|
end
|
|
169
252
|
|
|
253
|
+
def use_refresh_token(options = {})
|
|
254
|
+
#puts "use_refresh_token(#{options})"
|
|
255
|
+
|
|
256
|
+
wallet = load_saved_credentials
|
|
257
|
+
|
|
258
|
+
if wallet.nil?
|
|
259
|
+
print_red_alert yellow,"You are not currently logged in to #{display_appliance(@appliance_name, @appliance_url)}",reset,"\n"
|
|
260
|
+
return nil
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
if wallet['refresh_token'].nil?
|
|
264
|
+
print_red_alert yellow,"No refresh token found for #{display_appliance(@appliance_name, @appliance_url)}",reset,"\n"
|
|
265
|
+
return nil
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
username = wallet['username']
|
|
270
|
+
|
|
271
|
+
begin
|
|
272
|
+
auth_interface.setopts(options)
|
|
273
|
+
auth_interface = Morpheus::AuthInterface.new(@appliance_url)
|
|
274
|
+
if options[:dry_run]
|
|
275
|
+
print_dry_run auth_interface.dry.use_refresh_token(wallet['refresh_token'])
|
|
276
|
+
return nil
|
|
277
|
+
end
|
|
278
|
+
json_response = auth_interface.use_refresh_token(wallet['refresh_token'])
|
|
279
|
+
#wallet = json_response
|
|
280
|
+
login_date = Time.now
|
|
281
|
+
expire_date = nil
|
|
282
|
+
if json_response['expires_in']
|
|
283
|
+
expire_date = login_date.to_i + json_response['expires_in'].to_i
|
|
284
|
+
end
|
|
285
|
+
wallet = {
|
|
286
|
+
'username' => username,
|
|
287
|
+
'login_date' => login_date.to_i,
|
|
288
|
+
'expire_date' => expire_date ? expire_date.to_i : nil,
|
|
289
|
+
'access_token' => json_response['access_token'],
|
|
290
|
+
'refresh_token' => json_response['refresh_token'],
|
|
291
|
+
'token_type' => json_response['token_type']
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
rescue ::RestClient::Exception => e
|
|
295
|
+
#raise e
|
|
296
|
+
if (e.response && e.response.code == 400)
|
|
297
|
+
json_response = JSON.parse(e.response.to_s)
|
|
298
|
+
error_msg = json_response['error_description'] || "Refresh token not valid."
|
|
299
|
+
print_red_alert error_msg
|
|
300
|
+
if options[:json]
|
|
301
|
+
json_response = JSON.parse(e.response.to_s)
|
|
302
|
+
print JSON.pretty_generate(json_response)
|
|
303
|
+
print reset, "\n"
|
|
304
|
+
end
|
|
305
|
+
else
|
|
306
|
+
print_rest_exception(e, options)
|
|
307
|
+
end
|
|
308
|
+
wallet = nil
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
# save wallet to credentials file
|
|
312
|
+
save_credentials(@appliance_name, wallet)
|
|
313
|
+
|
|
314
|
+
begin
|
|
315
|
+
# save pertinent session info to the appliance
|
|
316
|
+
now = Time.now.to_i
|
|
317
|
+
appliance = ::Morpheus::Cli::Remote.load_remote(@appliance_name)
|
|
318
|
+
if appliance
|
|
319
|
+
if wallet && wallet['access_token']
|
|
320
|
+
appliance = ::Morpheus::Cli::Remote.load_remote(@appliance_name)
|
|
321
|
+
appliance[:authenticated] = true
|
|
322
|
+
appliance[:username] = username
|
|
323
|
+
appliance[:status] = "ready"
|
|
324
|
+
appliance[:last_login_at] = now
|
|
325
|
+
appliance[:last_success_at] = now
|
|
326
|
+
::Morpheus::Cli::Remote.save_remote(@appliance_name, appliance)
|
|
327
|
+
else
|
|
328
|
+
now = Time.now.to_i
|
|
329
|
+
appliance = ::Morpheus::Cli::Remote.load_remote(@appliance_name)
|
|
330
|
+
appliance[:authenticated] = false
|
|
331
|
+
#appliance[:username] = username
|
|
332
|
+
#appliance[:last_login_at] = now
|
|
333
|
+
#appliance[:error] = "Credentials not verified"
|
|
334
|
+
::Morpheus::Cli::Remote.save_remote(@appliance_name, appliance)
|
|
335
|
+
end
|
|
336
|
+
end
|
|
337
|
+
rescue => e
|
|
338
|
+
Morpheus::Logging::DarkPrinter.puts "failed to update remote appliance config: (#{e.class}) #{e.message}"
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
return wallet
|
|
343
|
+
end
|
|
344
|
+
|
|
170
345
|
def clear_saved_credentials(appliance_name)
|
|
171
346
|
@@appliance_credentials_map = load_credentials_file || {}
|
|
172
|
-
@@appliance_credentials_map.delete(appliance_name)
|
|
347
|
+
@@appliance_credentials_map.delete(appliance_name.to_s)
|
|
348
|
+
@@appliance_credentials_map.delete(appliance_name.to_sym)
|
|
173
349
|
Morpheus::Logging::DarkPrinter.puts "clearing credentials for #{appliance_name} from file #{credentials_file_path}" if Morpheus::Logging.debug?
|
|
174
350
|
File.open(credentials_file_path, 'w') {|f| f.write @@appliance_credentials_map.to_yaml } #Store
|
|
351
|
+
::Morpheus::Cli::Remote.recalculate_variable_map()
|
|
352
|
+
true
|
|
175
353
|
end
|
|
176
354
|
|
|
177
355
|
def load_saved_credentials(reload=false)
|
|
178
356
|
if reload || !defined?(@@appliance_credentials_map) || @@appliance_credentials_map.nil?
|
|
179
357
|
@@appliance_credentials_map = load_credentials_file || {}
|
|
180
358
|
end
|
|
181
|
-
|
|
359
|
+
# ok, we switched symbols to strings, because symbols suck in yaml! need to support both
|
|
360
|
+
# also we switched from just a token (symbol) to a whole object of strings
|
|
361
|
+
wallet = @@appliance_credentials_map[@appliance_name.to_s] || @@appliance_credentials_map[@appliance_name.to_sym]
|
|
362
|
+
if wallet.is_a?(String)
|
|
363
|
+
wallet = {'access_token' => wallet}
|
|
364
|
+
end
|
|
365
|
+
return wallet
|
|
182
366
|
end
|
|
183
367
|
|
|
184
368
|
def load_credentials_file
|
|
@@ -195,14 +379,19 @@ module Morpheus
|
|
|
195
379
|
File.join(Morpheus::Cli.home_directory, "credentials")
|
|
196
380
|
end
|
|
197
381
|
|
|
198
|
-
|
|
199
|
-
|
|
382
|
+
# credentials wallet is {'access_token': '...', 'refresh_token': '...' 'expiration': '2019-01-01...'}
|
|
383
|
+
def save_credentials(appliance_name, wallet)
|
|
200
384
|
# reloading file is better for now, otherwise you can lose credentials with multiple shells.
|
|
201
385
|
credential_map = load_credentials_file || {}
|
|
202
|
-
|
|
203
|
-
|
|
386
|
+
|
|
387
|
+
if wallet
|
|
388
|
+
credential_map[appliance_name.to_s] = wallet
|
|
389
|
+
else
|
|
390
|
+
# nil mean remove the damn thing
|
|
391
|
+
credential_map.delete(appliance_name.to_s)
|
|
204
392
|
end
|
|
205
|
-
|
|
393
|
+
# always remove symbol, which was used pre 3.6.9
|
|
394
|
+
credential_map.delete(appliance_name.to_sym)
|
|
206
395
|
begin
|
|
207
396
|
fn = credentials_file_path
|
|
208
397
|
if !Dir.exists?(File.dirname(fn))
|