morpheus-cli 4.2.8 → 4.2.10
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/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
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
require 'optparse'
|
|
2
1
|
require 'morpheus/cli/cli_command'
|
|
3
|
-
require 'morpheus/cli/mixins/accounts_helper'
|
|
4
|
-
require 'json'
|
|
5
2
|
|
|
6
3
|
class Morpheus::Cli::RecentActivityCommand
|
|
7
4
|
include Morpheus::Cli::CliCommand
|
|
@@ -9,6 +6,9 @@ class Morpheus::Cli::RecentActivityCommand
|
|
|
9
6
|
|
|
10
7
|
set_command_name :'recent-activity'
|
|
11
8
|
|
|
9
|
+
# deprecated 4.2.10
|
|
10
|
+
set_command_hidden
|
|
11
|
+
|
|
12
12
|
def initialize()
|
|
13
13
|
# @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
|
|
14
14
|
end
|
|
@@ -19,58 +19,89 @@ class Morpheus::Cli::RecentActivityCommand
|
|
|
19
19
|
@accounts_interface = @api_client.accounts
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
def usage
|
|
23
|
-
|
|
24
|
-
end
|
|
22
|
+
# def usage
|
|
23
|
+
# "Usage: morpheus #{command_name}"
|
|
24
|
+
# end
|
|
25
25
|
|
|
26
26
|
def handle(args)
|
|
27
|
+
print_error yellow,"[DEPRECATED] The command `recent-activity` is deprecated. It has been replaced by `activity list`.",reset,"\n"
|
|
27
28
|
list(args)
|
|
28
29
|
end
|
|
30
|
+
|
|
29
31
|
def list(args)
|
|
30
|
-
options = {}
|
|
32
|
+
params, options = {}, {}
|
|
31
33
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
|
32
34
|
opts.banner = usage
|
|
35
|
+
opts.on( '-u', '--user USER', "Username or ID" ) do |val|
|
|
36
|
+
options[:user] = val
|
|
37
|
+
end
|
|
33
38
|
opts.on('--start TIMESTAMP','--start TIMESTAMP', "Start timestamp. Default is 30 days ago.") do |val|
|
|
34
39
|
options[:start] = parse_time(val).utc.iso8601
|
|
35
40
|
end
|
|
36
41
|
opts.on('--end TIMESTAMP','--end TIMESTAMP', "End timestamp. Default is now.") do |val|
|
|
37
42
|
options[:end] = parse_time(val).utc.iso8601
|
|
38
43
|
end
|
|
39
|
-
|
|
44
|
+
build_standard_get_options(opts, options)
|
|
45
|
+
opts.footer = <<-EOT
|
|
46
|
+
List recent activity.
|
|
47
|
+
This command is deprecated. Use `activity` instead.
|
|
48
|
+
EOT
|
|
40
49
|
end
|
|
50
|
+
# parse options
|
|
41
51
|
optparse.parse!(args)
|
|
52
|
+
# parse arguments
|
|
53
|
+
verify_args!(args:args, count:0, optparse:optparse)
|
|
54
|
+
# establish connection to @remote_appliance
|
|
42
55
|
connect(options)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
end
|
|
59
|
-
|
|
56
|
+
# construct request
|
|
57
|
+
#params.merge!(parse_query_options(options)) # inject -Q PARAMS
|
|
58
|
+
params.merge!(parse_list_options(options)) # inject phrase,sort,max,offset and -Q PARAMS
|
|
59
|
+
# parse my options
|
|
60
|
+
# this api allows filter by params.accountId
|
|
61
|
+
# todo: use OptionSourceHelper parse_tenant_id() instead of AccountsHelper
|
|
62
|
+
account = find_account_from_options(options)
|
|
63
|
+
account_id = account ? account['id'] : nil
|
|
64
|
+
if account_id
|
|
65
|
+
params['accountId'] = account_id
|
|
66
|
+
end
|
|
67
|
+
if options[:start]
|
|
68
|
+
params['start'] = options[:start]
|
|
69
|
+
end
|
|
70
|
+
if options[:end]
|
|
71
|
+
params['end'] = options[:end]
|
|
72
|
+
end
|
|
60
73
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
+
# parse --user
|
|
75
|
+
if options[:user]
|
|
76
|
+
user_ids = parse_user_id_list(options[:user])
|
|
77
|
+
return 1 if user_ids.nil?
|
|
78
|
+
# userId limited to one right now
|
|
79
|
+
# params['userId'] = user_ids
|
|
80
|
+
params['userId'] = user_ids[0]
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# setup interface and check for dry run?
|
|
84
|
+
@dashboard_interface.setopts(options)
|
|
85
|
+
if options[:dry_run]
|
|
86
|
+
print_dry_run @dashboard_interface.dry.recent_activity(params)
|
|
87
|
+
return 0, nil
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# make the request
|
|
91
|
+
json_response = @dashboard_interface.recent_activity(params)
|
|
92
|
+
|
|
93
|
+
# determine exit status
|
|
94
|
+
exit_code, err = 0, nil
|
|
95
|
+
|
|
96
|
+
# could error if there are no results.
|
|
97
|
+
# if json_response['activity'].empty?
|
|
98
|
+
# exit_code = 3
|
|
99
|
+
# err = "0 results found"
|
|
100
|
+
# end
|
|
101
|
+
|
|
102
|
+
# render output
|
|
103
|
+
render_response(json_response, options, "activity") do
|
|
104
|
+
title = "Activity"
|
|
74
105
|
subtitles = []
|
|
75
106
|
subtitles += parse_list_subtitles(options)
|
|
76
107
|
if options[:start]
|
|
@@ -85,37 +116,28 @@ class Morpheus::Cli::RecentActivityCommand
|
|
|
85
116
|
if items.empty?
|
|
86
117
|
puts "No activity found."
|
|
87
118
|
print reset,"\n"
|
|
88
|
-
|
|
119
|
+
else
|
|
120
|
+
# JD: this api response is funky, no meta and it includes date objects
|
|
121
|
+
# ok then its gone, get good api response data gosh darnit!
|
|
122
|
+
# use /api/activity instead
|
|
123
|
+
items = items.select { |item| item['_id'] || item['name'] }
|
|
124
|
+
columns = [
|
|
125
|
+
# {"ID" => lambda {|item| item['id'] } },
|
|
126
|
+
# {"SEVERITY" => lambda {|item| format_activity_severity(item['severity']) } },
|
|
127
|
+
{"TYPE" => lambda {|item| item['activityType'] } },
|
|
128
|
+
{"AUTHOR" => lambda {|item| item['userName'] || '' } },
|
|
129
|
+
{"MESSAGE" => lambda {|item| item['message'] || '' } },
|
|
130
|
+
{"OBJECT" => lambda {|item| format_activity_display_object(item) } },
|
|
131
|
+
{"WHEN" => lambda {|item| format_local_dt(item['ts']) } }
|
|
132
|
+
]
|
|
133
|
+
print as_pretty_table(items, columns, options)
|
|
134
|
+
print reset,"\n"
|
|
89
135
|
end
|
|
90
|
-
|
|
91
|
-
items = items.select { |item| item['_id'] || item['name'] }
|
|
92
|
-
print_recent_activity_table(items, options)
|
|
93
|
-
print reset,"\n"
|
|
94
|
-
return 0
|
|
95
|
-
|
|
96
|
-
rescue RestClient::Exception => e
|
|
97
|
-
print_rest_exception(e, options)
|
|
98
|
-
return 1
|
|
136
|
+
return exit_code, err
|
|
99
137
|
end
|
|
100
138
|
end
|
|
101
139
|
|
|
102
|
-
|
|
103
|
-
columns = [
|
|
104
|
-
# {"ID" => lambda {|item| item['id'] } },
|
|
105
|
-
# {"SEVERITY" => lambda {|item| format_activity_severity(item['severity']) } },
|
|
106
|
-
{"TYPE" => lambda {|item| item['activityType'] } },
|
|
107
|
-
{"AUTHOR" => lambda {|item| item['userName'] || '' } },
|
|
108
|
-
{"MESSAGE" => lambda {|item| item['message'] || '' } },
|
|
109
|
-
# {"NAME" => lambda {|item| item['name'] } },
|
|
110
|
-
{"OBJECT" => lambda {|item| format_activity_display_object(item) } },
|
|
111
|
-
{"WHEN" => lambda {|item| format_local_dt(item['ts']) } }
|
|
112
|
-
# {"WHEN" => lambda {|item| "#{format_duration(item['ts'])} ago" } }
|
|
113
|
-
]
|
|
114
|
-
if opts[:include_fields]
|
|
115
|
-
columns = opts[:include_fields]
|
|
116
|
-
end
|
|
117
|
-
print as_pretty_table(items, columns, opts)
|
|
118
|
-
end
|
|
140
|
+
protected
|
|
119
141
|
|
|
120
142
|
def format_activity_severity(severity, return_color=cyan)
|
|
121
143
|
out = ""
|
data/lib/morpheus/cli/remote.rb
CHANGED
|
@@ -10,9 +10,16 @@ require 'morpheus/cli/cli_command'
|
|
|
10
10
|
|
|
11
11
|
class Morpheus::Cli::Remote
|
|
12
12
|
include Morpheus::Cli::CliCommand
|
|
13
|
+
include Morpheus::Cli::RemoteHelper
|
|
13
14
|
|
|
14
|
-
register_subcommands :list, :add, :get, :update, :rename, :remove, :use, :unuse, :current
|
|
15
|
-
|
|
15
|
+
register_subcommands :list, :add, :get, :update, :rename, :remove, :use, :unuse, :clone, :current, :view
|
|
16
|
+
# remote setup and remote check
|
|
17
|
+
# are now avaiable under ping and setup
|
|
18
|
+
# they do the same thing
|
|
19
|
+
register_subcommands :setup
|
|
20
|
+
register_subcommands :check
|
|
21
|
+
register_subcommands :'check-all' => :check_all
|
|
22
|
+
register_subcommands :version => :version
|
|
16
23
|
|
|
17
24
|
set_default_subcommand :list
|
|
18
25
|
|
|
@@ -21,8 +28,8 @@ class Morpheus::Cli::Remote
|
|
|
21
28
|
end
|
|
22
29
|
|
|
23
30
|
def connect(opts={})
|
|
24
|
-
|
|
25
|
-
@api_client = establish_remote_appliance_connection(
|
|
31
|
+
# no authorization needed, do not verify a token or prompt for login
|
|
32
|
+
@api_client = establish_remote_appliance_connection({:skip_verify_access_token => true, :skip_login => true}.merge(opts))
|
|
26
33
|
@setup_interface = @api_client.setup
|
|
27
34
|
end
|
|
28
35
|
|
|
@@ -34,16 +41,23 @@ class Morpheus::Cli::Remote
|
|
|
34
41
|
options = {}
|
|
35
42
|
params = {}
|
|
36
43
|
show_all_activity = false
|
|
44
|
+
current_only = false
|
|
45
|
+
do_check = false
|
|
37
46
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
|
38
47
|
opts.banner = subcommand_usage()
|
|
39
48
|
opts.on("-a",'--all', "Show all the appliance activity details") do
|
|
40
49
|
show_all_activity = true
|
|
50
|
+
options[:wrap] = true
|
|
51
|
+
end
|
|
52
|
+
opts.on("--current", "--current", "List only the active (current) appliance.") do
|
|
53
|
+
current_only = true
|
|
54
|
+
end
|
|
55
|
+
opts.on("--check", "--check", "Check each appliance in the list to refresh their status, this may take a while.") do
|
|
56
|
+
do_check = true
|
|
41
57
|
end
|
|
42
58
|
build_common_options(opts, options, [:list, :json, :yaml, :csv, :fields])
|
|
43
59
|
opts.footer = <<-EOT
|
|
44
|
-
|
|
45
|
-
the current appliance. The current appliance is where morpheus will send
|
|
46
|
-
its commands by default. That is, in absence of the '--remote' option.
|
|
60
|
+
List the configured remote appliances.
|
|
47
61
|
EOT
|
|
48
62
|
end
|
|
49
63
|
optparse.parse!(args)
|
|
@@ -54,138 +68,195 @@ EOT
|
|
|
54
68
|
params.merge!(parse_list_options(options))
|
|
55
69
|
appliances = ::Morpheus::Cli::Remote.load_all_remotes(params)
|
|
56
70
|
# if appliances.empty?
|
|
57
|
-
# raise_command_error "You have no appliances configured. See the `remote add
|
|
71
|
+
# raise_command_error "You have no appliances configured. See the command `remote add`."
|
|
58
72
|
# end
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
if options[:json]
|
|
62
|
-
puts as_json(json_response, options, "appliances")
|
|
63
|
-
return 0
|
|
64
|
-
elsif options[:yaml]
|
|
65
|
-
puts as_yaml(json_response, options, "appliances")
|
|
66
|
-
return 0
|
|
67
|
-
elsif options[:csv]
|
|
68
|
-
puts records_as_csv(appliances, options)
|
|
69
|
-
return 0
|
|
73
|
+
if current_only
|
|
74
|
+
appliances = appliances.select {|a| a[:active] }
|
|
70
75
|
end
|
|
71
|
-
if
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
{:activity => {display_method: lambda {|it| show_all_activity ? get_appliance_session_blurbs(it).join("\t") : get_appliance_session_blurbs(it).first } } }
|
|
92
|
-
]
|
|
93
|
-
print as_pretty_table(appliances, columns, options)
|
|
94
|
-
print reset
|
|
95
|
-
if @appliance_name
|
|
96
|
-
#unless appliances.keys.size == 1
|
|
97
|
-
print cyan, "\n# => #{@appliance_name} is the current remote appliance\n", reset
|
|
98
|
-
#end
|
|
76
|
+
if do_check
|
|
77
|
+
# return here because it prints a list() too..
|
|
78
|
+
return _check_all_appliances(options)
|
|
79
|
+
end
|
|
80
|
+
# mock json
|
|
81
|
+
json_response = {"appliances" => appliances}
|
|
82
|
+
# render
|
|
83
|
+
exit_code, err = 0, nil
|
|
84
|
+
render_response(json_response, options, "appliances") do
|
|
85
|
+
|
|
86
|
+
if appliances.empty?
|
|
87
|
+
if params[:phrase]
|
|
88
|
+
print reset,"0 remotes matched '#{params[:phrase]}'", reset, "\n"
|
|
89
|
+
print reset,"Try `remote add #{params[:phrase]}`", reset, "\n"
|
|
90
|
+
return 0, nil # maybe exit non-zero when no records are found, could be nicer
|
|
91
|
+
else
|
|
92
|
+
warning_msg = "No remote appliances configured. See the command `remote add`."
|
|
93
|
+
print yellow, warning_msg, reset, "\n"
|
|
94
|
+
return 2, warning_msg
|
|
95
|
+
end
|
|
99
96
|
else
|
|
100
|
-
|
|
97
|
+
title = "Morpheus Appliances"
|
|
98
|
+
subtitles = parse_list_subtitles(options)
|
|
99
|
+
subtitles << "Current" if current_only
|
|
100
|
+
print_h1 title, subtitles, options
|
|
101
|
+
|
|
102
|
+
columns = {
|
|
103
|
+
"Name" => :name,
|
|
104
|
+
"URL" => lambda {|it| it[:url] || it[:host] },
|
|
105
|
+
"Status" => lambda {|it| format_appliance_status(it, cyan) },
|
|
106
|
+
"Version" => lambda {|it| it[:build_version] ? "#{it[:build_version]}" : '' },
|
|
107
|
+
"Appliance URL" => lambda {|it| it[:appliance_url] ? "#{it[:appliance_url]}" : '' },
|
|
108
|
+
"Secure" => lambda {|it| format_boolean(it[:insecure] != true && (it[:url] || it[:host]).to_s.include?("https")) },
|
|
109
|
+
"Active" => lambda {|it| it[:active] ? "Yes " + format_is_current() : "No" },
|
|
110
|
+
#"Authenticated" => lambda {|it| format_boolean it[:authenticated] },
|
|
111
|
+
"Username" => :username,
|
|
112
|
+
# "Activity" => lambda {|it| get_appliance_session_blurbs(it).join("\n" + (' '*15)) },
|
|
113
|
+
"Last Login" => lambda {|it| format_duration_ago(it[:last_login_at]) },
|
|
114
|
+
#"Last Logout" => lambda {|it| format_duration_ago(it[:last_logout_at]) },
|
|
115
|
+
"Last Success" => lambda {|it| format_duration_ago(it[:last_success_at]) },
|
|
116
|
+
"Last Check" => lambda {|it|
|
|
117
|
+
check_str = ""
|
|
118
|
+
if it[:last_check]
|
|
119
|
+
check_timestamp = it[:last_check][:timestamp]
|
|
120
|
+
check_status = it[:last_check][:http_status]
|
|
121
|
+
if check_status
|
|
122
|
+
if check_status == 200
|
|
123
|
+
# no need to show this
|
|
124
|
+
else
|
|
125
|
+
check_status = check_status
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
if check_timestamp
|
|
129
|
+
check_duration_str = format_duration_ago(check_timestamp)
|
|
130
|
+
# check_str = check_status ? "#{check_duration_str} (HTTP #{check_status})" : check_duration_str
|
|
131
|
+
check_str = check_duration_str
|
|
132
|
+
end
|
|
133
|
+
else
|
|
134
|
+
# check_str = "n/a"
|
|
135
|
+
end
|
|
136
|
+
check_str
|
|
137
|
+
},
|
|
138
|
+
"Response Time" => lambda {|it| format_duration_milliseconds(it[:last_check][:took]) rescue "" },
|
|
139
|
+
#"Response Time" => lambda {|it| format_sig_dig((it[:last_check][:took]/ 1000.to_f), 3) + "s" rescue "" },
|
|
140
|
+
"Error" => {display_method: lambda {|it|
|
|
141
|
+
error_str = it[:last_check] ? it[:last_check][:error].to_s : ""
|
|
142
|
+
error_str
|
|
143
|
+
}, max_width: 30},
|
|
144
|
+
}
|
|
145
|
+
# when an active remote is in the list, add => prefix and padding to keep things aligned.
|
|
146
|
+
# this is sucky, use arrays
|
|
147
|
+
has_active_remote = appliances.find {|appliance| appliance[:active] }
|
|
148
|
+
if has_active_remote
|
|
149
|
+
columns.delete("Name")
|
|
150
|
+
columns = {" Name" => lambda {|it| it[:active] ? (bold + "=> #{it[:name]}" + reset + cyan) : " #{it[:name]}" } }.merge(columns)
|
|
151
|
+
end
|
|
152
|
+
has_an_error = appliances.find {|appliance| appliance[:last_check][:error] rescue nil }
|
|
153
|
+
if !has_an_error
|
|
154
|
+
columns.delete("Error")
|
|
155
|
+
end
|
|
156
|
+
if show_all_activity != true
|
|
157
|
+
columns.delete("Secure")
|
|
158
|
+
columns.delete("Appliance URL")
|
|
159
|
+
columns.delete("Active")
|
|
160
|
+
columns.delete("Authenticated")
|
|
161
|
+
columns.delete("Last Login")
|
|
162
|
+
columns.delete("Last Logout")
|
|
163
|
+
columns.delete("Last Success")
|
|
164
|
+
#columns.delete("Error") # unless appliances.find {|appliance| appliance[:last_check][:error] rescue nil }
|
|
165
|
+
else
|
|
166
|
+
# always remove these columns because they are worthless
|
|
167
|
+
columns.delete("Authenticated")
|
|
168
|
+
columns.delete("Active")
|
|
169
|
+
columns.delete("Last Success")
|
|
170
|
+
end
|
|
171
|
+
# oops, table labels are upcase, but description list is not??, make them upcase here
|
|
172
|
+
new_columns = {}
|
|
173
|
+
columns.each {|k,v| new_columns[k.to_s.upcase] = v }
|
|
174
|
+
columns = new_columns
|
|
175
|
+
print as_pretty_table(appliances, columns, options)
|
|
176
|
+
print reset
|
|
177
|
+
print_results_pagination({size:appliances.size,total:appliances.size})
|
|
101
178
|
end
|
|
102
179
|
print reset, "\n"
|
|
103
180
|
end
|
|
104
|
-
return
|
|
181
|
+
return exit_code, err
|
|
105
182
|
end
|
|
106
183
|
|
|
107
184
|
def add(args)
|
|
108
|
-
|
|
109
|
-
options = {}
|
|
110
|
-
params = {}
|
|
185
|
+
options, params, payload = {}, {}, {}
|
|
111
186
|
new_appliance_map = {}
|
|
112
|
-
use_it =
|
|
187
|
+
use_it = nil
|
|
113
188
|
secure = nil
|
|
114
189
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
|
115
|
-
banner = subcommand_usage(
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
[url] The url of your appliance eg. https://demo.mymorpheus.com
|
|
119
|
-
EOT
|
|
120
|
-
opts.banner = banner + "\n" + banner_args
|
|
121
|
-
opts.on(nil, '--use', "Make this the current appliance" ) do
|
|
122
|
-
use_it = true
|
|
123
|
-
new_appliance_map[:active] = true
|
|
124
|
-
end
|
|
125
|
-
# let's free up the -d switch for global options, maybe?
|
|
126
|
-
opts.on( '-d', '--default', "Does the same thing as --use" ) do
|
|
127
|
-
use_it = true
|
|
190
|
+
opts.banner = subcommand_usage('[name] [url]')
|
|
191
|
+
opts.on(nil, '--use [true|false]', "Start using remote right now. By default this is true if it's the first remote, otherwise false." ) do |val|
|
|
192
|
+
use_it = (val == 'no' || val == 'off' || val.to_s == 'false')
|
|
128
193
|
new_appliance_map[:active] = true
|
|
129
194
|
end
|
|
130
|
-
opts.on(nil, "--secure", "Prevent insecure HTTPS communication.
|
|
195
|
+
opts.on(nil, "--secure", "Prevent insecure HTTPS communication. Default is true.") do
|
|
131
196
|
secure = true
|
|
132
197
|
end
|
|
133
|
-
opts.on(nil, "--insecure", "Allow insecure HTTPS communication. i.e. Ignore SSL errors.") do
|
|
198
|
+
opts.on(nil, "--insecure", "Allow insecure HTTPS communication. i.e. Ignore SSL errors. Default is false.") do
|
|
134
199
|
secure = false
|
|
135
200
|
end
|
|
201
|
+
# ok, need to be able to pass every option supported by login() and setup()
|
|
136
202
|
build_common_options(opts, options, [:options, :quiet])
|
|
137
203
|
opts.footer = <<-EOT
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
204
|
+
Add a new remote to your morpheus client configuration.
|
|
205
|
+
[name] is required. A unique name for your appliance. eg. demo
|
|
206
|
+
[url] is required. The URL of your appliance eg. https://demo.morpheusdata.com
|
|
207
|
+
First, this inspects the remote url to check the appliance status and version.
|
|
208
|
+
If remote is ready, it will prompt to login, see the command `login`.
|
|
209
|
+
If remote is freshly installed, it will prompt to initialize the appliance, see the command `setup`.
|
|
210
|
+
The option --use can be included to start using the new remote right away.
|
|
211
|
+
The remote will be used by default if it is the first remote in the configuration.
|
|
212
|
+
The --quiet option can be used to to skip prompting.
|
|
213
|
+
|
|
143
214
|
EOT
|
|
144
215
|
end
|
|
145
216
|
optparse.parse!(args)
|
|
146
|
-
|
|
147
|
-
raise_command_error "wrong number of arguments, expected 0-2 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
|
|
148
|
-
end
|
|
217
|
+
verify_args!(args:args, max:2, optparse:optparse)
|
|
149
218
|
|
|
219
|
+
# payload = options[:payload] ? options[:payload] : {}
|
|
220
|
+
# payload.deep_merge!(parse_passed_options(options))
|
|
221
|
+
# # skip prompting when --payload is used
|
|
222
|
+
# if options[:payload].nil?
|
|
223
|
+
# end
|
|
224
|
+
|
|
150
225
|
# load current appliances
|
|
151
226
|
appliances = ::Morpheus::Cli::Remote.appliances
|
|
152
227
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
new_appliance_map[:active] = true
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
new_appliance_name = args[0] if args[0]
|
|
159
|
-
url = args[1] if args[1]
|
|
228
|
+
new_appliance_name = args[0] ? args[0] : nil
|
|
229
|
+
url = args[1] ? args[1] : nil
|
|
160
230
|
|
|
161
231
|
# Name
|
|
162
232
|
still_prompting = true
|
|
163
233
|
while still_prompting do
|
|
164
|
-
if
|
|
165
|
-
|
|
166
|
-
|
|
234
|
+
if args[0]
|
|
235
|
+
new_appliance_name = args[0]
|
|
236
|
+
still_prompting = false
|
|
237
|
+
else
|
|
238
|
+
if new_appliance_name.to_s.empty?
|
|
239
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'description' => 'A unique name for the remote Morpheus appliance. Example: local'}], options[:options])
|
|
240
|
+
new_appliance_name = v_prompt['name']
|
|
241
|
+
end
|
|
167
242
|
end
|
|
168
|
-
|
|
169
243
|
# for the sake of sanity
|
|
170
|
-
if [:current, :all].include?(new_appliance_name.to_sym)
|
|
171
|
-
raise_command_error "The specified appliance name '#{new_appliance_name}' is invalid."
|
|
244
|
+
if [:current, :all, :'remote-url'].include?(new_appliance_name.to_sym)
|
|
245
|
+
raise_command_error "The specified remote appliance name '#{new_appliance_name}' is invalid."
|
|
172
246
|
new_appliance_name = nil
|
|
173
247
|
end
|
|
174
248
|
# unique name
|
|
175
249
|
existing_appliance = appliances[new_appliance_name.to_sym]
|
|
176
250
|
if existing_appliance
|
|
177
|
-
print_error red,"The specified appliance name '#{new_appliance_name}' already exists
|
|
251
|
+
print_error red,"The specified remote appliance name '#{new_appliance_name}' already exists: #{display_appliance(existing_appliance[:name], (existing_appliance[:url]))}",reset,"\n"
|
|
178
252
|
new_appliance_name = nil
|
|
179
253
|
end
|
|
180
|
-
|
|
181
|
-
if new_appliance_name.to_s.empty?
|
|
182
|
-
if options[:no_prompt]
|
|
183
|
-
return 1
|
|
184
|
-
end
|
|
185
|
-
still_prompting = true
|
|
186
|
-
else
|
|
254
|
+
if new_appliance_name
|
|
187
255
|
still_prompting = false
|
|
188
256
|
end
|
|
257
|
+
if new_appliance_name.nil? && still_prompting == false
|
|
258
|
+
return 1
|
|
259
|
+
end
|
|
189
260
|
end
|
|
190
261
|
|
|
191
262
|
new_appliance_map[:name] = new_appliance_name.to_sym
|
|
@@ -193,83 +264,109 @@ EOT
|
|
|
193
264
|
# URL
|
|
194
265
|
still_prompting = true
|
|
195
266
|
while still_prompting do
|
|
196
|
-
if
|
|
197
|
-
|
|
198
|
-
|
|
267
|
+
if args[1]
|
|
268
|
+
url = args[1]
|
|
269
|
+
still_prompting = false
|
|
270
|
+
else
|
|
271
|
+
if !url
|
|
272
|
+
default_url = nil
|
|
273
|
+
# use Name: dev to get a happy default.
|
|
274
|
+
# if new_appliance_name == "dev"
|
|
275
|
+
if new_appliance_name == "local" || new_appliance_name == "localhost" || new_appliance_name == "dev"
|
|
276
|
+
default_url = "http://localhost:8080"
|
|
277
|
+
end
|
|
278
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'url', 'fieldLabel' => 'URL', 'type' => 'text', 'required' => true, 'description' => 'The URL of the remote Morpheus appliance. Example: https://10.0.2.2', 'defaultValue' => default_url}], options[:options])
|
|
279
|
+
url = v_prompt['url']
|
|
280
|
+
end
|
|
199
281
|
end
|
|
200
282
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
283
|
+
# strip whitespace from URL
|
|
284
|
+
url = url.to_s.strip
|
|
285
|
+
|
|
286
|
+
if url.to_s !~ /^https?\:\/\/.+/
|
|
287
|
+
print_error red,"The specified remote appliance url '#{url}' is invalid.",reset,"\n"
|
|
288
|
+
#still_prompting = true
|
|
204
289
|
url = nil
|
|
205
290
|
else
|
|
206
291
|
still_prompting = false
|
|
207
292
|
end
|
|
293
|
+
if url.nil? && still_prompting == false
|
|
294
|
+
return 1
|
|
295
|
+
end
|
|
208
296
|
end
|
|
209
297
|
|
|
210
|
-
# let's replace :host with :url
|
|
211
|
-
new_appliance_map[:host] = url
|
|
212
298
|
new_appliance_map[:url] = url
|
|
213
299
|
|
|
214
|
-
#
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
300
|
+
# --insecure or --secure
|
|
301
|
+
# Secure? (Ignore SSL errors)
|
|
302
|
+
# secure is the default,
|
|
303
|
+
# try to only store insecure:false in the appliances config
|
|
304
|
+
if url.to_s =~ /^https\:/ && secure.nil?
|
|
305
|
+
if secure != nil
|
|
306
|
+
new_appliance_map[:insecure] = !secure
|
|
307
|
+
else
|
|
308
|
+
#v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'secure', 'fieldLabel' => 'Secure', 'type' => 'checkbox', 'required' => false, 'defaultValue' => true, 'description' => 'Prevent insecure HTTPS communication, respect SSL errors.'}], options[:options])
|
|
309
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'insecure', 'fieldLabel' => 'Insecure (Ignore SSL Errors)', 'type' => 'checkbox', 'required' => false, 'defaultValue' => false, 'description' => 'Allow insecure HTTPS communication, ignore SSL errors.'}], options[:options])
|
|
310
|
+
if v_prompt['insecure'].to_s == 'true' || v_prompt['insecure'].to_s == 'on'
|
|
311
|
+
new_appliance_map[:insecure] = true
|
|
312
|
+
end
|
|
313
|
+
end
|
|
219
314
|
end
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
315
|
+
|
|
316
|
+
# --use
|
|
317
|
+
if use_it != nil
|
|
318
|
+
if use_it
|
|
319
|
+
new_appliance_map[:active] = true
|
|
320
|
+
end
|
|
321
|
+
else
|
|
322
|
+
# if ::Morpheus::Cli::OptionTypes::confirm("Would you like to switch to using this remote now?", options.merge({default: appliances.empty?}))
|
|
323
|
+
# new_appliance_map[:active] = true
|
|
324
|
+
# end
|
|
325
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'use', 'fieldLabel' => 'Use?', 'type' => 'checkbox', 'defaultValue' => appliances.empty?, 'description' => 'Start using this remote right away'}], options[:options])
|
|
326
|
+
if v_prompt['use'].to_s == 'true' || v_prompt['use'].to_s == 'on'
|
|
327
|
+
new_appliance_map[:active] = true
|
|
328
|
+
end
|
|
223
329
|
end
|
|
224
330
|
|
|
225
331
|
# save it
|
|
226
332
|
appliance = ::Morpheus::Cli::Remote.save_remote(new_appliance_name.to_sym, new_appliance_map)
|
|
227
333
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
334
|
+
# refresh it (does /api/setup/check to refresh status and build
|
|
335
|
+
# todo: this should happen in save eh?
|
|
336
|
+
#Morpheus::Logging::DarkPrinter.puts "inspecting remote #{appliance[:name]} #{appliance[:url]}" if Morpheus::Logging.debug? && !options[:quiet]
|
|
337
|
+
appliance, json_response = ::Morpheus::Cli::Remote.refresh_remote(new_appliance_name.to_sym)
|
|
232
338
|
|
|
233
|
-
# hit check api and
|
|
339
|
+
# hit /setup/check api and update version and status
|
|
234
340
|
if !options[:quiet]
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
end
|
|
238
|
-
appliance, check_json_response = ::Morpheus::Cli::Remote.refresh_remote(new_appliance_name.to_sym)
|
|
239
|
-
if !options[:quiet]
|
|
240
|
-
print cyan
|
|
241
|
-
puts "Status is: #{format_appliance_status(appliance)}"
|
|
341
|
+
# print_green_success "Added remote #{new_appliance_name}, status is #{format_appliance_status(appliance)}"
|
|
342
|
+
print cyan,"Added remote #{new_appliance_name}, status is #{format_appliance_status(appliance)}",reset,"\n"
|
|
242
343
|
end
|
|
344
|
+
|
|
345
|
+
appliance, json_response = ::Morpheus::Cli::Remote.refresh_remote(new_appliance_name.to_sym)
|
|
346
|
+
# if !options[:quiet]
|
|
347
|
+
# print cyan
|
|
348
|
+
# puts "Status: #{format_appliance_status(appliance)}"
|
|
349
|
+
# print reset
|
|
350
|
+
# end
|
|
243
351
|
# puts "refreshed appliance #{appliance.inspect}"
|
|
244
352
|
# determine command exit_code and err
|
|
245
|
-
exit_code =
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
exit_code = 1
|
|
250
|
-
err = "Check Failed: #{appliance[:error]}"
|
|
251
|
-
end
|
|
353
|
+
exit_code, err = 0, nil
|
|
354
|
+
if (appliance[:status] != 'ready' && appliance[:status] != 'fresh')
|
|
355
|
+
exit_code = 1
|
|
356
|
+
err = "remote status is #{appliance[:status]}"
|
|
252
357
|
end
|
|
253
358
|
|
|
359
|
+
# just skip prompting no prompt -q is used.
|
|
254
360
|
if options[:quiet]
|
|
255
361
|
return exit_code, err
|
|
256
362
|
end
|
|
257
|
-
|
|
258
|
-
if options[:json]
|
|
259
|
-
puts as_json(check_json_response, options)
|
|
260
|
-
return exit_code, err
|
|
261
|
-
end
|
|
262
|
-
|
|
263
|
-
# just skip setup/login stuff is no prompt -N is used.
|
|
363
|
+
# just skip prompting no prompt -N is used.
|
|
264
364
|
if options[:no_prompt]
|
|
265
365
|
return exit_code, err
|
|
266
366
|
end
|
|
267
367
|
|
|
268
|
-
#
|
|
269
|
-
# check_cmd_result = check_appliance([new_appliance_name])
|
|
270
|
-
|
|
368
|
+
# setup fresh appliance?
|
|
271
369
|
if appliance[:status] == 'fresh' # || appliance[:setup_needed] == true
|
|
272
|
-
|
|
273
370
|
if !appliance[:active]
|
|
274
371
|
if ::Morpheus::Cli::OptionTypes::confirm("Would you like to switch to using this remote now?", options.merge({default: true}))
|
|
275
372
|
use([appliance[:name]])
|
|
@@ -283,21 +380,20 @@ EOT
|
|
|
283
380
|
# no need to login, setup() handles that
|
|
284
381
|
end
|
|
285
382
|
|
|
286
|
-
|
|
287
383
|
# only login if you are using this remote
|
|
288
384
|
# maybe remote use should do the login prompting eh?
|
|
289
385
|
# if appliance[:active] && appliance[:status] == 'ready'
|
|
290
386
|
if appliance[:status] == 'ready'
|
|
291
387
|
print reset
|
|
292
388
|
if ::Morpheus::Cli::OptionTypes::confirm("Would you like to login now?", options.merge({default: true}))
|
|
293
|
-
login_result = ::Morpheus::Cli::Login.new.handle(["
|
|
389
|
+
login_result = ::Morpheus::Cli::Login.new.handle(["-r", appliance[:name].to_s])
|
|
294
390
|
keep_trying = true
|
|
295
391
|
if login_result == 0
|
|
296
392
|
keep_trying = false
|
|
297
393
|
end
|
|
298
394
|
while keep_trying do
|
|
299
|
-
if ::Morpheus::Cli::OptionTypes::confirm("Login
|
|
300
|
-
login_result = ::Morpheus::Cli::Login.new.handle(["
|
|
395
|
+
if ::Morpheus::Cli::OptionTypes::confirm("Login attempt failed. Would you like to try again?", options.merge({default: true}))
|
|
396
|
+
login_result = ::Morpheus::Cli::Login.new.handle(["-r", appliance[:name].to_s])
|
|
301
397
|
if login_result == 0
|
|
302
398
|
keep_trying = false
|
|
303
399
|
end
|
|
@@ -308,18 +404,16 @@ EOT
|
|
|
308
404
|
|
|
309
405
|
end
|
|
310
406
|
|
|
311
|
-
if !appliance[:active]
|
|
312
|
-
if ::Morpheus::Cli::OptionTypes::confirm("Would you like to switch to using this remote now?", options.merge({default: true}))
|
|
313
|
-
use([appliance[:name]])
|
|
314
|
-
end
|
|
315
|
-
end
|
|
316
|
-
|
|
317
407
|
else
|
|
318
408
|
#puts "Status is #{format_appliance_status(appliance)}"
|
|
319
409
|
end
|
|
320
410
|
|
|
321
411
|
# print new appliance details
|
|
322
|
-
|
|
412
|
+
print_h1 "Morpheus Appliance", [], options
|
|
413
|
+
print cyan
|
|
414
|
+
print format_remote_details(appliance, options)
|
|
415
|
+
print reset, "\n"
|
|
416
|
+
#_get(appliance[:name], {})
|
|
323
417
|
|
|
324
418
|
return exit_code, err
|
|
325
419
|
end
|
|
@@ -333,14 +427,14 @@ EOT
|
|
|
333
427
|
checkall = false
|
|
334
428
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
|
335
429
|
opts.banner = subcommand_usage("[name]")
|
|
336
|
-
build_common_options(opts, options, [:json, :yaml, :csv, :fields, :quiet
|
|
430
|
+
build_common_options(opts, options, [:json, :yaml, :csv, :fields, :quiet])
|
|
337
431
|
opts.on('-a', '--all', "Check all remotes.") do
|
|
338
432
|
checkall = true
|
|
339
433
|
end
|
|
340
434
|
opts.footer = <<-EOT
|
|
341
435
|
Check the status of a remote appliance.
|
|
342
436
|
[name] is optional. This is the name of a remote. Default is the current remote. Can be passed as 'all'. to perform remote check-all.
|
|
343
|
-
This makes a request to the
|
|
437
|
+
This makes a request to the remote url and updates the status and version.
|
|
344
438
|
EOT
|
|
345
439
|
end
|
|
346
440
|
optparse.parse!(args)
|
|
@@ -362,50 +456,133 @@ EOT
|
|
|
362
456
|
end
|
|
363
457
|
end
|
|
364
458
|
|
|
365
|
-
def
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
if !appliance
|
|
372
|
-
raise_command_error "No current appliance, see `remote use`."
|
|
373
|
-
end
|
|
374
|
-
appliance_name = appliance[:name]
|
|
375
|
-
else
|
|
376
|
-
appliance = ::Morpheus::Cli::Remote.load_remote(appliance_name)
|
|
377
|
-
if !appliance
|
|
378
|
-
raise_command_error "Remote not found by the name '#{appliance_name}'"
|
|
379
|
-
end
|
|
459
|
+
def version(args)
|
|
460
|
+
options = {}
|
|
461
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
|
462
|
+
opts.banner = subcommand_usage("[remote]")
|
|
463
|
+
opts.on('--offline', '--offline', "Do this offline without an api request to refresh the remote appliance status.") do
|
|
464
|
+
options[:do_offline] = true
|
|
380
465
|
end
|
|
466
|
+
build_common_options(opts, options, [:json, :yaml, :csv, :fields, :quiet])
|
|
467
|
+
opts.footer = <<-EOT
|
|
468
|
+
Print version of remote appliance.
|
|
469
|
+
[name] is optional. This is the name of a remote. Default is the current remote.
|
|
470
|
+
This makes a request to the configured appliance url and updates the status and version.
|
|
471
|
+
EOT
|
|
472
|
+
end
|
|
473
|
+
optparse.parse!(args)
|
|
474
|
+
verify_args!(args:args, max:1, optparse:optparse)
|
|
475
|
+
#connect(options)
|
|
476
|
+
# print version, default is current remote
|
|
477
|
+
appliance_name = nil
|
|
478
|
+
if args.count == 0
|
|
479
|
+
appliance_name = 'current'
|
|
480
|
+
elsif args.count == 1
|
|
481
|
+
appliance_name = args[0]
|
|
482
|
+
else
|
|
483
|
+
raise_command_error "No current appliance, see the command `remote use`"
|
|
484
|
+
end
|
|
485
|
+
exit_code, err = 0, nil
|
|
486
|
+
|
|
487
|
+
appliance = load_remote_by_name(appliance_name)
|
|
488
|
+
appliance_name = appliance[:name]
|
|
489
|
+
appliance_url = appliance[:url]
|
|
381
490
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
491
|
+
# found appliance, now refresh it
|
|
492
|
+
# print "Checking remote url: #{appliance[:url]} ..."
|
|
493
|
+
json_response = nil
|
|
494
|
+
if options[:do_offline] == true
|
|
495
|
+
json_response = {'appliance' => appliance}
|
|
496
|
+
else
|
|
497
|
+
appliance, json_response = ::Morpheus::Cli::Remote.refresh_remote(appliance_name)
|
|
498
|
+
end
|
|
390
499
|
|
|
391
|
-
|
|
500
|
+
# render
|
|
501
|
+
render_response(json_response, options) do
|
|
502
|
+
end
|
|
503
|
+
# if options[:json] || options[:yml] || options[:csv] || options[:quiet]
|
|
504
|
+
render_result = render_with_format(json_response, options)
|
|
505
|
+
return exit_code if render_result
|
|
392
506
|
|
|
393
|
-
|
|
507
|
+
build_version = appliance[:build_version]
|
|
508
|
+
if build_version
|
|
509
|
+
print cyan,build_version.to_s,reset,"\n"
|
|
510
|
+
return 0
|
|
511
|
+
else
|
|
512
|
+
print yellow,"version unknown".to_s,reset,"\n"
|
|
513
|
+
return 1
|
|
514
|
+
end
|
|
515
|
+
|
|
516
|
+
end
|
|
394
517
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
518
|
+
def check(args)
|
|
519
|
+
options = {}
|
|
520
|
+
checkall = false
|
|
521
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
|
522
|
+
opts.banner = subcommand_usage("[name]")
|
|
523
|
+
build_common_options(opts, options, [:json, :yaml, :csv, :fields, :quiet])
|
|
524
|
+
opts.on('-a', '--all', "Check all remotes.") do
|
|
525
|
+
checkall = true
|
|
526
|
+
end
|
|
527
|
+
opts.on('--offline', '--offline', "Do this offline without an api request to refresh the remote appliance status.") do
|
|
528
|
+
options[:do_offline] = true
|
|
400
529
|
end
|
|
530
|
+
opts.footer = <<-EOT
|
|
531
|
+
Check the status of a remote appliance.
|
|
532
|
+
[name] is optional. This is the name of a remote. Default is the current remote. Can be passed as 'all'. to perform remote check-all.
|
|
533
|
+
This makes a request to the configured appliance url and updates the status and version.
|
|
534
|
+
EOT
|
|
535
|
+
end
|
|
536
|
+
optparse.parse!(args)
|
|
537
|
+
if checkall == true
|
|
538
|
+
return _check_all_appliances(options)
|
|
539
|
+
end
|
|
540
|
+
if args.count == 0
|
|
541
|
+
id_list = ['current']
|
|
542
|
+
else
|
|
543
|
+
id_list = parse_id_list(args)
|
|
544
|
+
end
|
|
545
|
+
# trick for remote check all
|
|
546
|
+
if id_list.length == 1 && id_list[0].to_s.downcase == 'all'
|
|
547
|
+
return _check_all_appliances(options)
|
|
548
|
+
end
|
|
549
|
+
#connect(options)
|
|
550
|
+
return run_command_for_each_arg(id_list) do |arg|
|
|
551
|
+
_check_appliance(arg, options)
|
|
552
|
+
end
|
|
553
|
+
end
|
|
401
554
|
|
|
402
|
-
|
|
403
|
-
|
|
555
|
+
def _check_appliance(appliance_name, options)
|
|
556
|
+
exit_code, err = 0, nil
|
|
557
|
+
begin
|
|
558
|
+
appliance = load_remote_by_name(appliance_name)
|
|
559
|
+
appliance_name = appliance[:name]
|
|
560
|
+
appliance_url = appliance[:url]
|
|
404
561
|
|
|
405
|
-
|
|
562
|
+
# found appliance, now refresh it
|
|
563
|
+
|
|
564
|
+
if options[:do_offline]
|
|
565
|
+
json_response = {'appliance' => appliance} # mock payload
|
|
566
|
+
else
|
|
567
|
+
appliance, json_response = ::Morpheus::Cli::Remote.refresh_remote(appliance_name.to_sym)
|
|
568
|
+
json_response = {'appliance' => appliance} # mock payload
|
|
569
|
+
appliance, json_response = ::Morpheus::Cli::Remote.refresh_remote(appliance_name)
|
|
570
|
+
# json_response = {'appliance' => appliance} # mock payload
|
|
571
|
+
end
|
|
572
|
+
# appliance, json_response = ::Morpheus::Cli::Remote.refresh_remote(appliance_name)
|
|
406
573
|
|
|
407
|
-
|
|
574
|
+
if (appliance[:status] != 'ready' && appliance[:status] != 'fresh')
|
|
575
|
+
exit_code = 1
|
|
576
|
+
# err = appliance[:last_check] && appliance[:last_check][:error] ? appliance[:last_check][:error] : nil
|
|
577
|
+
end
|
|
408
578
|
|
|
579
|
+
render_response(json_response, options) do
|
|
580
|
+
print_h1 "Morpheus Appliance", [], options
|
|
581
|
+
print cyan
|
|
582
|
+
print format_remote_details(appliance, options)
|
|
583
|
+
print reset, "\n"
|
|
584
|
+
end
|
|
585
|
+
return exit_code, err
|
|
409
586
|
rescue RestClient::Exception => e
|
|
410
587
|
print_rest_exception(e, options)
|
|
411
588
|
exit 1
|
|
@@ -428,7 +605,7 @@ EOT
|
|
|
428
605
|
if args.count != 0
|
|
429
606
|
raise_command_error "wrong number of arguments, expected 0-1 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
|
|
430
607
|
end
|
|
431
|
-
connect() # needed?
|
|
608
|
+
connect(options) # needed?
|
|
432
609
|
_check_all_appliances(options)
|
|
433
610
|
end
|
|
434
611
|
|
|
@@ -438,16 +615,16 @@ EOT
|
|
|
438
615
|
id_list = ::Morpheus::Cli::Remote.appliances.keys # sort ?
|
|
439
616
|
if id_list.size > 1
|
|
440
617
|
print cyan
|
|
441
|
-
puts "Checking #{id_list.size}
|
|
618
|
+
puts "Checking #{id_list.size} remotes"
|
|
442
619
|
elsif id_list.size == 1
|
|
443
620
|
puts "Checking #{Morpheus::Cli::Remote.appliances.keys.first}"
|
|
444
621
|
end
|
|
445
622
|
id_list.each do |appliance_name|
|
|
446
623
|
#print "."
|
|
447
|
-
appliance,
|
|
624
|
+
appliance, json_response = ::Morpheus::Cli::Remote.refresh_remote(appliance_name)
|
|
448
625
|
end
|
|
449
626
|
took_sec = (Time.now - start_time)
|
|
450
|
-
print_green_success "Completed
|
|
627
|
+
print_green_success "Completed check of #{id_list.size} #{id_list.size == 1 ? 'remote' : 'remotes'} in #{format_duration_seconds(took_sec)}"
|
|
451
628
|
|
|
452
629
|
if options[:quiet]
|
|
453
630
|
return 0
|
|
@@ -457,8 +634,7 @@ EOT
|
|
|
457
634
|
end
|
|
458
635
|
|
|
459
636
|
def rename(args)
|
|
460
|
-
options = {}
|
|
461
|
-
params = {}
|
|
637
|
+
exit_code, err, options, params, payload = 0, nil, {}, {}, {}
|
|
462
638
|
use_it = false
|
|
463
639
|
is_insecure = nil
|
|
464
640
|
new_name = nil
|
|
@@ -466,11 +642,9 @@ EOT
|
|
|
466
642
|
opts.banner = subcommand_usage("[name] [new name]")
|
|
467
643
|
opts.on(nil, "--name NAME", "Update the name of your remote appliance") do |val|
|
|
468
644
|
new_name = val
|
|
469
|
-
end
|
|
470
|
-
|
|
645
|
+
end
|
|
471
646
|
# opts.on(nil, '--use', "Make this the current appliance" ) do
|
|
472
647
|
# use_it = true
|
|
473
|
-
# params[:active] = true
|
|
474
648
|
# end
|
|
475
649
|
build_common_options(opts, options, [:auto_confirm, :quiet])
|
|
476
650
|
opts.footer = <<-EOT
|
|
@@ -481,25 +655,20 @@ This changes your client configuration remote name, not the appliance itself.
|
|
|
481
655
|
EOT
|
|
482
656
|
end
|
|
483
657
|
optparse.parse!(args)
|
|
484
|
-
|
|
485
|
-
print_error Morpheus::Terminal.angry_prompt
|
|
486
|
-
puts_error "#{command_name} rename expects argument [name]."
|
|
487
|
-
puts_error optparse
|
|
488
|
-
return 1
|
|
489
|
-
end
|
|
658
|
+
verify_args!(args:args, count:2, optparse:optparse)
|
|
490
659
|
appliance_name = args[0].to_sym
|
|
491
660
|
new_appliance_name = args[1].to_sym
|
|
492
661
|
appliance = ::Morpheus::Cli::Remote.load_remote(appliance_name)
|
|
493
662
|
if !appliance
|
|
494
|
-
raise_command_error "Remote appliance not found by the name '#{appliance_name}'"
|
|
663
|
+
raise_command_error "Remote appliance not found by the name '#{appliance_name}', see the command `remote list`"
|
|
495
664
|
end
|
|
496
665
|
# don't allow overwrite yet
|
|
497
666
|
matching_appliance = ::Morpheus::Cli::Remote.load_remote(new_appliance_name)
|
|
498
667
|
if matching_appliance
|
|
499
|
-
raise_command_error "Remote appliance already exists with the name '#{new_appliance_name}'"
|
|
668
|
+
raise_command_error "Remote appliance already exists with the name '#{new_appliance_name}', see the command `, see the command `remote get #{new_appliance_name}`"
|
|
500
669
|
end
|
|
501
670
|
|
|
502
|
-
unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you
|
|
671
|
+
unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you want to rename remote '#{appliance_name}' to '#{new_appliance_name}'?", options)
|
|
503
672
|
return 9, "aborted command"
|
|
504
673
|
end
|
|
505
674
|
# this does all the work
|
|
@@ -508,22 +677,20 @@ EOT
|
|
|
508
677
|
print_green_success "Renamed remote #{appliance_name} to #{new_appliance_name}"
|
|
509
678
|
# todo: just go ahead and refresh it now...
|
|
510
679
|
# _check(appliance_name, {:quiet => true})
|
|
511
|
-
# appliance,
|
|
680
|
+
# appliance, json_response = ::Morpheus::Cli::Remote.refresh_remote(new_appliance_name)
|
|
512
681
|
# print new appliance details
|
|
513
682
|
_get(new_appliance_name, {})
|
|
514
683
|
return 0, nil
|
|
515
684
|
end
|
|
516
685
|
|
|
517
686
|
def update(args)
|
|
518
|
-
options = {}
|
|
519
|
-
params = {}
|
|
687
|
+
exit_code, err, options, params, payload = 0, nil, {}, {}, {}
|
|
520
688
|
use_it = false
|
|
521
689
|
is_insecure = nil
|
|
522
|
-
new_name = nil
|
|
523
690
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
|
524
691
|
opts.banner = subcommand_usage("[name]")
|
|
525
|
-
opts.on(
|
|
526
|
-
|
|
692
|
+
opts.on("--name NAME", String, "Update the name of your remote appliance") do |val|
|
|
693
|
+
params[:name] = val
|
|
527
694
|
end
|
|
528
695
|
opts.on("--url URL", String, "Update the url of your remote appliance") do |val|
|
|
529
696
|
params[:host] = val
|
|
@@ -542,18 +709,12 @@ EOT
|
|
|
542
709
|
opts.footer = "This can be used to update remote appliance settings.\n"
|
|
543
710
|
end
|
|
544
711
|
optparse.parse!(args)
|
|
545
|
-
|
|
546
|
-
print_error Morpheus::Terminal.angry_prompt
|
|
547
|
-
puts_error "#{command_name} update expects argument [name]."
|
|
548
|
-
puts_error optparse
|
|
549
|
-
return 1
|
|
550
|
-
end
|
|
712
|
+
verify_args!(args:args, count:1, optparse:optparse)
|
|
551
713
|
|
|
552
714
|
appliance_name = args[0].to_sym
|
|
553
|
-
appliance =
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
end
|
|
715
|
+
appliance = load_remote_by_name(appliance_name)
|
|
716
|
+
appliance_name = appliance[:name]
|
|
717
|
+
appliance_url = appliance[:url]
|
|
557
718
|
|
|
558
719
|
# params[:url] = args[1] if args[1]
|
|
559
720
|
|
|
@@ -574,34 +735,117 @@ EOT
|
|
|
574
735
|
end
|
|
575
736
|
|
|
576
737
|
::Morpheus::Cli::Remote.save_remote(appliance_name, appliance)
|
|
577
|
-
|
|
578
|
-
|
|
738
|
+
# rename_remote() should be inside save_remote()
|
|
739
|
+
if params[:name] && params[:name].to_s != appliance_name.to_s
|
|
740
|
+
::Morpheus::Cli::Remote.save_remote(appliance_name, appliance)
|
|
741
|
+
::Morpheus::Cli::Remote.rename_remote(appliance_name, params[:name])
|
|
742
|
+
print_green_success "Updated remote #{appliance_name} (renamed #{params[:name]})"
|
|
743
|
+
appliance_name = params[:name]
|
|
744
|
+
else
|
|
745
|
+
::Morpheus::Cli::Remote.save_remote(appliance_name, appliance)
|
|
746
|
+
print_green_success "Updated remote #{appliance_name}"
|
|
747
|
+
end
|
|
748
|
+
|
|
579
749
|
# todo: just go ahead and refresh it now...
|
|
580
750
|
# _check(appliance_name, {:quiet => true})
|
|
581
|
-
appliance,
|
|
751
|
+
appliance, json_response = ::Morpheus::Cli::Remote.refresh_remote(appliance_name)
|
|
582
752
|
# print new appliance details
|
|
583
753
|
_get(appliance[:name], {})
|
|
584
|
-
return
|
|
754
|
+
return exit_code, err
|
|
755
|
+
end
|
|
756
|
+
|
|
757
|
+
def clone(args)
|
|
758
|
+
exit_code, err, options, params, payload = 0, nil, {}, {}, {}
|
|
759
|
+
use_it = false
|
|
760
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
|
761
|
+
opts.banner = subcommand_usage("[remote] [name]")
|
|
762
|
+
# opts.on(nil, "--secure", "Prevent insecure HTTPS communication. This is enabled by default") do
|
|
763
|
+
# params[:secure] = true
|
|
764
|
+
# end
|
|
765
|
+
# opts.on(nil, "--insecure", "Allow insecure HTTPS communication. i.e. Ignore SSL errors.") do
|
|
766
|
+
# params[:insecure] = true
|
|
767
|
+
# end
|
|
768
|
+
opts.on(nil, '--use', "Make it the current appliance" ) do
|
|
769
|
+
use_it = true
|
|
770
|
+
params[:active] = true
|
|
771
|
+
end
|
|
772
|
+
build_common_options(opts, options, [:quiet])
|
|
773
|
+
opts.footer = <<-EOT
|
|
774
|
+
Clone remote appliance configuratio, including any existing credentials.
|
|
775
|
+
[remote] is required. This is the name of an existing remote.
|
|
776
|
+
[name] is optional. This is the name of the new remote that will be created.
|
|
777
|
+
EOT
|
|
778
|
+
end
|
|
779
|
+
optparse.parse!(args)
|
|
780
|
+
verify_args!(args:args, optparse:optparse, count:2)
|
|
781
|
+
|
|
782
|
+
|
|
783
|
+
appliance_name = args[0].to_sym
|
|
784
|
+
appliance = load_remote_by_name(appliance_name)
|
|
785
|
+
if !appliance
|
|
786
|
+
raise_command_error "Remote appliance not found by the name '#{appliance_name}', see the command `remote list`"
|
|
787
|
+
end
|
|
788
|
+
|
|
789
|
+
new_appliance_name = args[1].to_sym
|
|
790
|
+
matching_appliance = ::Morpheus::Cli::Remote.appliances[new_appliance_name.to_sym]
|
|
791
|
+
if matching_appliance
|
|
792
|
+
raise_command_error "Remote already exists with the name '#{matching_appliance[:name]}', see the command `remote get #{matching_appliance[:name]}`"
|
|
793
|
+
end
|
|
794
|
+
|
|
795
|
+
# ok clone it
|
|
796
|
+
original_appliance = appliance
|
|
797
|
+
appliance = original_appliance.clone
|
|
798
|
+
appliance[:name] = new_appliance_name
|
|
799
|
+
|
|
800
|
+
if params[:insecure]
|
|
801
|
+
appliance[:insecure] = true
|
|
802
|
+
elsif params[:secure]
|
|
803
|
+
appliance.delete(:insecure)
|
|
804
|
+
end
|
|
805
|
+
if params[:url] || params[:host]
|
|
806
|
+
appliance[:url] = params[:url] || params[:host]
|
|
807
|
+
# appliance.delete(:host)
|
|
808
|
+
end
|
|
809
|
+
if use_it
|
|
810
|
+
appliance[:active] = true
|
|
811
|
+
end
|
|
812
|
+
|
|
813
|
+
# save the new remote
|
|
814
|
+
::Morpheus::Cli::Remote.save_remote(appliance_name, appliance)
|
|
815
|
+
# refresh it now?
|
|
816
|
+
appliance, json_response = ::Morpheus::Cli::Remote.refresh_remote(new_appliance_name)
|
|
817
|
+
|
|
818
|
+
# render
|
|
819
|
+
if options[:quiet]
|
|
820
|
+
return exit_code, err
|
|
821
|
+
end
|
|
822
|
+
print_green_success "Cloned remote #{original_appliance[:name]} to #{appliance[:name]}"
|
|
823
|
+
# print new appliance details
|
|
824
|
+
_get(appliance[:name], {})
|
|
825
|
+
return exit_code, err
|
|
585
826
|
end
|
|
586
827
|
|
|
587
828
|
def get(args)
|
|
588
|
-
options = {}
|
|
829
|
+
exit_code, err, options, params, payload = 0, nil, {}, {}, {}
|
|
589
830
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
|
590
831
|
opts.banner = subcommand_usage("[name]")
|
|
591
832
|
opts.on( '-u', '--url', "Print only the url." ) do
|
|
592
833
|
options[:url_only] = true
|
|
593
834
|
end
|
|
594
|
-
|
|
835
|
+
opts.on('--offline', '--offline', "Do this offline without an api request to refresh the remote appliance status.") do
|
|
836
|
+
options[:do_offline] = true
|
|
837
|
+
end
|
|
838
|
+
build_common_options(opts, options, [:json,:yaml,:csv,:fields, :quiet])
|
|
595
839
|
end
|
|
596
840
|
optparse.parse!(args)
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
841
|
+
id_list = nil
|
|
842
|
+
# verify_args!(args:args, min:1, optparse:optparse)
|
|
843
|
+
if args.count == 0
|
|
844
|
+
id_list = ['current']
|
|
845
|
+
else
|
|
846
|
+
id_list = parse_id_list(args)
|
|
602
847
|
end
|
|
603
848
|
#connect(options)
|
|
604
|
-
id_list = parse_id_list(args)
|
|
605
849
|
return run_command_for_each_arg(id_list) do |arg|
|
|
606
850
|
_get(arg, options)
|
|
607
851
|
end
|
|
@@ -609,41 +853,23 @@ EOT
|
|
|
609
853
|
|
|
610
854
|
def _get(appliance_name, options)
|
|
611
855
|
exit_code, err = 0, nil
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
if !appliance
|
|
617
|
-
err = "No current appliance, see `remote use`."
|
|
618
|
-
exit_code = 1
|
|
619
|
-
end
|
|
620
|
-
appliance_name = appliance[:name]
|
|
621
|
-
else
|
|
622
|
-
appliance = ::Morpheus::Cli::Remote.load_remote(appliance_name)
|
|
623
|
-
if !appliance
|
|
624
|
-
err = "Remote appliance not found by the name '#{appliance_name}'"
|
|
625
|
-
exit_code = 1
|
|
626
|
-
end
|
|
627
|
-
end
|
|
628
|
-
|
|
629
|
-
if options[:quiet]
|
|
630
|
-
return exit_code, err
|
|
631
|
-
end
|
|
632
|
-
|
|
633
|
-
if options[:json]
|
|
634
|
-
json_response = {'appliance' => appliance} # mock payload
|
|
635
|
-
puts as_json(json_response, options, "appliance")
|
|
636
|
-
return exit_code, err
|
|
637
|
-
end
|
|
638
|
-
|
|
639
|
-
if options[:yaml]
|
|
640
|
-
json_response = {'appliance' => appliance} # mock payload
|
|
641
|
-
puts as_yaml(json_response, options, "appliance")
|
|
642
|
-
return exit_code, err
|
|
643
|
-
end
|
|
856
|
+
|
|
857
|
+
appliance = load_remote_by_name(appliance_name)
|
|
858
|
+
appliance_name = appliance[:name]
|
|
859
|
+
appliance_url = appliance[:url]
|
|
644
860
|
|
|
645
|
-
|
|
861
|
+
# refresh remote status and version by default
|
|
862
|
+
# should json just be appliance instead maybe?
|
|
863
|
+
json_response = nil
|
|
864
|
+
if options[:do_offline]
|
|
865
|
+
json_response = {'appliance' => appliance} # mock payload
|
|
866
|
+
else
|
|
867
|
+
appliance, json_response = ::Morpheus::Cli::Remote.refresh_remote(appliance_name.to_sym)
|
|
868
|
+
json_response = {'appliance' => appliance} # mock payload
|
|
869
|
+
end
|
|
646
870
|
|
|
871
|
+
# render
|
|
872
|
+
render_response(json_response, options) do
|
|
647
873
|
if options[:url_only]
|
|
648
874
|
if appliance
|
|
649
875
|
print cyan, (appliance[:url] || appliance[:host]),"\n",reset
|
|
@@ -653,100 +879,113 @@ EOT
|
|
|
653
879
|
return exit_code, err
|
|
654
880
|
end
|
|
655
881
|
end
|
|
656
|
-
|
|
657
882
|
if exit_code != 0
|
|
658
883
|
print_error red, err,"\n",reset
|
|
659
884
|
return exit_code, err
|
|
660
885
|
end
|
|
661
886
|
|
|
662
|
-
|
|
663
|
-
# print_h1 "Current Remote Appliance: #{appliance[:name]}"
|
|
664
|
-
print_h1 "Morpheus Appliance", [], options
|
|
665
|
-
else
|
|
666
|
-
print_h1 "Morpheus Appliance", [], options
|
|
667
|
-
end
|
|
668
|
-
print cyan
|
|
669
|
-
description_cols = {
|
|
670
|
-
"Name" => :name,
|
|
671
|
-
"URL" => :host,
|
|
672
|
-
"Secure" => lambda {|it| format_appliance_secure(it) },
|
|
673
|
-
"Version" => lambda {|it| it[:build_version] ? "#{it[:build_version]}" : 'unknown' },
|
|
674
|
-
"Status" => lambda {|it| format_appliance_status(it, cyan) },
|
|
675
|
-
"Username" => :username,
|
|
676
|
-
# "Authenticated" => lambda {|it| format_boolean it[:authenticated] },
|
|
677
|
-
# todo: fix this layout, obv
|
|
678
|
-
"Activity" => lambda {|it| get_appliance_session_blurbs(it).join("\n" + (' '*10)) }
|
|
679
|
-
}
|
|
887
|
+
print_h1 "Morpheus Appliance", [], options
|
|
680
888
|
print cyan
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
# if appliance[:insecure]
|
|
684
|
-
# puts " Ignore SSL Errors: Yes"
|
|
685
|
-
# else
|
|
686
|
-
# puts " Ignore SSL Errors: No"
|
|
687
|
-
# end
|
|
688
|
-
|
|
689
|
-
if appliance[:active]
|
|
690
|
-
# print cyan
|
|
691
|
-
print cyan, "# => #{appliance[:name]} is the current remote appliance.", reset, "\n\n"
|
|
692
|
-
end
|
|
693
|
-
|
|
694
|
-
return 0
|
|
695
|
-
rescue RestClient::Exception => e
|
|
696
|
-
print_rest_exception(e, options)
|
|
697
|
-
exit 1
|
|
889
|
+
print format_remote_details(appliance, options)
|
|
890
|
+
print reset, "\n"
|
|
698
891
|
end
|
|
892
|
+
return exit_code, err
|
|
893
|
+
|
|
699
894
|
end
|
|
700
895
|
|
|
701
|
-
def
|
|
896
|
+
def view(args)
|
|
702
897
|
options = {}
|
|
898
|
+
path = "/"
|
|
899
|
+
no_auth = false
|
|
703
900
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
|
704
901
|
opts.banner = subcommand_usage("[name]")
|
|
705
|
-
|
|
902
|
+
opts.on('--path PATH', String, "Specify a path to load. eg '/logs'" ) do |val|
|
|
903
|
+
path = val
|
|
904
|
+
end
|
|
905
|
+
opts.on('--no-auth PATH', String, "Do not attempt to login with access token." ) do |val|
|
|
906
|
+
no_auth = true
|
|
907
|
+
end
|
|
908
|
+
build_common_options(opts, options, [:dry_run])
|
|
706
909
|
opts.footer = <<-EOT
|
|
707
|
-
|
|
708
|
-
[name] is
|
|
910
|
+
View remote appliance in a web browser.
|
|
911
|
+
[name] is optional. This is the name of a remote. Default is the current remote.
|
|
912
|
+
This will automatically login with the current access token.
|
|
709
913
|
EOT
|
|
710
914
|
end
|
|
711
915
|
optparse.parse!(args)
|
|
916
|
+
# verify_args!(args:args, optparse:optparse)
|
|
712
917
|
if args.count == 0
|
|
713
|
-
|
|
714
|
-
raise_command_error "wrong number of arguments, expected 1-N and got 0\n#{optparse}"
|
|
918
|
+
id_list = ['current']
|
|
919
|
+
#raise_command_error "wrong number of arguments, expected 1-N and got 0\n#{optparse}"
|
|
715
920
|
else
|
|
716
921
|
id_list = parse_id_list(args)
|
|
717
922
|
end
|
|
718
923
|
#connect(options)
|
|
719
|
-
unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like to delete #{id_list.size == 1 ? 'remote' : 'remotes'}: #{anded_list(id_list)}?", options)
|
|
720
|
-
return 9, "aborted command"
|
|
721
|
-
end
|
|
722
924
|
return run_command_for_each_arg(id_list) do |arg|
|
|
723
|
-
|
|
925
|
+
_view_appliance(arg, path, no_auth, options)
|
|
724
926
|
end
|
|
725
927
|
end
|
|
726
928
|
|
|
727
|
-
def
|
|
728
|
-
|
|
729
|
-
appliance_name =
|
|
730
|
-
|
|
731
|
-
if
|
|
732
|
-
raise_command_error "Remote appliance not
|
|
929
|
+
def _view_appliance(appliance_name, path, no_auth, options)
|
|
930
|
+
appliance = load_remote_by_name(appliance_name)
|
|
931
|
+
appliance_name = appliance[:name]
|
|
932
|
+
appliance_url = appliance[:url]
|
|
933
|
+
if appliance_url.to_s.empty?
|
|
934
|
+
raise_command_error "Remote appliance does not have a url?"
|
|
935
|
+
end
|
|
936
|
+
path = path.to_s.empty? ? "/" : path
|
|
937
|
+
if path[0].chr != "/"
|
|
938
|
+
path = "/#{path}"
|
|
939
|
+
end
|
|
940
|
+
wallet = ::Morpheus::Cli::Credentials.new(appliance_name, nil).load_saved_credentials()
|
|
941
|
+
# try to auto login if we have a token
|
|
942
|
+
link = "#{appliance_url}#{path}"
|
|
943
|
+
if no_auth == false
|
|
944
|
+
if wallet && wallet['access_token']
|
|
945
|
+
link = "#{appliance_url}/login/oauth-redirect?access_token=#{wallet['access_token']}\\&redirectUri=#{path}"
|
|
946
|
+
end
|
|
733
947
|
end
|
|
734
|
-
|
|
735
948
|
|
|
736
|
-
|
|
949
|
+
if options[:dry_run]
|
|
950
|
+
puts Morpheus::Util.open_url_command(link)
|
|
951
|
+
return 0
|
|
952
|
+
end
|
|
953
|
+
return Morpheus::Util.open_url(link)
|
|
954
|
+
end
|
|
737
955
|
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
956
|
+
def remove(args)
|
|
957
|
+
options = {}
|
|
958
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
|
959
|
+
opts.banner = subcommand_usage("[name]")
|
|
960
|
+
build_common_options(opts, options, [:auto_confirm, :quiet])
|
|
961
|
+
opts.footer = <<-EOT
|
|
962
|
+
This will delete the specified remote appliance(s) from your local configuration.
|
|
963
|
+
[name] is required. This is the name of a remote. More than one can be passed.
|
|
964
|
+
EOT
|
|
965
|
+
end
|
|
966
|
+
optparse.parse!(args)
|
|
967
|
+
verify_args!(args:args, min:1, optparse:optparse)
|
|
968
|
+
id_list = parse_id_list(args)
|
|
969
|
+
#connect(options)
|
|
970
|
+
# verify they all exist first, this a cheap lookup and raises and error if not found
|
|
971
|
+
id_list.each do |remote_id|
|
|
972
|
+
found_remote = load_remote_by_name(remote_id)
|
|
973
|
+
return 1, "Remote appliance not found by the name '#{remote_id}', see the command `remote list`" if found_remote.nil?
|
|
974
|
+
end
|
|
975
|
+
unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like to delete #{id_list.size == 1 ? 'remote' : id_list.size.to_s + ' remotes'}: #{anded_list(id_list)}?", options)
|
|
976
|
+
return 9, "aborted command"
|
|
977
|
+
end
|
|
978
|
+
return run_command_for_each_arg(id_list) do |arg|
|
|
979
|
+
_remove_appliance(arg, options)
|
|
744
980
|
end
|
|
981
|
+
end
|
|
745
982
|
|
|
983
|
+
def _remove_appliance(appliance_name, options)
|
|
984
|
+
if ::Morpheus::Cli::Remote.appliances[appliance_name.to_sym].nil?
|
|
985
|
+
raise_command_error "Remote does not exist with name '#{appliance_name.to_s}'"
|
|
986
|
+
end
|
|
746
987
|
# ok, delete it
|
|
747
|
-
|
|
748
988
|
::Morpheus::Cli::Remote.delete_remote(appliance_name)
|
|
749
|
-
|
|
750
989
|
# return result
|
|
751
990
|
if options[:quiet]
|
|
752
991
|
return 0
|
|
@@ -756,29 +995,94 @@ EOT
|
|
|
756
995
|
return 0
|
|
757
996
|
end
|
|
758
997
|
|
|
998
|
+
def remove_all(args)
|
|
999
|
+
options = {}
|
|
1000
|
+
checkall = false
|
|
1001
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
|
1002
|
+
opts.banner = subcommand_usage()
|
|
1003
|
+
build_common_options(opts, options, [:auto_confirm, :quiet])
|
|
1004
|
+
opts.footer = <<-EOT
|
|
1005
|
+
Remove all remote appliances, clearing the client configuration.
|
|
1006
|
+
This clears all the configured remotes and credentials.
|
|
1007
|
+
EOT
|
|
1008
|
+
end
|
|
1009
|
+
optparse.parse!(args)
|
|
1010
|
+
verify_args!(args:args, count:0, optparse:optparse)
|
|
1011
|
+
connect(options) # needed?
|
|
1012
|
+
_remove_all_appliances(options)
|
|
1013
|
+
end
|
|
1014
|
+
|
|
1015
|
+
def _remove_all_appliances(options)
|
|
1016
|
+
exit_code, err = 0, nil
|
|
1017
|
+
all_appliance_names = ::Morpheus::Cli::Remote.appliances.keys.size
|
|
1018
|
+
if all_appliance_names.empty?
|
|
1019
|
+
if options[:quiet] != true
|
|
1020
|
+
print_green_success "No remotes found, nothing to remove"
|
|
1021
|
+
return 0, nil
|
|
1022
|
+
end
|
|
1023
|
+
end
|
|
1024
|
+
unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you want to remove all of your remotes (#{all_appliance_names.size})?", options)
|
|
1025
|
+
return 9, "aborted command"
|
|
1026
|
+
end
|
|
1027
|
+
# ok, do it
|
|
1028
|
+
deleted_list = ::Morpheus::Cli::Remote.delete_all_remotes()
|
|
1029
|
+
|
|
1030
|
+
# render
|
|
1031
|
+
if options[:quiet]
|
|
1032
|
+
return exit_code, err
|
|
1033
|
+
end
|
|
1034
|
+
if all_appliance_names.size == 1
|
|
1035
|
+
print_green_success "Removed 1 remote (#{all_appliance_names.join(', ')})"
|
|
1036
|
+
else
|
|
1037
|
+
print_green_success "Removed 1 remote () "
|
|
1038
|
+
end
|
|
1039
|
+
#list([])
|
|
1040
|
+
return exit_code, err
|
|
1041
|
+
end
|
|
1042
|
+
|
|
759
1043
|
def use(args)
|
|
760
1044
|
options = {}
|
|
761
1045
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
|
762
1046
|
opts.banner = subcommand_usage("[name]")
|
|
1047
|
+
opts.on('--offline', '--offline', "Do this offline without an api request to refresh the remote appliance status.") do
|
|
1048
|
+
options[:do_offline] = true
|
|
1049
|
+
end
|
|
763
1050
|
build_common_options(opts, options, [:quiet])
|
|
764
|
-
opts.footer =
|
|
765
|
-
|
|
766
|
-
|
|
1051
|
+
opts.footer = <<-EOT
|
|
1052
|
+
[name] is required. This is the name of a remote, see the command `remote list`.
|
|
1053
|
+
Start using a remote, making it the active (current) remote appliance.
|
|
1054
|
+
This switches the remote context of your client configuration for all subsequent commands.
|
|
1055
|
+
So rely on 'remote use' with caution.
|
|
1056
|
+
It is important to always be aware of the context your commands are running in.
|
|
1057
|
+
The command `remote current` will return the current remote information.
|
|
1058
|
+
Also, instead of using an active remote, the -r option can be specified in your commands.
|
|
1059
|
+
|
|
1060
|
+
It is recommeneded to set a custom prompt to show the remote name.
|
|
1061
|
+
For example, add the following to your .morpheusrc file:
|
|
1062
|
+
|
|
1063
|
+
# set your shell prompt to display the current username and remote
|
|
1064
|
+
set-prompt "%green%username%reset@%magenta%remote %cyanmorpheus> %reset"
|
|
1065
|
+
|
|
1066
|
+
EOT
|
|
767
1067
|
end
|
|
768
1068
|
optparse.parse!(args)
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
appliance_name = args[0].to_sym
|
|
777
|
-
appliance = ::Morpheus::Cli::Remote.load_remote(appliance_name)
|
|
778
|
-
if !appliance
|
|
779
|
-
raise_command_error "Remote appliance not found by the name '#{appliance_name}'"
|
|
1069
|
+
verify_args!(args:args, count:1, optparse:optparse)
|
|
1070
|
+
exit_code, err = 0, nil
|
|
1071
|
+
# connect()
|
|
1072
|
+
current_appliance_name, current_appliance_url = @appliance_name, @appliance_url
|
|
1073
|
+
current_appliance = ::Morpheus::Cli::Remote.load_active_remote()
|
|
1074
|
+
if current_appliance
|
|
1075
|
+
current_appliance_name, current_appliance_url = current_appliance[:name], current_appliance[:url]
|
|
780
1076
|
end
|
|
781
1077
|
|
|
1078
|
+
# current_appliance_name, current_appliance_url = @appliance_name, @appliance_url
|
|
1079
|
+
appliance_name = args[0].to_sym
|
|
1080
|
+
appliance = load_remote_by_name(appliance_name)
|
|
1081
|
+
# appliance = ::Morpheus::Cli::Remote.load_remote(appliance_name)
|
|
1082
|
+
# if !appliance
|
|
1083
|
+
# raise_command_error "Remote not found by the name '#{appliance_name}', see the command `remote list`"
|
|
1084
|
+
# end
|
|
1085
|
+
|
|
782
1086
|
# appliance = ::Morpheus::Cli::Remote.set_active_appliance(appliance_name)
|
|
783
1087
|
appliance[:active] = true
|
|
784
1088
|
appliance = ::Morpheus::Cli::Remote.save_remote(appliance_name, appliance)
|
|
@@ -788,15 +1092,25 @@ EOT
|
|
|
788
1092
|
end
|
|
789
1093
|
|
|
790
1094
|
if current_appliance_name.to_s == appliance_name.to_s
|
|
791
|
-
|
|
1095
|
+
print_green_success "Using remote #{display_appliance(appliance[:name], appliance[:url])}"
|
|
792
1096
|
else
|
|
793
|
-
|
|
1097
|
+
print_green_success "Using remote #{display_appliance(appliance[:name], appliance[:url])}"
|
|
794
1098
|
end
|
|
795
1099
|
|
|
796
1100
|
# recalculate session variables
|
|
797
1101
|
::Morpheus::Cli::Remote.recalculate_variable_map()
|
|
798
1102
|
|
|
799
|
-
|
|
1103
|
+
# could just do this
|
|
1104
|
+
# return _get(appliance_name, options)
|
|
1105
|
+
|
|
1106
|
+
# ok need to refresh here unless --offline
|
|
1107
|
+
# refresh status and version
|
|
1108
|
+
# maybe just make json_response = appliance here
|
|
1109
|
+
unless options[:do_offline]
|
|
1110
|
+
appliance, json_response = ::Morpheus::Cli::Remote.refresh_remote(appliance[:name])
|
|
1111
|
+
end
|
|
1112
|
+
# return list([])
|
|
1113
|
+
return exit_code, err
|
|
800
1114
|
end
|
|
801
1115
|
|
|
802
1116
|
def unuse(args)
|
|
@@ -804,30 +1118,31 @@ EOT
|
|
|
804
1118
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
|
805
1119
|
opts.banner = subcommand_usage()
|
|
806
1120
|
opts.footer = "" +
|
|
807
|
-
"
|
|
1121
|
+
"Stop using the current remote appliance.\n"
|
|
808
1122
|
build_common_options(opts, options, [])
|
|
809
1123
|
end
|
|
810
1124
|
optparse.parse!(args)
|
|
811
|
-
|
|
812
|
-
raise_command_error "wrong number of arguments, expected 0-1 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
|
|
813
|
-
end
|
|
1125
|
+
verify_args!(args:args, count:0, optparse:optparse)
|
|
814
1126
|
#connect(options)
|
|
1127
|
+
exit_code, err = 0, nil
|
|
815
1128
|
@appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
|
|
816
1129
|
if !@appliance_name
|
|
817
|
-
print
|
|
1130
|
+
print reset,"You are not using any remote appliance",reset,"\n"
|
|
818
1131
|
return 0
|
|
819
1132
|
end
|
|
820
1133
|
Morpheus::Cli::Remote.clear_active_appliance()
|
|
821
|
-
|
|
1134
|
+
print_green_success "Stopped using remote #{display_appliance(@appliance_name, @appliance_url)}"
|
|
822
1135
|
# recalculate session variables
|
|
823
1136
|
::Morpheus::Cli::Remote.recalculate_variable_map()
|
|
824
|
-
return
|
|
1137
|
+
# return list([])
|
|
1138
|
+
return exit_code, err
|
|
825
1139
|
end
|
|
826
1140
|
|
|
827
1141
|
def current(args)
|
|
828
1142
|
options = {}
|
|
829
1143
|
name_only = false
|
|
830
1144
|
url_only = false
|
|
1145
|
+
version_only = false
|
|
831
1146
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
|
832
1147
|
opts.banner = subcommand_usage()
|
|
833
1148
|
opts.on( '-n', '--name', "Print only the name." ) do
|
|
@@ -836,561 +1151,171 @@ EOT
|
|
|
836
1151
|
opts.on( '-u', '--url', "Print only the url." ) do
|
|
837
1152
|
url_only = true
|
|
838
1153
|
end
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
"The default behavior is the same as 'remote get current'."
|
|
842
|
-
end
|
|
843
|
-
optparse.parse!(args)
|
|
844
|
-
if args.count != 0
|
|
845
|
-
raise_command_error "wrong number of arguments, expected 0 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
|
|
846
|
-
end
|
|
847
|
-
connect(options)
|
|
848
|
-
# if !@appliance_name
|
|
849
|
-
# print yellow, "No current appliance, see `remote use`\n", reset
|
|
850
|
-
# return 1
|
|
851
|
-
# end
|
|
852
|
-
#connect(options)
|
|
853
|
-
if name_only
|
|
854
|
-
print cyan, @appliance_name,"\n",reset
|
|
855
|
-
return 0
|
|
856
|
-
elsif url_only
|
|
857
|
-
print cyan, @appliance_url,"\n",reset
|
|
858
|
-
return 0
|
|
859
|
-
else
|
|
860
|
-
return _get("current", options)
|
|
861
|
-
end
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
end
|
|
865
|
-
|
|
866
|
-
# this is a wizard that walks through the /api/setup controller
|
|
867
|
-
# it only needs to be used once to initialize a new appliance
|
|
868
|
-
def setup(args)
|
|
869
|
-
options = {}
|
|
870
|
-
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
|
871
|
-
opts.banner = subcommand_usage()
|
|
872
|
-
build_common_options(opts, options, [:payload, :options, :json, :dry_run, :quiet, :remote])
|
|
873
|
-
opts.on('--hubmode MODE','--hubmode MODE', "Choose an option for hub registration possible values are login, register, skip.") do |val|
|
|
874
|
-
options[:hubmode] = val.to_s.downcase
|
|
1154
|
+
opts.on( '-v', '--version', "Print only the build version." ) do
|
|
1155
|
+
version_only = true
|
|
875
1156
|
end
|
|
876
|
-
opts.
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
1157
|
+
opts.on('--offline', '--offline', "Do this offline without an api request to refresh the remote appliance status.") do
|
|
1158
|
+
options[:do_offline] = true
|
|
1159
|
+
end
|
|
1160
|
+
build_common_options(opts, options, [:json,:yaml,:csv,:fields, :quiet])
|
|
1161
|
+
opts.footer = <<-EOT
|
|
1162
|
+
Print details about the current remote appliance.
|
|
1163
|
+
This behaves the same as `remote get current`.
|
|
1164
|
+
EOT
|
|
881
1165
|
end
|
|
882
1166
|
optparse.parse!(args)
|
|
883
|
-
|
|
884
|
-
# first arg as remote name otherwise the active appliance is connected to
|
|
885
|
-
if args.count > 1
|
|
886
|
-
raise_command_error "wrong number of arguments, expected 0-1 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
|
|
887
|
-
end
|
|
888
|
-
if args[0]
|
|
889
|
-
options[:remote] = args[0]
|
|
890
|
-
end
|
|
1167
|
+
verify_args!(args:args, count:0, optparse:optparse)
|
|
891
1168
|
connect(options)
|
|
892
1169
|
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
1170
|
+
# this does the same thing
|
|
1171
|
+
#return _get("current", options)
|
|
1172
|
+
|
|
1173
|
+
# appliance = load_remote_by_name("current")
|
|
1174
|
+
appliance = @remote_appliance
|
|
1175
|
+
exit_code, err = 0, nil
|
|
1176
|
+
if appliance.nil?
|
|
1177
|
+
raise_command_error "no current remote appliance, see command `remote add`."
|
|
896
1178
|
end
|
|
897
1179
|
|
|
898
|
-
#
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
1180
|
+
# ok need to refresh here unless do_offline
|
|
1181
|
+
# refresh status and version
|
|
1182
|
+
# maybe just make json_response = appliance here
|
|
1183
|
+
json_response = nil
|
|
1184
|
+
if options[:do_offline]
|
|
1185
|
+
json_response = {'appliance' => appliance} # mock payload
|
|
902
1186
|
else
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
rescue RestClient::Exception => e
|
|
920
|
-
print_rest_exception(e, options)
|
|
921
|
-
return false
|
|
922
|
-
end
|
|
923
|
-
|
|
924
|
-
# retrieved hub.enabled and hub.url
|
|
925
|
-
hub_settings = appliance_status_json['hubSettings'] || appliance_status_json['hub'] || {}
|
|
926
|
-
|
|
927
|
-
# store login/registration info in here, for prompt default values
|
|
928
|
-
hub_info = nil
|
|
929
|
-
print cyan
|
|
930
|
-
print_h2 "Remote Setup: #{@appliance_name} - #{@appliance_url}"
|
|
931
|
-
|
|
932
|
-
print cyan
|
|
933
|
-
puts "Welcome to the setup of your new Morpheus Appliance #{@appliance_name} @ #{@appliance_url}"
|
|
934
|
-
puts "It looks like you're the first here, so let's begin."
|
|
935
|
-
|
|
936
|
-
hubmode = nil
|
|
937
|
-
hub_init_payload = nil # gets included as payload for hub scoped like hub.email
|
|
938
|
-
if hub_settings['enabled']
|
|
939
|
-
|
|
940
|
-
# Hub Registration
|
|
941
|
-
hub_action_dropdown = [
|
|
942
|
-
{'name' => 'Login to existing hub account', 'value' => 'login', 'isDefault' => true},
|
|
943
|
-
{'name' => 'Register a new hub account', 'value' => 'register'},
|
|
944
|
-
{'name' => 'Skip this step and manually install a license later.', 'value' => 'skip'},
|
|
945
|
-
{'name' => 'Abort', 'value' => 'abort'}
|
|
946
|
-
]
|
|
947
|
-
|
|
948
|
-
|
|
1187
|
+
appliance, json_response = ::Morpheus::Cli::Remote.refresh_remote(appliance[:name])
|
|
1188
|
+
json_response = {'appliance' => appliance} # mock payload
|
|
1189
|
+
end
|
|
1190
|
+
# could set exit_code if appliance[:build_version].nil?
|
|
1191
|
+
render_response(json_response, options) do
|
|
1192
|
+
if name_only && url_only
|
|
1193
|
+
#print cyan, display_appliance(appliance[:name], appliance[:url]),"\n",reset
|
|
1194
|
+
print cyan, appliance[:name], " ", appliance[:url],"\n",reset
|
|
1195
|
+
elsif name_only
|
|
1196
|
+
print cyan, appliance[:name],"\n",reset
|
|
1197
|
+
elsif url_only
|
|
1198
|
+
print cyan, appliance[:url],"\n",reset
|
|
1199
|
+
elsif version_only
|
|
1200
|
+
print cyan, appliance[:build_version],"\n",reset
|
|
1201
|
+
else
|
|
1202
|
+
print_h1 "Morpheus Appliance", [], options
|
|
949
1203
|
print cyan
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
puts "This is done to retrieve and install the license key for your appliance."
|
|
953
|
-
puts "You have several options for how to proceed:"
|
|
954
|
-
hub_action_dropdown.each_with_index do |hub_action, idx|
|
|
955
|
-
puts "#{idx+1}. #{hub_action['name']} [#{hub_action['value']}]"
|
|
956
|
-
end
|
|
957
|
-
print "\n", reset
|
|
958
|
-
|
|
959
|
-
while hubmode == nil do
|
|
960
|
-
|
|
961
|
-
options[:options]['hubmode'] = options[:hubmode] if options.key?(:hubmode)
|
|
962
|
-
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'hubmode', 'fieldLabel' => 'Choose Hub Mode', 'type' => 'select', 'selectOptions' => hub_action_dropdown, 'required' => true, 'defaultValue' => 'login'}], options[:options])
|
|
963
|
-
hubmode = v_prompt['hubmode']
|
|
964
|
-
|
|
965
|
-
if hubmode == 'login'
|
|
966
|
-
|
|
967
|
-
# print cyan
|
|
968
|
-
# puts "MORPHEUS HUB #{hub_settings['url']}"
|
|
969
|
-
# puts "The Command Center for DevOps"
|
|
970
|
-
# print reset
|
|
971
|
-
|
|
972
|
-
# Hub Login
|
|
973
|
-
print_h2 "Morpheus Hub Login @ #{hub_settings['url']}", options
|
|
974
|
-
hub_login_option_types = [
|
|
975
|
-
{'fieldContext' => 'hub', 'fieldName' => 'email', 'fieldLabel' => 'Email', 'type' => 'text', 'required' => true, 'description' => 'Email Address of existing Morpheus Hub user to link with.'},
|
|
976
|
-
{'fieldContext' => 'hub', 'fieldName' => 'password', 'fieldLabel' => 'Password', 'type' => 'password', 'required' => true, 'description' => 'Password of existing Morpheus Hub user.'},
|
|
977
|
-
]
|
|
978
|
-
v_prompt = Morpheus::Cli::OptionTypes.prompt(hub_login_option_types, options[:options])
|
|
979
|
-
hub_login_payload = v_prompt['hub']
|
|
980
|
-
hub_login_response = nil
|
|
981
|
-
begin
|
|
982
|
-
hub_login_response = @setup_interface.hub_login(hub_login_payload)
|
|
983
|
-
hub_init_payload = hub_login_payload
|
|
984
|
-
hub_info = {'email' => hub_login_payload['email'], 'password' => hub_login_payload['password'] }
|
|
985
|
-
hub_info.deep_merge!(hub_login_response['data']['info']) if (hub_login_response['data'] && hub_login_response['data']['info'])
|
|
986
|
-
hub_info.deep_merge!(hub_login_response['hub']) if hub_login_response['hub'].is_a?(Hash)
|
|
987
|
-
print_green_success "Logged into Morpheus Hub as #{hub_info['email']}"
|
|
988
|
-
rescue RestClient::Exception => e
|
|
989
|
-
hub_login_response = parse_rest_exception(e)
|
|
990
|
-
error_msg = hub_login_response["msg"] || "Hub login failed."
|
|
991
|
-
print_error red,error_msg,reset,"\n"
|
|
992
|
-
hubmode = nil
|
|
993
|
-
#print_rest_exception(e, options)
|
|
994
|
-
#exit 1
|
|
995
|
-
end
|
|
996
|
-
|
|
997
|
-
# DEBUG
|
|
998
|
-
if options[:debug] && hub_login_response
|
|
999
|
-
print_h2 "JSON response for hub login"
|
|
1000
|
-
Morpheus::Logging::DarkPrinter.puts as_json(hub_login_response)
|
|
1001
|
-
end
|
|
1002
|
-
|
|
1003
|
-
elsif hubmode == 'register'
|
|
1004
|
-
# Hub Registration
|
|
1005
|
-
print_h2 "Morpheus Hub Registration", options
|
|
1006
|
-
hub_register_option_types = [
|
|
1007
|
-
{'fieldContext' => 'hub', 'fieldName' => 'companyName', 'fieldLabel' => 'Company Name', 'type' => 'text', 'required' => true, 'description' => 'Company Name of new Morpheus Hub account to be created.'},
|
|
1008
|
-
{'fieldContext' => 'hub', 'fieldName' => 'firstName', 'fieldLabel' => 'First Name', 'type' => 'text', 'required' => true, 'description' => 'First Name of new Morpheus Hub user.'},
|
|
1009
|
-
{'fieldContext' => 'hub', 'fieldName' => 'lastName', 'fieldLabel' => 'Last Name', 'type' => 'text', 'required' => true, 'description' => 'Last Name of new Morpheus Hub user.'},
|
|
1010
|
-
{'fieldContext' => 'hub', 'fieldName' => 'email', 'fieldLabel' => 'Email', 'type' => 'text', 'required' => true, 'description' => 'Email Address of new Morpheus Hub user.'}
|
|
1011
|
-
]
|
|
1012
|
-
v_prompt = Morpheus::Cli::OptionTypes.prompt(hub_register_option_types, options[:options])
|
|
1013
|
-
hub_register_payload = v_prompt['hub']
|
|
1014
|
-
|
|
1015
|
-
# Password prompt with re-prompting if no match
|
|
1016
|
-
need_password = true
|
|
1017
|
-
if options[:no_prompt]
|
|
1018
|
-
if options[:options]['hub'] && options[:options]['hub']['password']
|
|
1019
|
-
options[:options]['hub']['confirmPassword'] = options[:options]['hub']['password']
|
|
1020
|
-
end
|
|
1021
|
-
end
|
|
1022
|
-
while need_password do
|
|
1023
|
-
password_option_types = [
|
|
1024
|
-
{'fieldContext' => 'hub', 'fieldName' => 'password', 'fieldLabel' => 'Create Password', 'type' => 'password', 'required' => true, 'description' => 'Confirm password of new Morpheus Hub user.'},
|
|
1025
|
-
{'fieldContext' => 'hub', 'fieldName' => 'confirmPassword', 'fieldLabel' => 'Confirm Password', 'type' => 'password', 'required' => true, 'description' => 'Confirm password of new Morpheus Hub user.'}
|
|
1026
|
-
]
|
|
1027
|
-
v_prompt = Morpheus::Cli::OptionTypes.prompt(password_option_types, options[:options])
|
|
1028
|
-
if v_prompt['hub']['password'] == v_prompt['hub']['confirmPassword']
|
|
1029
|
-
hub_register_payload.deep_merge!(v_prompt['hub'])
|
|
1030
|
-
need_password = false
|
|
1031
|
-
else
|
|
1032
|
-
print_error red, "Password confirmation does not match. Re-enter your new password.", reset, "\n"
|
|
1033
|
-
end
|
|
1034
|
-
end
|
|
1035
|
-
|
|
1036
|
-
begin
|
|
1037
|
-
hub_register_response = @setup_interface.hub_register(hub_register_payload)
|
|
1038
|
-
hub_init_payload = hub_register_payload
|
|
1039
|
-
hub_info = {'email' => hub_register_payload['email'], 'password' => hub_register_payload['password'] }
|
|
1040
|
-
hub_info.deep_merge!(hub_register_payload)
|
|
1041
|
-
hub_info.deep_merge!(hub_register_response['data']['info']) if (hub_register_response['data'] && hub_register_response['data']['info'])
|
|
1042
|
-
hub_info.deep_merge!(hub_register_response['hub']) if hub_register_response['hub'].is_a?(Hash)
|
|
1043
|
-
print_green_success "Registered with Morpheus Hub as #{hub_info['email']}"
|
|
1044
|
-
# uh ok so that means the init() request can use login
|
|
1045
|
-
# this avoid duplicate email error
|
|
1046
|
-
# but it can also just omit hubMode from the init() payload to achieve the same thing.
|
|
1047
|
-
# hubmode = nil
|
|
1048
|
-
rescue RestClient::Exception => e
|
|
1049
|
-
hub_register_response = parse_rest_exception(e)
|
|
1050
|
-
error_msg = hub_register_response["msg"] || "Hub Registration failed."
|
|
1051
|
-
print_error red,error_msg,reset,"\n"
|
|
1052
|
-
hubmode = nil
|
|
1053
|
-
#print_rest_exception(e, options)
|
|
1054
|
-
#exit 1
|
|
1055
|
-
end
|
|
1056
|
-
|
|
1057
|
-
# DEBUG
|
|
1058
|
-
if options[:debug] && hub_register_response
|
|
1059
|
-
print_h2 "JSON response for hub registration"
|
|
1060
|
-
Morpheus::Logging::DarkPrinter.puts as_json(hub_register_response)
|
|
1061
|
-
end
|
|
1062
|
-
|
|
1063
|
-
elsif hubmode == 'skip'
|
|
1064
|
-
print cyan,"Skipping hub registraton for now...",reset,"\n"
|
|
1065
|
-
# puts "You may enter a license key later."
|
|
1066
|
-
elsif hubmode == 'abort'
|
|
1067
|
-
return 9, "aborted command"
|
|
1068
|
-
else
|
|
1069
|
-
hubmode = nil
|
|
1070
|
-
end
|
|
1071
|
-
end
|
|
1072
|
-
end
|
|
1073
|
-
|
|
1074
|
-
# ok, we're done with the hub.
|
|
1075
|
-
# now build the payload for POST /api/setup/init
|
|
1076
|
-
|
|
1077
|
-
payload = {}
|
|
1078
|
-
payload.deep_merge!(params)
|
|
1079
|
-
|
|
1080
|
-
# print cyan
|
|
1081
|
-
#print_h1 "Morpheus Appliance Setup", [], options
|
|
1082
|
-
#print cyan
|
|
1083
|
-
#puts "Initializing remote appliance at URL: #{@appliance_url}"
|
|
1084
|
-
|
|
1085
|
-
# Master Account
|
|
1086
|
-
print_h2 "Create Master Tenant", options
|
|
1087
|
-
account_option_types = [
|
|
1088
|
-
{'fieldName' => 'accountName', 'fieldLabel' => 'Master Tenant Name', 'type' => 'text', 'required' => true, 'defaultValue' => (hub_info ? hub_info['companyName'] : nil), 'description' => 'A unique name for the Master Tenant (account).'},
|
|
1089
|
-
]
|
|
1090
|
-
v_prompt = Morpheus::Cli::OptionTypes.prompt(account_option_types, options[:options])
|
|
1091
|
-
payload.merge!(v_prompt)
|
|
1092
|
-
|
|
1093
|
-
# Master User
|
|
1094
|
-
print_h2 "Create Master User", options
|
|
1095
|
-
user_option_types = [
|
|
1096
|
-
{'fieldName' => 'firstName', 'fieldLabel' => 'First Name', 'type' => 'text', 'required' => false, 'defaultValue' => (hub_info ? hub_info['firstName'] : nil), 'description' => 'First name of the user.'},
|
|
1097
|
-
{'fieldName' => 'lastName', 'fieldLabel' => 'Last Name', 'type' => 'text', 'required' => false, 'defaultValue' => (hub_info ? hub_info['lastName'] : nil), 'description' => 'Last name of the user.'},
|
|
1098
|
-
{'fieldName' => 'email', 'fieldLabel' => 'Email', 'type' => 'text', 'required' => true, 'defaultValue' => (hub_info ? hub_info['email'] : nil), 'description' => 'A unique email address for the user.'},
|
|
1099
|
-
{'fieldName' => 'username', 'fieldLabel' => 'Username', 'type' => 'text', 'required' => true, 'description' => 'A unique username for the master user.'}
|
|
1100
|
-
]
|
|
1101
|
-
v_prompt = Morpheus::Cli::OptionTypes.prompt(user_option_types, options[:options])
|
|
1102
|
-
payload.merge!(v_prompt)
|
|
1103
|
-
|
|
1104
|
-
# Password prompt with re-prompting if no match
|
|
1105
|
-
need_password = true
|
|
1106
|
-
if options[:no_prompt]
|
|
1107
|
-
options[:options]['confirmPassword'] = payload['password']
|
|
1108
|
-
payload['confirmPassword'] = payload['password'] if payload['password']
|
|
1109
|
-
end
|
|
1110
|
-
while need_password do
|
|
1111
|
-
password_option_types = [
|
|
1112
|
-
{'fieldName' => 'password', 'fieldLabel' => 'Create Password', 'type' => 'password', 'required' => true, 'description' => 'Create a new password for the user.'},
|
|
1113
|
-
{'fieldName' => 'confirmPassword', 'fieldLabel' => 'Confirm Password', 'type' => 'password', 'required' => true, 'description' => 'Confirm the new password for the user.'},
|
|
1114
|
-
]
|
|
1115
|
-
password_prompt = Morpheus::Cli::OptionTypes.prompt(password_option_types, options[:options])
|
|
1116
|
-
if password_prompt['password'] == password_prompt['confirmPassword']
|
|
1117
|
-
payload['password'] = password_prompt['password']
|
|
1118
|
-
need_password = false
|
|
1119
|
-
else
|
|
1120
|
-
print_error red, "Password confirmation does not match. Re-enter your new password.", reset, "\n"
|
|
1121
|
-
end
|
|
1122
|
-
end
|
|
1123
|
-
|
|
1124
|
-
# Appliance Settings
|
|
1125
|
-
default_appliance_url = appliance_status_json['applianceUrl']
|
|
1126
|
-
if default_appliance_url && default_appliance_url.include?('10.0.2.2:8080') # ignore this default value.
|
|
1127
|
-
default_appliance_url = @appliance_url
|
|
1128
|
-
end
|
|
1129
|
-
default_appliance_name = appliance_status_json['applianceName']
|
|
1130
|
-
if default_appliance_name.nil?
|
|
1131
|
-
default_appliance_name = @appliance_name
|
|
1132
|
-
end
|
|
1133
|
-
print_h2 "Initial Setup", options
|
|
1134
|
-
extra_option_types = [
|
|
1135
|
-
{'fieldName' => 'applianceName', 'fieldLabel' => 'Appliance Name', 'type' => 'text', 'required' => true, 'defaultValue' => default_appliance_name, 'description' => 'A name for identifying your morpheus appliance.'},
|
|
1136
|
-
{'fieldName' => 'applianceUrl', 'fieldLabel' => 'Appliance URL', 'type' => 'text', 'required' => true, 'defaultValue' => default_appliance_url, 'description' => 'Appliance URL. Can be used for integrations and callbacks.'},
|
|
1137
|
-
{'fieldName' => 'backups', 'fieldLabel' => 'Enable Backups', 'type' => 'checkbox', 'required' => false, 'defaultValue' => 'off', 'description' => 'Backups. Default is off. This means backups are created automatically during provisioning.'},
|
|
1138
|
-
{'fieldName' => 'monitoring', 'fieldLabel' => 'Enable Monitoring', 'type' => 'checkbox', 'required' => false, 'defaultValue' => 'on', 'description' => 'Enable Monitoring. This means checks are created automatically during provisioning.'},
|
|
1139
|
-
{'fieldName' => 'logs', 'fieldLabel' => 'Enable Logs', 'type' => 'checkbox', 'required' => false, 'defaultValue' => 'on', 'description' => 'Enable Logs. This means container logs are collected.'}
|
|
1140
|
-
]
|
|
1141
|
-
v_prompt = Morpheus::Cli::OptionTypes.prompt(extra_option_types, options[:options])
|
|
1142
|
-
payload.merge!(v_prompt)
|
|
1143
|
-
|
|
1144
|
-
# include hubmode and hub params for login or registration
|
|
1145
|
-
# actually we remove hubMode because it has already been setup, probably just now,
|
|
1146
|
-
# and the init() request will just used the same creds instead of
|
|
1147
|
-
# reauthenticated/registering with the hub
|
|
1148
|
-
if hubmode
|
|
1149
|
-
payload['hubMode'] = hubmode
|
|
1150
|
-
end
|
|
1151
|
-
if hub_init_payload
|
|
1152
|
-
payload['hub'] = hub_init_payload
|
|
1153
|
-
end
|
|
1154
|
-
if hubmode == 'register' || hubmode == 'login'
|
|
1155
|
-
payload.delete('hubMode')
|
|
1156
|
-
payload.delete('hub')
|
|
1157
|
-
end
|
|
1158
|
-
|
|
1159
|
-
end
|
|
1160
|
-
|
|
1161
|
-
# ok, make the api request
|
|
1162
|
-
@setup_interface.setopts(options)
|
|
1163
|
-
if options[:dry_run]
|
|
1164
|
-
print_dry_run @setup_interface.dry.init(payload)
|
|
1165
|
-
return
|
|
1166
|
-
end
|
|
1167
|
-
|
|
1168
|
-
json_response = @setup_interface.init(payload)
|
|
1169
|
-
|
|
1170
|
-
render_result = render_with_format(json_response, options)
|
|
1171
|
-
return 0 if render_result
|
|
1172
|
-
|
|
1173
|
-
if options[:json]
|
|
1174
|
-
print JSON.pretty_generate(json_response)
|
|
1175
|
-
print "\n"
|
|
1176
|
-
return
|
|
1177
|
-
end
|
|
1178
|
-
print "\n"
|
|
1179
|
-
print green,"Setup complete for remote #{@appliance_name} - #{@appliance_url}",reset,"\n"
|
|
1180
|
-
#print cyan, "You may now login with the command `login`.\n"
|
|
1181
|
-
# uh, just use Credentials.login(username, password, {save: true})
|
|
1182
|
-
cmd_res = Morpheus::Cli::Login.new.login(['--username', payload['username'], '--password', payload['password'], '-q'] + (options[:remote] ? ["-r",options[:remote]] : []))
|
|
1183
|
-
# print "\n"
|
|
1184
|
-
print cyan, "You are now logged in as the System Admin #{payload['username']}.\n"
|
|
1185
|
-
print reset
|
|
1186
|
-
#print "\n"
|
|
1187
|
-
|
|
1188
|
-
if hubmode == 'skip'
|
|
1189
|
-
if ::Morpheus::Cli::OptionTypes::confirm("Would you like to apply your License Key now?", options.merge({:default => true}))
|
|
1190
|
-
cmd_res = Morpheus::Cli::License.new.apply([] + (options[:remote] ? ["-r",options[:remote]] : []))
|
|
1191
|
-
# license_is_valid = cmd_res != false
|
|
1204
|
+
print format_remote_details(appliance, options)
|
|
1205
|
+
print reset, "\n"
|
|
1192
1206
|
end
|
|
1193
1207
|
end
|
|
1194
|
-
|
|
1195
|
-
if ::Morpheus::Cli::OptionTypes::confirm("Do you want to create the first group now?", options.merge({:default => true}))
|
|
1196
|
-
cmd_res = Morpheus::Cli::Groups.new.add(['--use'] + (options[:remote] ? ["-r",options[:remote]] : []))
|
|
1197
|
-
|
|
1198
|
-
#print "\n"
|
|
1199
|
-
|
|
1200
|
-
# if cmd_res !=
|
|
1201
|
-
if ::Morpheus::Cli::OptionTypes::confirm("Do you want to create the first cloud now?", options.merge({:default => true}))
|
|
1202
|
-
cmd_res = Morpheus::Cli::Clouds.new.add([] + (options[:remote] ? ["-r",options[:remote]] : []))
|
|
1203
|
-
#print "\n"
|
|
1204
|
-
end
|
|
1205
|
-
# end
|
|
1206
|
-
end
|
|
1207
|
-
print "\n",reset
|
|
1208
|
-
|
|
1208
|
+
return exit_code, err
|
|
1209
1209
|
end
|
|
1210
1210
|
|
|
1211
|
-
|
|
1212
|
-
#
|
|
1213
|
-
|
|
1214
|
-
|
|
1211
|
+
|
|
1212
|
+
# This moved to the SetupCommand
|
|
1213
|
+
def setup(args)
|
|
1214
|
+
print_error yellow,"[DEPRECATED] The command `remote setup [name]` is deprecated. It has been replaced by `setup init`.",reset,"\n"
|
|
1215
1215
|
options = {}
|
|
1216
1216
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
|
1217
1217
|
opts.banner = subcommand_usage()
|
|
1218
|
-
build_common_options(opts, options, [:json, :dry_run, :quiet
|
|
1219
|
-
opts.
|
|
1218
|
+
build_common_options(opts, options, [:payload, :options, :json, :dry_run, :quiet])
|
|
1219
|
+
opts.on('--hubmode MODE','--hubmode MODE', "Choose an option for hub registration possible values are login, register, skip.") do |val|
|
|
1220
|
+
options[:hubmode] = val.to_s.downcase
|
|
1221
|
+
end
|
|
1222
|
+
opts.footer = <<-EOT
|
|
1223
|
+
Setup a fresh remote appliance, initializing it.
|
|
1224
|
+
First, this checks if setup is available, and returns an error if not.
|
|
1225
|
+
Then it prompts to create the master tenant and admin user.
|
|
1226
|
+
If Morpheus Hub registration is enabled, you may login or register to retrieve a license key,
|
|
1227
|
+
or you can pass `--hubmode skip`.
|
|
1228
|
+
This is only available on a new, freshly installed remote appliance,
|
|
1229
|
+
and it may only be executed successfully one time.
|
|
1230
|
+
EOT
|
|
1220
1231
|
end
|
|
1221
1232
|
optparse.parse!(args)
|
|
1222
|
-
|
|
1223
|
-
#
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1233
|
+
verify_args!(args:args, max:1, optparse:optparse)
|
|
1234
|
+
# just invoke the setup command.
|
|
1235
|
+
# for this to work, the argument [remote] must be the first argument.
|
|
1236
|
+
cmd_args = []
|
|
1237
|
+
remote_name = nil
|
|
1227
1238
|
if args[0]
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
if !@appliance_name
|
|
1233
|
-
print yellow, "No active appliance, see `remote use`\n", reset
|
|
1234
|
-
return false
|
|
1235
|
-
end
|
|
1236
|
-
|
|
1237
|
-
unless options[:quiet]
|
|
1238
|
-
print yellow
|
|
1239
|
-
print "\n"
|
|
1240
|
-
puts "WARNING: You are about to reset your appliance installation."
|
|
1241
|
-
puts "It's only possible to perform teardown when the appliance has just been installed."
|
|
1242
|
-
puts "This provides a way to reset your appliance and run setup again."
|
|
1243
|
-
print reset
|
|
1244
|
-
print "\n"
|
|
1245
|
-
end
|
|
1246
|
-
|
|
1247
|
-
unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like teardown appliance '#{@appliance_name}'.", options)
|
|
1248
|
-
return 9, "aborted command" # new exit code for aborting confirmation
|
|
1249
|
-
end
|
|
1250
|
-
|
|
1251
|
-
#@setup_interface = @api_client.setup
|
|
1252
|
-
|
|
1253
|
-
# construct payload
|
|
1254
|
-
|
|
1255
|
-
params = {}
|
|
1256
|
-
params.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
|
|
1257
|
-
|
|
1258
|
-
# this works without any authentication!
|
|
1259
|
-
# it will allow anyone to use it, if there are no users/accounts in the system.
|
|
1260
|
-
#@api_client = establish_remote_appliance_connection(options)
|
|
1261
|
-
#@setup_interface = @api_client.setup
|
|
1262
|
-
@setup_interface = Morpheus::SetupInterface.new({url:@appliance_url,access_token:@access_token, very_ssl:false})
|
|
1263
|
-
json_response = nil
|
|
1264
|
-
begin
|
|
1265
|
-
json_response = @setup_interface.teardown(params)
|
|
1266
|
-
if json_response['success'] != true
|
|
1267
|
-
print_error red, (json_response['msg'] || "Teardown failed").to_s, reset, "\n"
|
|
1268
|
-
return false
|
|
1269
|
-
end
|
|
1270
|
-
rescue RestClient::Exception => e
|
|
1271
|
-
print_rest_exception(e, options)
|
|
1272
|
-
return false
|
|
1273
|
-
end
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
# ok, make the api request and render the response or print a message
|
|
1277
|
-
@setup_interface.setopts(options)
|
|
1278
|
-
if options[:dry_run]
|
|
1279
|
-
print_dry_run @setup_interface.dry.teardown(params)
|
|
1280
|
-
return
|
|
1281
|
-
end
|
|
1282
|
-
|
|
1283
|
-
json_response = @setup_interface.teardown(params)
|
|
1284
|
-
|
|
1285
|
-
render_result = render_with_format(json_response, options)
|
|
1286
|
-
return 0 if render_result
|
|
1287
|
-
if options[:quiet]
|
|
1288
|
-
return 0
|
|
1289
|
-
end
|
|
1290
|
-
if json_response['msg']
|
|
1291
|
-
print_green_success json_response['msg']
|
|
1292
|
-
else
|
|
1293
|
-
print_green_success "Teardown complete for remote #{@appliance_name} - #{@appliance_url}. Now see `remote setup`"
|
|
1294
|
-
end
|
|
1295
|
-
return 0
|
|
1296
|
-
|
|
1297
|
-
end
|
|
1298
|
-
|
|
1299
|
-
def format_appliance_status(app_map, return_color=cyan)
|
|
1300
|
-
return "" if !app_map
|
|
1301
|
-
status_str = app_map[:status] || app_map['status'] || "unknown" # get_object_value(app_map, :status)
|
|
1302
|
-
status_str = status_str.empty? ? "unknown" : status_str.to_s.downcase
|
|
1303
|
-
out = ""
|
|
1304
|
-
if status_str == "new"
|
|
1305
|
-
out << "#{cyan}#{status_str.upcase}#{return_color}"
|
|
1306
|
-
elsif status_str == "fresh"
|
|
1307
|
-
# maybe just green instead?
|
|
1308
|
-
out << "#{magenta}#{status_str.upcase}#{return_color}"
|
|
1309
|
-
elsif status_str == "ready"
|
|
1310
|
-
out << "#{green}#{status_str.upcase}#{return_color}"
|
|
1311
|
-
elsif status_str == "http-error"
|
|
1312
|
-
out << "#{red}HTTP ERROR#{return_color}"
|
|
1313
|
-
elsif ['error', 'net-error', 'ssl-error', 'http-timeout', 'unreachable', 'unrecognized'].include?(status_str)
|
|
1314
|
-
out << "#{red}#{status_str.gsub('-', ' ').upcase}#{return_color}"
|
|
1315
|
-
else
|
|
1316
|
-
# dunno
|
|
1317
|
-
out << "#{yellow}#{status_str.upcase}#{return_color}"
|
|
1239
|
+
remote_name = args.shift
|
|
1240
|
+
# cmd_args = cmd_args + ["-r",remote_name, args]
|
|
1241
|
+
cmd_args = args + ["-r",remote_name, args]
|
|
1318
1242
|
end
|
|
1319
|
-
|
|
1243
|
+
return Morpheus::Cli::Setup.new.init(cmd_args)
|
|
1320
1244
|
end
|
|
1321
1245
|
|
|
1322
|
-
def
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1246
|
+
def load_remote_by_name(appliance_name, allow_current=true)
|
|
1247
|
+
appliance = nil
|
|
1248
|
+
if appliance_name.to_s == "current" && allow_current
|
|
1249
|
+
appliance = ::Morpheus::Cli::Remote.load_active_remote()
|
|
1250
|
+
if !appliance
|
|
1251
|
+
raise_command_error "No current appliance, see the command `remote use`"
|
|
1252
|
+
end
|
|
1329
1253
|
else
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
# should have a flag that gets set when everything actually looks good..
|
|
1334
|
-
out << "Yes"
|
|
1254
|
+
appliance = ::Morpheus::Cli::Remote.load_remote(appliance_name)
|
|
1255
|
+
if !appliance
|
|
1256
|
+
raise_command_error "Remote not found by name '#{appliance_name}', see the command `remote list`"
|
|
1335
1257
|
end
|
|
1336
1258
|
end
|
|
1337
|
-
|
|
1259
|
+
return appliance
|
|
1338
1260
|
end
|
|
1339
1261
|
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1262
|
+
def format_remote_details(appliance, options={})
|
|
1263
|
+
columns = {
|
|
1264
|
+
"Name" => :name,
|
|
1265
|
+
#"Name" => lambda {|it| it[:active] ? "#{it[:name]} #{bold}(current)#{reset}#{cyan}" : it[:name] },
|
|
1266
|
+
"URL" => lambda {|it| it[:url] || it[:host] },
|
|
1267
|
+
#"Status" => lambda {|it| format_appliance_status(it, cyan) },
|
|
1268
|
+
"Version" => lambda {|it| it[:build_version] ? "#{it[:build_version]}" : '' },
|
|
1269
|
+
"Appliance URL" => lambda {|it| it[:appliance_url] ? "#{it[:appliance_url]}" : '' },
|
|
1270
|
+
"Secure" => lambda {|it| format_appliance_secure(it) },
|
|
1271
|
+
"Active" => lambda {|it| it[:active] ? "Yes " + format_is_current() : "No" },
|
|
1272
|
+
# "Active" => lambda {|it| format_boolean(it[:active]) },
|
|
1273
|
+
#"Authenticated" => lambda {|it| format_boolean it[:authenticated] },
|
|
1274
|
+
"Username" => :username,
|
|
1275
|
+
# "Activity" => lambda {|it| get_appliance_session_blurbs(it).join("\n" + (' '*15)) },
|
|
1276
|
+
"Last Login" => lambda {|it| format_duration_ago(it[:last_login_at]) },
|
|
1277
|
+
#"Last Logout" => lambda {|it| format_duration_ago(it[:last_logout_at]) },
|
|
1278
|
+
"Last Success" => lambda {|it| format_duration_ago(it[:last_success_at]) },
|
|
1279
|
+
"Last Check" => lambda {|it|
|
|
1280
|
+
check_timestamp = nil
|
|
1281
|
+
if it[:last_check] && it[:last_check][:timestamp]
|
|
1282
|
+
check_timestamp = it[:last_check][:timestamp]
|
|
1356
1283
|
end
|
|
1357
|
-
|
|
1358
|
-
if
|
|
1359
|
-
|
|
1360
|
-
else
|
|
1361
|
-
blurbs << "Logged out."
|
|
1284
|
+
check_status = nil
|
|
1285
|
+
if it[:last_check] && it[:last_check][:http_status]
|
|
1286
|
+
check_status = it[:last_check][:http_status]
|
|
1362
1287
|
end
|
|
1363
|
-
if
|
|
1364
|
-
|
|
1288
|
+
if check_timestamp
|
|
1289
|
+
format_duration_ago(check_timestamp) # + (check_status ? " (HTTP #{check_status})" : "")
|
|
1290
|
+
else
|
|
1291
|
+
""
|
|
1365
1292
|
end
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1293
|
+
},
|
|
1294
|
+
"Response Time" => lambda {|it| format_duration_milliseconds(it[:last_check][:took]) rescue "" },
|
|
1295
|
+
#"Response Time" => lambda {|it| format_sig_dig((it[:last_check][:took]/ 1000.to_f), 3) + "s" rescue "" },
|
|
1296
|
+
"Status" => lambda {|it| format_appliance_status(it, cyan) },
|
|
1297
|
+
"Error" => lambda {|it|
|
|
1298
|
+
error_str = it[:last_check] ? it[:last_check][:error] : ""
|
|
1299
|
+
# meh no need to show http status, :error explains it well enough
|
|
1300
|
+
# check_status = it[:last_check] ? it[:last_check][:http_status] : nil
|
|
1301
|
+
# if check_status && check_status != 200
|
|
1302
|
+
# #"(HTTP #{check_status}) #{error_str}"
|
|
1303
|
+
# else
|
|
1304
|
+
# error_str
|
|
1305
|
+
# end
|
|
1306
|
+
error_str
|
|
1307
|
+
},
|
|
1308
|
+
|
|
1309
|
+
}
|
|
1310
|
+
if appliance[:last_success_at].nil?
|
|
1311
|
+
columns.delete("Last Success")
|
|
1372
1312
|
else
|
|
1373
|
-
|
|
1374
|
-
if app_map[:last_check]
|
|
1375
|
-
if app_map[:last_check][:timestamp]
|
|
1376
|
-
blurbs << "Last checked #{format_duration(app_map[:last_check][:timestamp])} ago."
|
|
1377
|
-
end
|
|
1378
|
-
if app_map[:last_check][:error]
|
|
1379
|
-
last_error_msg = truncate_string(app_map[:last_check][:error], 250)
|
|
1380
|
-
blurbs << "Error: #{last_error_msg}"
|
|
1381
|
-
end
|
|
1382
|
-
if app_map[:last_check][:http_status]
|
|
1383
|
-
blurbs << "HTTP #{app_map[:last_check][:http_status]}"
|
|
1384
|
-
end
|
|
1385
|
-
end
|
|
1386
|
-
|
|
1387
|
-
if app_map[:last_success_at]
|
|
1388
|
-
blurbs << "Last Success: #{format_local_dt(app_map[:last_success_at])}"
|
|
1389
|
-
end
|
|
1390
|
-
|
|
1313
|
+
columns.delete("Last Success")
|
|
1391
1314
|
end
|
|
1392
|
-
|
|
1393
|
-
|
|
1315
|
+
if appliance[:last_check].nil? || appliance[:last_check][:error].nil?
|
|
1316
|
+
columns.delete("Error")
|
|
1317
|
+
end
|
|
1318
|
+
return as_description_list(appliance, columns, options)
|
|
1394
1319
|
end
|
|
1395
1320
|
|
|
1396
1321
|
class << self
|
|
@@ -1406,7 +1331,18 @@ EOT
|
|
|
1406
1331
|
end
|
|
1407
1332
|
|
|
1408
1333
|
def appliance_config
|
|
1409
|
-
@@appliance_config
|
|
1334
|
+
if @@appliance_config.nil?
|
|
1335
|
+
@@appliance_config
|
|
1336
|
+
@@appliance_config = load_appliance_file
|
|
1337
|
+
# fix things right away, replace deprecated :host with :url
|
|
1338
|
+
@@appliance_config.each do |app_name, appliance|
|
|
1339
|
+
host = appliance.delete(:host)
|
|
1340
|
+
if host && appliance[:url].to_s.empty?
|
|
1341
|
+
appliance[:url] = host
|
|
1342
|
+
end
|
|
1343
|
+
end
|
|
1344
|
+
end
|
|
1345
|
+
return @@appliance_config
|
|
1410
1346
|
end
|
|
1411
1347
|
|
|
1412
1348
|
# Returns two things, the remote appliance name and url
|
|
@@ -1472,10 +1408,14 @@ EOT
|
|
|
1472
1408
|
end
|
|
1473
1409
|
# apply sort
|
|
1474
1410
|
sort_key = params[:sort] ? params[:sort].to_sym : :name
|
|
1411
|
+
# :url used to be stored as :host
|
|
1412
|
+
if sort_key == :url || sort_key == :host
|
|
1413
|
+
all_appliances = all_appliances.sort {|a,b| (a[:url] || a[:host]).to_s <=> (b[:url] || b[:host]).to_s }
|
|
1414
|
+
elsif sort_key
|
|
1415
|
+
all_appliances = all_appliances.sort {|a,b| a[sort_key].to_s <=> b[sort_key].to_s }
|
|
1416
|
+
end
|
|
1475
1417
|
if params['direction'] == 'desc'
|
|
1476
|
-
all_appliances
|
|
1477
|
-
else
|
|
1478
|
-
all_appliances = all_appliances.sort {|a,b| a[sort_key] <=> b[sort_key] }
|
|
1418
|
+
all_appliances.reverse!
|
|
1479
1419
|
end
|
|
1480
1420
|
# limit
|
|
1481
1421
|
if params[:max]
|
|
@@ -1577,12 +1517,26 @@ EOT
|
|
|
1577
1517
|
# @param app_map [Hash] appliance configuration data :url, :insecure, :active, :etc
|
|
1578
1518
|
# @return [Hash] updated appliance config data
|
|
1579
1519
|
def save_remote(app_name, app_map)
|
|
1520
|
+
# need an app_name to save it
|
|
1521
|
+
if app_name.to_s.empty?
|
|
1522
|
+
puts "skipped save of remote with a blank name"
|
|
1523
|
+
return nil
|
|
1524
|
+
end
|
|
1525
|
+
# in case a temporary config gets passed in here, do not save it.. this should be avoided though
|
|
1526
|
+
if app_map[:temporary]
|
|
1527
|
+
puts "skipped save of temporary remote '#{app_name}'"
|
|
1528
|
+
return nil
|
|
1529
|
+
end
|
|
1580
1530
|
app_name = app_name.to_sym
|
|
1581
1531
|
# it's probably better to use load_appliance_file() here instead
|
|
1582
1532
|
cur_appliances = self.appliances #.clone
|
|
1583
1533
|
cur_appliances[app_name] = app_map
|
|
1584
|
-
cur_appliances[app_name] ||= {:status => "unknown", :error => "Bad configuration. Missing url. See 'remote update --url'" }
|
|
1585
|
-
|
|
1534
|
+
#cur_appliances[app_name] ||= {:status => "unknown", :error => "Bad configuration. Missing url. See 'remote update --url'" }
|
|
1535
|
+
cur_appliances[app_name] ||= {:status => "unknown"}
|
|
1536
|
+
# :host is gone, use :url please
|
|
1537
|
+
if cur_appliances[app_name][:host]
|
|
1538
|
+
cur_appliances[app_name][:url] = cur_appliances[app_name].delete(:host)
|
|
1539
|
+
end
|
|
1586
1540
|
# this is the new set_active_appliance(), instead just pass :active => true
|
|
1587
1541
|
# remove active flag from others
|
|
1588
1542
|
if app_map[:active]
|
|
@@ -1619,12 +1573,12 @@ EOT
|
|
|
1619
1573
|
cur_appliances = self.appliances #.clone
|
|
1620
1574
|
app_map = cur_appliances[app_name]
|
|
1621
1575
|
if app_map.nil?
|
|
1622
|
-
print_red_alert "
|
|
1576
|
+
print_red_alert "Remote not found by the name '#{app_name}', see the command `remote list`"
|
|
1623
1577
|
#print "Did you mean one of these commands: #{suggestions.join(', ')?", reset, "\n"
|
|
1624
1578
|
return nil
|
|
1625
1579
|
end
|
|
1626
1580
|
if cur_appliances[new_app_name]
|
|
1627
|
-
print_red_alert "A remote already exists with name '#{new_app_name}'
|
|
1581
|
+
print_red_alert "A remote already exists with name '#{new_app_name}', see the command `remote get #{new_app_name}`"
|
|
1628
1582
|
puts "First, you must rename or remove the existing remote."
|
|
1629
1583
|
return nil
|
|
1630
1584
|
end
|
|
@@ -1695,109 +1649,146 @@ EOT
|
|
|
1695
1649
|
return app_map
|
|
1696
1650
|
end
|
|
1697
1651
|
|
|
1652
|
+
def delete_all_remotes()
|
|
1653
|
+
deleted_list = []
|
|
1654
|
+
self.appliances.each do |app_name, appliance|
|
|
1655
|
+
deleted_list << delete_remote(app_name)
|
|
1656
|
+
end
|
|
1657
|
+
# self.appliances = {}
|
|
1658
|
+
# Morpheus::Cli::Remote.save_appliances({})
|
|
1659
|
+
# recalculate_variable_map()
|
|
1660
|
+
# return deleted_list
|
|
1661
|
+
return self.appliances
|
|
1662
|
+
end
|
|
1663
|
+
|
|
1698
1664
|
# refresh_remote makes an api request to the configured appliance url
|
|
1699
1665
|
# and updates the appliance's build version, status and last_check attributes
|
|
1700
|
-
def refresh_remote(app_name)
|
|
1701
|
-
# this might be better off staying in the CliCommands themselves
|
|
1702
|
-
# todo: public api /api/setup/check should move to /api/version or /api/server-info
|
|
1666
|
+
def refresh_remote(app_name, params={}, timeout=5)
|
|
1703
1667
|
app_name = app_name.to_sym
|
|
1704
1668
|
cur_appliances = self.appliances
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
if !app_url
|
|
1669
|
+
appliance = cur_appliances[app_name] || {}
|
|
1670
|
+
appliance_url = (appliance[:url] || appliance[:host]).to_s
|
|
1671
|
+
if !appliance_url
|
|
1709
1672
|
raise "appliance config is missing url!" # should not need this
|
|
1710
1673
|
end
|
|
1711
|
-
|
|
1712
1674
|
# todo: this insecure flag needs to applied everywhere now tho..
|
|
1713
|
-
if
|
|
1675
|
+
if appliance[:insecure]
|
|
1714
1676
|
Morpheus::RestClient.enable_ssl_verification = false
|
|
1677
|
+
# Morpheus::RestClient.enable_http = true
|
|
1678
|
+
end
|
|
1679
|
+
err = nil
|
|
1680
|
+
json_response = nil
|
|
1681
|
+
# make request to /api/setup/check
|
|
1682
|
+
# and update appliance :status, :build_version, :last_check{}
|
|
1683
|
+
if appliance_url.to_s.empty?
|
|
1684
|
+
err = "no url specified"
|
|
1685
|
+
# wtf, no url...
|
|
1686
|
+
return appliance, json_response
|
|
1687
|
+
else
|
|
1688
|
+
setup_interface = Morpheus::SetupInterface.new({url:appliance_url, verify_ssl: (appliance[:insecure] != true), timeout: timeout})
|
|
1689
|
+
start_time = Time.now
|
|
1690
|
+
begin
|
|
1691
|
+
json_response = setup_interface.check(params)
|
|
1692
|
+
rescue => ex
|
|
1693
|
+
err = ex
|
|
1694
|
+
ensure
|
|
1695
|
+
took_sec = Time.now - start_time
|
|
1696
|
+
end
|
|
1697
|
+
|
|
1698
|
+
# save and update appliance info
|
|
1699
|
+
return save_remote_last_check(appliance, json_response, err, took_sec)
|
|
1700
|
+
end
|
|
1701
|
+
end
|
|
1702
|
+
|
|
1703
|
+
# save the app status and last request information
|
|
1704
|
+
# looks for json_response like /setup/check and /ping
|
|
1705
|
+
def save_remote_last_check(appliance, json_response, err=nil, took_sec=nil)
|
|
1706
|
+
#puts "save_remote_last_check: #{appliance}, #{json_response}"
|
|
1707
|
+
app_name = appliance[:name] ? appliance[:name].to_sym : nil
|
|
1708
|
+
cur_appliances = self.appliances
|
|
1709
|
+
app_map = appliance
|
|
1710
|
+
app_url = (app_map[:url] || app_map[:host]).to_s
|
|
1711
|
+
if !app_url
|
|
1712
|
+
raise "appliance config is missing url!"
|
|
1715
1713
|
end
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
#
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
if
|
|
1732
|
-
|
|
1733
|
-
|
|
1714
|
+
|
|
1715
|
+
# only change stuff that was contained in the response
|
|
1716
|
+
# this stores things under the context last_check
|
|
1717
|
+
appliance[:last_check] = {}
|
|
1718
|
+
appliance[:last_check][:success] = json_response.nil?
|
|
1719
|
+
appliance[:last_check][:timestamp] = Time.now.to_i
|
|
1720
|
+
appliance[:last_check][:http_status] = json_response ? 200 : nil
|
|
1721
|
+
if took_sec
|
|
1722
|
+
# store in ms
|
|
1723
|
+
appliance[:last_check][:took] = (took_sec.to_f*1000).round
|
|
1724
|
+
end
|
|
1725
|
+
if json_response
|
|
1726
|
+
if json_response.key?('applianceUrl')
|
|
1727
|
+
appliance[:appliance_url] = json_response['applianceUrl']
|
|
1728
|
+
end
|
|
1729
|
+
if json_response.key?('buildVersion')
|
|
1730
|
+
appliance[:build_version] = json_response['buildVersion']
|
|
1731
|
+
appliance[:status] = 'ready'
|
|
1732
|
+
appliance[:last_check][:success] = true
|
|
1734
1733
|
# consider bumping this after every successful api command
|
|
1735
|
-
|
|
1736
|
-
|
|
1734
|
+
appliance[:last_success_at] = Time.now.to_i
|
|
1735
|
+
appliance.delete(:error)
|
|
1737
1736
|
end
|
|
1738
|
-
if
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1737
|
+
if json_response.key?('setupNeeded')
|
|
1738
|
+
if json_response['setupNeeded'] == true
|
|
1739
|
+
appliance[:setup_needed] = true
|
|
1740
|
+
appliance[:status] = 'fresh'
|
|
1741
|
+
else
|
|
1742
|
+
appliance.delete(:setup_needed)
|
|
1743
|
+
end
|
|
1743
1744
|
end
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
#
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1745
|
+
else
|
|
1746
|
+
# no response body eh?
|
|
1747
|
+
appliance[:last_check][:success] = false
|
|
1748
|
+
appliance[:last_check][:error] = "Invalid api response"
|
|
1749
|
+
appliance[:status] = 'error'
|
|
1750
|
+
end
|
|
1751
|
+
# handle error
|
|
1752
|
+
if err
|
|
1753
|
+
case(err)
|
|
1754
|
+
when SocketError
|
|
1755
|
+
appliance[:status] = 'unreachable'
|
|
1756
|
+
appliance[:last_check][:http_status] = nil
|
|
1757
|
+
appliance[:last_check][:error] = err.message
|
|
1758
|
+
when RestClient::Exceptions::Timeout
|
|
1759
|
+
# print_rest_exception(e, options)
|
|
1760
|
+
# exit 1
|
|
1761
|
+
appliance[:status] = 'http-timeout'
|
|
1762
|
+
appliance[:last_check][:http_status] = nil
|
|
1763
|
+
when Errno::ECONNREFUSED
|
|
1764
|
+
appliance[:status] = 'net-error'
|
|
1765
|
+
appliance[:last_check][:error] = err.message
|
|
1766
|
+
when OpenSSL::SSL::SSLError
|
|
1767
|
+
appliance[:status] = 'ssl-error'
|
|
1768
|
+
appliance[:last_check][:error] = err.message
|
|
1769
|
+
when JSON::ParserError
|
|
1770
|
+
appliance[:status] = 'unrecognized'
|
|
1771
|
+
appliance[:last_check][:error] = err.message
|
|
1772
|
+
when RestClient::Exception
|
|
1773
|
+
appliance[:status] = 'http-error'
|
|
1774
|
+
# appliance[:http_status] = err.response ? err.response.code : nil
|
|
1775
|
+
appliance[:last_check][:http_status] = err.response ? err.response.code : nil
|
|
1776
|
+
appliance[:last_check][:error] = err.message
|
|
1777
|
+
# if err.response.code == 404
|
|
1778
|
+
# appliance[:status] = 'ready' # 'ok'
|
|
1779
|
+
# Morpheus::Logging::DarkPrinter.puts "ping failed but it is ready" if Morpheus::Logging.debug?
|
|
1780
|
+
# end
|
|
1781
|
+
else
|
|
1782
|
+
appliance[:status] = 'error' # err.class.to_s.dasherize
|
|
1783
|
+
appliance[:last_check][:error] = err.message
|
|
1782
1784
|
end
|
|
1783
|
-
rescue => err
|
|
1784
|
-
# should save before raising atleast..sheesh
|
|
1785
|
-
raise err
|
|
1786
|
-
app_map[:status] = 'error'
|
|
1787
|
-
app_map[:last_check][:error] = err.message
|
|
1788
1785
|
end
|
|
1789
1786
|
|
|
1790
|
-
#
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
# ... class variable returned by Remote.appliances is updated in there too...
|
|
1796
|
-
save_remote(app_name, app_map)
|
|
1797
|
-
|
|
1798
|
-
# return the updated data
|
|
1799
|
-
return app_map, check_json_response
|
|
1800
|
-
|
|
1787
|
+
# save to disk
|
|
1788
|
+
save_remote(app_name, appliance)
|
|
1789
|
+
|
|
1790
|
+
# return map and response
|
|
1791
|
+
return appliance, json_response
|
|
1801
1792
|
end
|
|
1802
1793
|
|
|
1803
1794
|
def recalculate_variable_map()
|