morpheus-cli 4.1.4 → 4.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/morpheus.rb +5 -0
- data/lib/morpheus/api.rb +2 -2
- data/lib/morpheus/api/api_client.rb +47 -12
- data/lib/morpheus/api/appliance_settings_interface.rb +30 -0
- data/lib/morpheus/api/auth_interface.rb +14 -10
- data/lib/morpheus/api/clouds_interface.rb +7 -0
- data/lib/morpheus/api/clusters_interface.rb +17 -5
- data/lib/morpheus/api/custom_instance_types_interface.rb +2 -3
- data/lib/morpheus/api/deployments_interface.rb +7 -0
- data/lib/morpheus/api/execute_schedules_interface.rb +2 -3
- data/lib/morpheus/api/groups_interface.rb +7 -0
- data/lib/morpheus/api/license_interface.rb +9 -2
- data/lib/morpheus/api/load_balancers_interface.rb +7 -0
- data/lib/morpheus/api/logs_interface.rb +11 -2
- data/lib/morpheus/api/monitoring_alerts_interface.rb +45 -0
- data/lib/morpheus/api/monitoring_checks_interface.rb +2 -2
- data/lib/morpheus/api/monitoring_interface.rb +13 -8
- data/lib/morpheus/api/power_schedules_interface.rb +2 -3
- data/lib/morpheus/api/servers_interface.rb +5 -2
- data/lib/morpheus/api/setup_interface.rb +25 -7
- data/lib/morpheus/api/task_sets_interface.rb +7 -1
- data/lib/morpheus/api/tasks_interface.rb +7 -0
- data/lib/morpheus/api/virtual_images_interface.rb +2 -3
- data/lib/morpheus/api/whitelabel_settings_interface.rb +60 -0
- data/lib/morpheus/cli.rb +18 -14
- data/lib/morpheus/cli/access_token_command.rb +18 -2
- data/lib/morpheus/cli/appliance_settings_command.rb +303 -0
- data/lib/morpheus/cli/apps.rb +4 -3
- data/lib/morpheus/cli/archives_command.rb +0 -21
- data/lib/morpheus/cli/blueprints_command.rb +2 -2
- data/lib/morpheus/cli/cli_command.rb +32 -8
- data/lib/morpheus/cli/clouds.rb +6 -11
- data/lib/morpheus/cli/clusters.rb +346 -117
- data/lib/morpheus/cli/command_error.rb +4 -0
- data/lib/morpheus/cli/commands/standard/man_command.rb +1 -1
- data/lib/morpheus/cli/containers_command.rb +2 -1
- data/lib/morpheus/cli/credentials.rb +49 -4
- data/lib/morpheus/cli/deployments.rb +2 -2
- data/lib/morpheus/cli/dot_file.rb +2 -2
- data/lib/morpheus/cli/error_handler.rb +6 -3
- data/lib/morpheus/cli/execute_schedules_command.rb +1 -1
- data/lib/morpheus/cli/groups.rb +4 -4
- data/lib/morpheus/cli/hosts.rb +3 -2
- data/lib/morpheus/cli/image_builder_command.rb +0 -21
- data/lib/morpheus/cli/instances.rb +17 -4
- data/lib/morpheus/cli/library_container_types_command.rb +1 -1
- data/lib/morpheus/cli/library_layouts_command.rb +1 -1
- data/lib/morpheus/cli/library_upgrades_command.rb +1 -1
- data/lib/morpheus/cli/license.rb +185 -72
- data/lib/morpheus/cli/load_balancers.rb +4 -4
- data/lib/morpheus/cli/login.rb +4 -0
- data/lib/morpheus/cli/logs_command.rb +132 -0
- data/lib/morpheus/cli/mixins/infrastructure_helper.rb +2 -2
- data/lib/morpheus/cli/mixins/logs_helper.rb +65 -0
- data/lib/morpheus/cli/mixins/monitoring_helper.rb +410 -28
- data/lib/morpheus/cli/mixins/print_helper.rb +14 -4
- data/lib/morpheus/cli/monitoring_alerts_command.rb +800 -0
- data/lib/morpheus/cli/monitoring_apps_command.rb +85 -28
- data/lib/morpheus/cli/monitoring_checks_command.rb +60 -27
- data/lib/morpheus/cli/monitoring_contacts_command.rb +54 -79
- data/lib/morpheus/cli/monitoring_groups_command.rb +62 -23
- data/lib/morpheus/cli/monitoring_incidents_command.rb +91 -70
- data/lib/morpheus/cli/network_pools_command.rb +39 -23
- data/lib/morpheus/cli/power_schedules_command.rb +1 -1
- data/lib/morpheus/cli/remote.rb +834 -275
- data/lib/morpheus/cli/roles.rb +100 -38
- data/lib/morpheus/cli/tasks.rb +1 -1
- data/lib/morpheus/cli/user_settings_command.rb +20 -12
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/virtual_images.rb +1 -1
- data/lib/morpheus/cli/whitelabel_settings_command.rb +546 -0
- data/lib/morpheus/cli/whoami.rb +1 -1
- data/lib/morpheus/cli/workflows.rb +2 -2
- data/lib/morpheus/terminal.rb +22 -8
- metadata +11 -2
@@ -6,7 +6,7 @@ class Morpheus::Cli::MonitoringIncidentsCommand
|
|
6
6
|
include Morpheus::Cli::MonitoringHelper
|
7
7
|
|
8
8
|
set_command_name :'monitor-incidents'
|
9
|
-
register_subcommands :list, :stats, :get, :history, :notifications, :update, :close, :reopen, :mute, :unmute
|
9
|
+
register_subcommands :list, :stats, :get, :history, :notifications, :update, :close, :reopen, :mute, :unmute, :add
|
10
10
|
register_subcommands :'mute-all' => :mute_all
|
11
11
|
register_subcommands :'unmute-all' => :unmute_all
|
12
12
|
|
@@ -159,7 +159,76 @@ class Morpheus::Cli::MonitoringIncidentsCommand
|
|
159
159
|
exit 1
|
160
160
|
end
|
161
161
|
end
|
162
|
-
|
162
|
+
|
163
|
+
def add(args)
|
164
|
+
options = {}
|
165
|
+
params = {}
|
166
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
167
|
+
opts.banner = subcommand_usage("[id]")
|
168
|
+
opts.on("-c", "--comment STRING", String, "Comment on this incident. Updates summary field.") do |val|
|
169
|
+
params['comment'] = val == 'null' ? nil : val
|
170
|
+
end
|
171
|
+
opts.on("--resolution STRING", String, "Description of the resolution to this incident") do |val|
|
172
|
+
params['resolution'] = val == 'null' ? nil : val
|
173
|
+
end
|
174
|
+
opts.on("--status STATUS", String, "Set status (open or closed)") do |val|
|
175
|
+
params['status'] = val
|
176
|
+
end
|
177
|
+
opts.on("--severity STATUS", String, "Set severity (critical, warning or info)") do |val|
|
178
|
+
params['severity'] = val
|
179
|
+
end
|
180
|
+
opts.on("--name STRING", String, "Set display name (subject)") do |val|
|
181
|
+
params['name'] = val == 'null' ? nil : val
|
182
|
+
end
|
183
|
+
opts.on("--startDate TIME", String, "Set start time") do |val|
|
184
|
+
begin
|
185
|
+
params['startDate'] = parse_time(val).utc.iso8601
|
186
|
+
rescue => e
|
187
|
+
raise OptionParser::InvalidArgument.new "Failed to parse --startDate '#{val}'. Error: #{e}"
|
188
|
+
end
|
189
|
+
end
|
190
|
+
opts.on("--endDate TIME", String, "Set end time") do |val|
|
191
|
+
begin
|
192
|
+
params['endDate'] = parse_time(val).utc.iso8601
|
193
|
+
rescue => e
|
194
|
+
raise OptionParser::InvalidArgument.new "Failed to parse --endDate '#{val}'. Error: #{e}"
|
195
|
+
end
|
196
|
+
end
|
197
|
+
opts.on("--inUptime BOOL", String, "Set 'In Availability'") do |val|
|
198
|
+
params['inUptime'] = ['true','on'].include?(val.to_s.strip)
|
199
|
+
end
|
200
|
+
build_common_options(opts, options, [:json, :dry_run, :quiet, :remote])
|
201
|
+
end
|
202
|
+
|
203
|
+
optparse.parse!(args)
|
204
|
+
connect(options)
|
205
|
+
|
206
|
+
begin
|
207
|
+
params['name'] = params['name'] || 'No subject'
|
208
|
+
params['startDate'] = params['startDate'] || Time.now.utc.iso8601
|
209
|
+
payload = { 'incident' => params }
|
210
|
+
|
211
|
+
@monitoring_incidents_interface.setopts(options)
|
212
|
+
if options[:dry_run]
|
213
|
+
print_dry_run @monitoring_incidents_interface.dry.create(payload)
|
214
|
+
return
|
215
|
+
end
|
216
|
+
|
217
|
+
json_response = @monitoring_incidents_interface.create(payload)
|
218
|
+
|
219
|
+
if options[:json]
|
220
|
+
puts as_json(json_response, options)
|
221
|
+
elsif !options[:quiet]
|
222
|
+
print_green_success "Created incident #{json_response['incident']['id']}"
|
223
|
+
_get(json_response['incident']['id'], options)
|
224
|
+
end
|
225
|
+
|
226
|
+
rescue RestClient::Exception => e
|
227
|
+
print_rest_exception(e, options)
|
228
|
+
exit 1
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
163
232
|
def get(args)
|
164
233
|
options = {}
|
165
234
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
@@ -170,7 +239,11 @@ class Morpheus::Cli::MonitoringIncidentsCommand
|
|
170
239
|
opts.on(nil,'--notifications', "Display Incident Notifications") do |val|
|
171
240
|
options[:show_notifications] = true
|
172
241
|
end
|
173
|
-
|
242
|
+
opts.on('-a','--all', "Display All Details (History, Notifications)") do
|
243
|
+
options[:show_history] = true
|
244
|
+
options[:show_notifications] = true
|
245
|
+
end
|
246
|
+
build_common_options(opts, options, [:json, :yaml, :csv, :fields, :query, :dry_run, :remote])
|
174
247
|
end
|
175
248
|
optparse.parse!(args)
|
176
249
|
if args.count < 1
|
@@ -236,7 +309,7 @@ class Morpheus::Cli::MonitoringIncidentsCommand
|
|
236
309
|
issues = json_response["issues"]
|
237
310
|
if issues && !issues.empty?
|
238
311
|
print_h2 "Issues"
|
239
|
-
|
312
|
+
print_incident_issues_table(issues, options)
|
240
313
|
else
|
241
314
|
print "\n"
|
242
315
|
puts "No checks involved in this incident"
|
@@ -265,7 +338,7 @@ class Morpheus::Cli::MonitoringIncidentsCommand
|
|
265
338
|
# gotta go get it
|
266
339
|
notifications_json_response = @monitoring_incidents_interface.notifications(incident["id"], {max: 10})
|
267
340
|
notification_items = notifications_json_response["notifications"]
|
268
|
-
if notification_items && notification_items.empty?
|
341
|
+
if notification_items && !notification_items.empty?
|
269
342
|
print_h2 "Notifications"
|
270
343
|
print_incident_notifications_table(notification_items, options)
|
271
344
|
print_results_pagination(notifications_json_response, {:label => "notification", :n_label => "notifications"})
|
@@ -374,14 +447,14 @@ class Morpheus::Cli::MonitoringIncidentsCommand
|
|
374
447
|
return 0
|
375
448
|
end
|
376
449
|
notification_items = json_response['notifications']
|
377
|
-
title = "Incident Notifications
|
450
|
+
title = "Incident Notifications [#{incident['id']}] #{incident['displayName'] || incident['name']}"
|
378
451
|
subtitles = []
|
379
452
|
subtitles += parse_list_subtitles(options)
|
380
453
|
print_h1 title, subtitles
|
381
454
|
if notification_items.empty?
|
382
455
|
print cyan,"No notifications found.",reset,"\n"
|
383
456
|
else
|
384
|
-
|
457
|
+
print_incident_notifications_table(notification_items, options)
|
385
458
|
print_results_pagination(json_response, {:label => "notification", :n_label => "notifications"})
|
386
459
|
end
|
387
460
|
print reset,"\n"
|
@@ -396,7 +469,7 @@ class Morpheus::Cli::MonitoringIncidentsCommand
|
|
396
469
|
params = {}
|
397
470
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
398
471
|
opts.banner = subcommand_usage("[id]")
|
399
|
-
opts.on("-c", "--comment STRING", String, "Comment on this incident") do |val|
|
472
|
+
opts.on("-c", "--comment STRING", String, "Comment on this incident. Updates summary field.") do |val|
|
400
473
|
params['comment'] = val == 'null' ? nil : val
|
401
474
|
end
|
402
475
|
opts.on("--resolution STRING", String, "Description of the resolution to this incident") do |val|
|
@@ -467,7 +540,7 @@ class Morpheus::Cli::MonitoringIncidentsCommand
|
|
467
540
|
puts as_json(json_response, options)
|
468
541
|
elsif !options[:quiet]
|
469
542
|
print_green_success "Updated incident #{incident['id']}"
|
470
|
-
_get(incident['id'],
|
543
|
+
_get(incident['id'], options)
|
471
544
|
end
|
472
545
|
|
473
546
|
rescue RestClient::Exception => e
|
@@ -479,10 +552,11 @@ class Morpheus::Cli::MonitoringIncidentsCommand
|
|
479
552
|
|
480
553
|
def mute(args)
|
481
554
|
options = {}
|
482
|
-
params = {
|
555
|
+
params = {}
|
483
556
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
484
557
|
opts.banner = subcommand_usage("[id]")
|
485
558
|
opts.on(nil, "--disable", "Disable mute state instead, the same as unmute") do
|
559
|
+
params['muted'] = false
|
486
560
|
params['enabled'] = false
|
487
561
|
end
|
488
562
|
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :quiet, :remote])
|
@@ -518,7 +592,7 @@ class Morpheus::Cli::MonitoringIncidentsCommand
|
|
518
592
|
else
|
519
593
|
print_green_success "Unmuted incident #{incident['id']}"
|
520
594
|
end
|
521
|
-
_get(incident['id'],
|
595
|
+
_get(incident['id'], options)
|
522
596
|
end
|
523
597
|
return 0
|
524
598
|
rescue RestClient::Exception => e
|
@@ -529,7 +603,7 @@ class Morpheus::Cli::MonitoringIncidentsCommand
|
|
529
603
|
|
530
604
|
def unmute(args)
|
531
605
|
options = {}
|
532
|
-
params = {'enabled' => false}
|
606
|
+
params = {'muted' => false, 'enabled' => false} # enabled was used pre 3.6.5
|
533
607
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
534
608
|
opts.banner = subcommand_usage("[id]")
|
535
609
|
build_common_options(opts, options, [:payload, :json, :dry_run, :quiet, :remote])
|
@@ -562,7 +636,7 @@ class Morpheus::Cli::MonitoringIncidentsCommand
|
|
562
636
|
puts as_json(json_response, options)
|
563
637
|
elsif !options[:quiet]
|
564
638
|
print_green_success "Unmuted incident #{incident['id']}"
|
565
|
-
_get(incident['id'],
|
639
|
+
_get(incident['id'], options)
|
566
640
|
end
|
567
641
|
return 0
|
568
642
|
rescue RestClient::Exception => e
|
@@ -573,7 +647,7 @@ class Morpheus::Cli::MonitoringIncidentsCommand
|
|
573
647
|
|
574
648
|
def mute_all(args)
|
575
649
|
options = {}
|
576
|
-
params = {
|
650
|
+
params = {}
|
577
651
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
578
652
|
opts.banner = subcommand_usage()
|
579
653
|
opts.on(nil, "--disable", "Disable mute state instead, the same as unmute-all") do
|
@@ -621,7 +695,7 @@ class Morpheus::Cli::MonitoringIncidentsCommand
|
|
621
695
|
|
622
696
|
def unmute_all(args)
|
623
697
|
options = {}
|
624
|
-
params = {'enabled' => false}
|
698
|
+
params = {'muted' => false, 'enabled' => false}
|
625
699
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
626
700
|
opts.banner = subcommand_usage()
|
627
701
|
build_common_options(opts, options, [:payload, :json, :dry_run, :quiet, :remote])
|
@@ -698,7 +772,7 @@ class Morpheus::Cli::MonitoringIncidentsCommand
|
|
698
772
|
print "\n"
|
699
773
|
elsif !options[:quiet]
|
700
774
|
print_green_success json_response["msg"] || "Incident #{incident['id']} is now closed"
|
701
|
-
# _get(incident['id']
|
775
|
+
# _get(incident['id'] options)
|
702
776
|
end
|
703
777
|
rescue RestClient::Exception => e
|
704
778
|
print_rest_exception(e, options)
|
@@ -747,7 +821,7 @@ class Morpheus::Cli::MonitoringIncidentsCommand
|
|
747
821
|
print "\n"
|
748
822
|
elsif !options[:quiet]
|
749
823
|
print_green_success json_response["msg"] || "Incident #{incident['id']} is now open"
|
750
|
-
# _get(incident['id']
|
824
|
+
# _get(incident['id'] options)
|
751
825
|
end
|
752
826
|
rescue RestClient::Exception => e
|
753
827
|
print_rest_exception(e, options)
|
@@ -757,58 +831,5 @@ class Morpheus::Cli::MonitoringIncidentsCommand
|
|
757
831
|
|
758
832
|
private
|
759
833
|
|
760
|
-
def print_incidents_table(incidents, opts={})
|
761
|
-
columns = [
|
762
|
-
{"ID" => lambda {|incident| incident['id'] } },
|
763
|
-
{"SEVERITY" => lambda {|incident| format_severity(incident['severity']) } },
|
764
|
-
{"NAME" => lambda {|incident| incident['displayName'] || incident['name'] || 'No Subject' } },
|
765
|
-
{"TIME" => lambda {|incident| format_local_dt(incident['startDate']) } },
|
766
|
-
{"STATUS" => lambda {|incident| format_monitoring_incident_status(incident) } },
|
767
|
-
{"DURATION" => lambda {|incident| format_duration(incident['startDate'], incident['endDate']) } }
|
768
|
-
]
|
769
|
-
if opts[:include_fields]
|
770
|
-
columns = opts[:include_fields]
|
771
|
-
end
|
772
|
-
print as_pretty_table(incidents, columns, opts)
|
773
|
-
end
|
774
|
-
|
775
|
-
def print_incident_history_table(history_items, opts={})
|
776
|
-
columns = [
|
777
|
-
# {"ID" => lambda {|issue| issue['id'] } },
|
778
|
-
{"SEVERITY" => lambda {|issue| format_severity(issue['severity']) } },
|
779
|
-
{"AVAILABLE" => lambda {|issue| format_boolean issue['available'] } },
|
780
|
-
{"TYPE" => lambda {|issue| issue["attachmentType"] } },
|
781
|
-
{"NAME" => lambda {|issue| issue['name'] } },
|
782
|
-
{"DATE CREATED" => lambda {|issue| format_local_dt(issue['startDate']) } }
|
783
|
-
]
|
784
|
-
if opts[:include_fields]
|
785
|
-
columns = opts[:include_fields]
|
786
|
-
end
|
787
|
-
print as_pretty_table(history_items, columns, opts)
|
788
|
-
end
|
789
|
-
|
790
|
-
def print_incident_notifications_table(notifications, opts={})
|
791
|
-
columns = [
|
792
|
-
{"NAME" => lambda {|notification| notification['recipient'] ? notification['recipient']['name'] : '' } },
|
793
|
-
{"DELIVERY TYPE" => lambda {|notification| notification['addressTypes'].to_s } },
|
794
|
-
{"NOTIFIED ON" => lambda {|notification| format_local_dt(notification['dateCreated']) } },
|
795
|
-
# {"AVAILABLE" => lambda {|notification| format_boolean notification['available'] } },
|
796
|
-
# {"TYPE" => lambda {|notification| notification["attachmentType"] } },
|
797
|
-
# {"NAME" => lambda {|notification| notification['name'] } },
|
798
|
-
{"DATE CREATED" => lambda {|notification|
|
799
|
-
date_str = format_local_dt(notification['startDate']).to_s
|
800
|
-
if notification['pendingUtil']
|
801
|
-
"(pending) #{date_str}"
|
802
|
-
else
|
803
|
-
date_str
|
804
|
-
end
|
805
|
-
} }
|
806
|
-
]
|
807
|
-
#event['pendingUntil']
|
808
|
-
if opts[:include_fields]
|
809
|
-
columns = opts[:include_fields]
|
810
|
-
end
|
811
|
-
print as_pretty_table(notifications, columns, opts)
|
812
|
-
end
|
813
834
|
|
814
835
|
end
|
@@ -229,14 +229,20 @@ class Morpheus::Cli::NetworkPoolsCommand
|
|
229
229
|
end
|
230
230
|
|
231
231
|
# Network Pool Type
|
232
|
-
|
232
|
+
network_type_code = nil
|
233
233
|
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'type', 'fieldLabel' => 'Pool Type', 'type' => 'select', 'optionSource' => 'networkPoolTypes', 'required' => true, 'description' => 'Choose a network pool type.'}], options, @api_client, {})
|
234
|
-
|
235
|
-
if
|
236
|
-
print_red_alert "Pool Type not found by
|
234
|
+
network_type_code = v_prompt['type']
|
235
|
+
if network_type_code.nil? || network_type_code.to_s.empty?
|
236
|
+
print_red_alert "Pool Type not found by code '#{options['type']}'"
|
237
237
|
return 1
|
238
238
|
end
|
239
|
-
|
239
|
+
# pre 4.1.1 expects ID
|
240
|
+
if network_type_code.to_s =~ /\A\d{1,}\Z/
|
241
|
+
payload['networkPool']['type'] = {'id' => network_type_code }
|
242
|
+
else
|
243
|
+
payload['networkPool']['type'] = {'code' => network_type_code }
|
244
|
+
end
|
245
|
+
# payload['networkPool']['type'] = network_type_code # this works too, simpler
|
240
246
|
|
241
247
|
# IP Ranges
|
242
248
|
if ip_range_list
|
@@ -283,9 +289,29 @@ class Morpheus::Cli::NetworkPoolsCommand
|
|
283
289
|
opts.on('--name VALUE', String, "Name for this network pool") do |val|
|
284
290
|
options['name'] = val
|
285
291
|
end
|
286
|
-
opts.on('--
|
287
|
-
options['
|
288
|
-
end
|
292
|
+
opts.on('--code VALUE', String, "Code") do |val|
|
293
|
+
options['code'] = val
|
294
|
+
end
|
295
|
+
opts.on('--category VALUE', String, "Category") do |val|
|
296
|
+
options['category'] = val
|
297
|
+
end
|
298
|
+
# todo all of these
|
299
|
+
# internalId
|
300
|
+
# externalId
|
301
|
+
# dnsDomain
|
302
|
+
# dnsSearchPath
|
303
|
+
# hostPrefix
|
304
|
+
# httpProxy
|
305
|
+
# dnsServers
|
306
|
+
# dnsSuffixList
|
307
|
+
# dhcpServer
|
308
|
+
# dhcpIp
|
309
|
+
# gateway
|
310
|
+
# netmask
|
311
|
+
# subnetAddress
|
312
|
+
# poolEnabled
|
313
|
+
# tftpServer
|
314
|
+
# bootFile
|
289
315
|
opts.on('--ip-ranges LIST', Array, "IP Ranges, comma separated list IP ranges in the format start-end.") do |list|
|
290
316
|
if list.size == 1 && list[0] == 'null' # hacky way to clear it
|
291
317
|
ip_range_list = []
|
@@ -333,22 +359,12 @@ class Morpheus::Cli::NetworkPoolsCommand
|
|
333
359
|
# Name
|
334
360
|
if options['name']
|
335
361
|
payload['networkPool']['name'] = options['name']
|
336
|
-
else
|
337
|
-
# v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'description' => 'Name for this network pool.'}], options)
|
338
|
-
# payload['networkPool']['name'] = v_prompt['name']
|
339
362
|
end
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
# if network_type_id.nil? || network_type_id.to_s.empty?
|
346
|
-
# print_red_alert "Pool Type not found by id '#{options['type']}'"
|
347
|
-
# return 1
|
348
|
-
# end
|
349
|
-
# payload['networkPool']['type'] = {'id' => network_type_id.to_i }
|
350
|
-
if options['type']
|
351
|
-
payload['networkPool']['type'] = {'id' => options['type'].to_i }
|
363
|
+
if options['category']
|
364
|
+
payload['networkPool']['category'] = options['category']
|
365
|
+
end
|
366
|
+
if options['code']
|
367
|
+
payload['networkPool']['code'] = options['code']
|
352
368
|
end
|
353
369
|
|
354
370
|
# IP Ranges
|
@@ -745,7 +745,7 @@ class Morpheus::Cli::PowerSchedulesCommand
|
|
745
745
|
end
|
746
746
|
|
747
747
|
def find_instance_by_name(name)
|
748
|
-
instances = @instances_interface.
|
748
|
+
instances = @instances_interface.list({name: name.to_s})['instances']
|
749
749
|
if instances.empty?
|
750
750
|
print_red_alert "Instance not found by name #{name}"
|
751
751
|
return nil
|
data/lib/morpheus/cli/remote.rb
CHANGED
@@ -11,31 +11,35 @@ require 'morpheus/cli/cli_command'
|
|
11
11
|
class Morpheus::Cli::Remote
|
12
12
|
include Morpheus::Cli::CliCommand
|
13
13
|
|
14
|
-
register_subcommands :list, :add, :get, :update, :remove, :use, :unuse, :current
|
14
|
+
register_subcommands :list, :add, :get, :update, :rename, :remove, :use, :unuse, :current
|
15
|
+
register_subcommands :setup, :teardown, :check, :'check-all'
|
16
|
+
|
15
17
|
set_default_subcommand :list
|
16
18
|
|
17
19
|
def initialize()
|
18
20
|
@appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
|
19
21
|
end
|
20
22
|
|
23
|
+
def connect(opts={})
|
24
|
+
connect_opts = {:skip_verify_access_token => true}.merge(opts)
|
25
|
+
@api_client = establish_remote_appliance_connection(connect_opts)
|
26
|
+
@setup_interface = @api_client.setup
|
27
|
+
end
|
28
|
+
|
21
29
|
def handle(args)
|
22
|
-
# if args.count == 0
|
23
|
-
# list(args)
|
24
|
-
# else
|
25
|
-
# handle_subcommand(args)
|
26
|
-
# end
|
27
30
|
handle_subcommand(args)
|
28
31
|
end
|
29
32
|
|
30
33
|
def list(args)
|
31
34
|
options = {}
|
35
|
+
params = {}
|
32
36
|
show_all_activity = false
|
33
37
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
34
38
|
opts.banner = subcommand_usage()
|
35
39
|
opts.on("-a",'--all', "Show all the appliance activity details") do
|
36
40
|
show_all_activity = true
|
37
41
|
end
|
38
|
-
build_common_options(opts, options, [:json, :yaml, :csv, :fields])
|
42
|
+
build_common_options(opts, options, [:list, :json, :yaml, :csv, :fields])
|
39
43
|
opts.footer = <<-EOT
|
40
44
|
This outputs a list of the configured remote appliances. It also indicates
|
41
45
|
the current appliance. The current appliance is where morpheus will send
|
@@ -44,10 +48,11 @@ EOT
|
|
44
48
|
end
|
45
49
|
optparse.parse!(args)
|
46
50
|
if args.count > 0
|
47
|
-
|
51
|
+
raise_command_error "wrong number of arguments, expected 0 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
|
48
52
|
end
|
49
|
-
|
50
|
-
|
53
|
+
#connect(options)
|
54
|
+
params.merge!(parse_list_options(options))
|
55
|
+
appliances = ::Morpheus::Cli::Remote.load_all_remotes(params)
|
51
56
|
# if appliances.empty?
|
52
57
|
# raise_command_error "You have no appliances configured. See the `remote add` command."
|
53
58
|
# end
|
@@ -63,13 +68,16 @@ EOT
|
|
63
68
|
puts records_as_csv(appliances, options)
|
64
69
|
return 0
|
65
70
|
end
|
66
|
-
|
67
|
-
print_h1 "Morpheus Appliances", [], options
|
68
71
|
if appliances.empty?
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
+
if params[:phrase]
|
73
|
+
print cyan,"0 remotes matched '#{params[:phrase]}'", reset, "\n"
|
74
|
+
else
|
75
|
+
print yellow,"You have no appliances configured. See the `remote add` command.", reset, "\n"
|
76
|
+
end
|
72
77
|
else
|
78
|
+
title = "Morpheus Appliances"
|
79
|
+
subtitles = parse_list_subtitles(options)
|
80
|
+
print_h1 title, subtitles, options
|
73
81
|
print cyan
|
74
82
|
columns = [
|
75
83
|
{:active => {:display_name => "", :display_method => lambda {|it| it[:active] ? "=>" : "" } } },
|
@@ -89,7 +97,7 @@ EOT
|
|
89
97
|
print cyan, "\n# => #{@appliance_name} is the current remote appliance\n", reset
|
90
98
|
#end
|
91
99
|
else
|
92
|
-
print "\n# => No current remote appliance, see `remote use`\n", reset
|
100
|
+
print cyan, "\n# => No current remote appliance, see `remote use`\n", reset
|
93
101
|
end
|
94
102
|
print reset, "\n"
|
95
103
|
end
|
@@ -102,12 +110,12 @@ EOT
|
|
102
110
|
params = {}
|
103
111
|
new_appliance_map = {}
|
104
112
|
use_it = false
|
105
|
-
|
113
|
+
secure = nil
|
106
114
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
107
115
|
banner = subcommand_usage("[name] [url]")
|
108
116
|
banner_args = <<-EOT
|
109
117
|
[name] The name for your appliance. eg. mymorph
|
110
|
-
[url] The url of your appliance eg. https://
|
118
|
+
[url] The url of your appliance eg. https://demo.mymorpheus.com
|
111
119
|
EOT
|
112
120
|
opts.banner = banner + "\n" + banner_args
|
113
121
|
opts.on(nil, '--use', "Make this the current appliance" ) do
|
@@ -120,26 +128,23 @@ EOT
|
|
120
128
|
new_appliance_map[:active] = true
|
121
129
|
end
|
122
130
|
opts.on(nil, "--secure", "Prevent insecure HTTPS communication. This is enabled by default.") do
|
123
|
-
|
131
|
+
secure = true
|
124
132
|
end
|
125
133
|
opts.on(nil, "--insecure", "Allow insecure HTTPS communication. i.e. Ignore SSL errors.") do
|
126
|
-
|
134
|
+
secure = false
|
127
135
|
end
|
128
136
|
build_common_options(opts, options, [:quiet])
|
129
137
|
opts.footer = <<-EOT
|
130
138
|
This will add a new remote appliance to your morpheus client configuration.
|
131
|
-
If
|
132
|
-
it will
|
139
|
+
If this is your first remote, --use is automatically applied so
|
140
|
+
it will become the current remote appliance.
|
133
141
|
This command will prompt you to login and/or setup a fresh appliance.
|
134
|
-
|
142
|
+
To skip login/setup, use the --quiet option.
|
135
143
|
EOT
|
136
144
|
end
|
137
145
|
optparse.parse!(args)
|
138
|
-
if args.count
|
139
|
-
|
140
|
-
puts_error "#{command_name} add expects 2 arguments: [name] [url]"
|
141
|
-
puts_error optparse
|
142
|
-
return 1
|
146
|
+
if args.count > 2
|
147
|
+
raise_command_error "wrong number of arguments, expected 0-2 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
|
143
148
|
end
|
144
149
|
|
145
150
|
# load current appliances
|
@@ -150,40 +155,75 @@ EOT
|
|
150
155
|
new_appliance_map[:active] = true
|
151
156
|
end
|
152
157
|
|
153
|
-
|
154
|
-
|
155
|
-
# and save it in the config file
|
156
|
-
new_appliance_name = args[0].to_sym
|
158
|
+
new_appliance_name = args[0] if args[0]
|
159
|
+
url = args[1] if args[1]
|
157
160
|
|
158
|
-
#
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
161
|
+
# Name
|
162
|
+
still_prompting = true
|
163
|
+
while still_prompting do
|
164
|
+
if new_appliance_name.to_s.empty?
|
165
|
+
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])
|
166
|
+
new_appliance_name = v_prompt['name']
|
167
|
+
end
|
168
|
+
|
169
|
+
# 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."
|
172
|
+
new_appliance_name = nil
|
173
|
+
end
|
174
|
+
# unique name
|
175
|
+
existing_appliance = appliances[new_appliance_name.to_sym]
|
176
|
+
if existing_appliance
|
177
|
+
print_error red,"The specified appliance name '#{new_appliance_name}' already exists with the URL #{existing_appliance[:url] || existing_appliance[:host]}",reset,"\n"
|
178
|
+
new_appliance_name = nil
|
179
|
+
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
|
187
|
+
still_prompting = false
|
188
|
+
end
|
165
189
|
end
|
166
|
-
new_appliance_map[:name] = new_appliance_name
|
167
190
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
191
|
+
new_appliance_map[:name] = new_appliance_name.to_sym
|
192
|
+
|
193
|
+
# URL
|
194
|
+
still_prompting = true
|
195
|
+
while still_prompting do
|
196
|
+
if !url
|
197
|
+
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'}], options[:options])
|
198
|
+
url = v_prompt['url']
|
199
|
+
end
|
200
|
+
|
201
|
+
if url !~ /^https?\:\/\/.+/
|
202
|
+
print_error red,"The specified appliance url '#{url}' is invalid.",reset,"\n"
|
203
|
+
still_prompting = true
|
204
|
+
url = nil
|
205
|
+
else
|
206
|
+
still_prompting = false
|
207
|
+
end
|
172
208
|
end
|
173
|
-
|
174
|
-
|
209
|
+
|
210
|
+
# let's replace :host with :url
|
211
|
+
new_appliance_map[:host] = url
|
212
|
+
new_appliance_map[:url] = url
|
213
|
+
|
214
|
+
# Insecure?
|
215
|
+
if url.include?('https:') && secure.nil?
|
216
|
+
# This is kind of annoying to always see, just default to true, use --insecure if you need to.
|
217
|
+
#v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'secure', 'fieldLabel' => 'Secure', 'type' => 'checkbox', 'required' => false, 'defaultValue' => true, 'description' => 'Prevent insecure HTTPS communication. This is enabled by default.'}], options[:options])
|
218
|
+
#secure = v_prompt['secure'].to_s == 'true' || v_prompt['secure'].to_s == 'on'
|
175
219
|
end
|
176
220
|
|
177
|
-
|
178
|
-
|
179
|
-
raise_command_error "The specified appliance url is invalid: '#{args[1]}'"
|
180
|
-
#puts optparse
|
181
|
-
return 1
|
221
|
+
if secure == false
|
222
|
+
new_appliance_map[:insecure] = true
|
182
223
|
end
|
183
|
-
new_appliance_map[:host] = url
|
184
224
|
|
185
225
|
# save it
|
186
|
-
appliance = ::Morpheus::Cli::Remote.save_remote(new_appliance_name, new_appliance_map)
|
226
|
+
appliance = ::Morpheus::Cli::Remote.save_remote(new_appliance_name.to_sym, new_appliance_map)
|
187
227
|
|
188
228
|
if !options[:quiet]
|
189
229
|
# print_green_success "Added remote #{new_appliance_name}"
|
@@ -195,7 +235,7 @@ EOT
|
|
195
235
|
print cyan
|
196
236
|
puts "Inspecting remote appliance url: #{appliance[:host]} ..."
|
197
237
|
end
|
198
|
-
appliance = ::Morpheus::Cli::Remote.refresh_remote(new_appliance_name)
|
238
|
+
appliance, check_json_response = ::Morpheus::Cli::Remote.refresh_remote(new_appliance_name.to_sym)
|
199
239
|
if !options[:quiet]
|
200
240
|
print cyan
|
201
241
|
puts "Status is: #{format_appliance_status(appliance)}"
|
@@ -215,10 +255,23 @@ EOT
|
|
215
255
|
return exit_code, err
|
216
256
|
end
|
217
257
|
|
258
|
+
if options[:json]
|
259
|
+
puts as_json(check_json_response, options)
|
260
|
+
return exit_code, err
|
261
|
+
end
|
262
|
+
|
218
263
|
# check_cmd_result = check_appliance([new_appliance_name, "--quiet"])
|
219
264
|
# check_cmd_result = check_appliance([new_appliance_name])
|
220
265
|
|
221
266
|
if appliance[:status] == 'fresh' # || appliance[:setup_needed] == true
|
267
|
+
|
268
|
+
if !appliance[:active]
|
269
|
+
if ::Morpheus::Cli::OptionTypes::confirm("Would you like to switch to using this remote now?", options.merge({default: true}))
|
270
|
+
use([appliance[:name]])
|
271
|
+
appliance[:active] = true # just in case, could reload instead with load_active_remote()
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
222
275
|
print cyan
|
223
276
|
puts "It looks like this appliance needs to be setup. Starting setup ..."
|
224
277
|
return setup([new_appliance_name])
|
@@ -274,58 +327,33 @@ EOT
|
|
274
327
|
options = {}
|
275
328
|
checkall = false
|
276
329
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
277
|
-
opts.banner =
|
278
|
-
|
279
|
-
[name] is required. This is the name of the remote. Use 'current' to check the active appliance."
|
280
|
-
EOT
|
281
|
-
#opts.banner = "#{opts.banner}\n" + " " + "[name] is required. This is the name of the remote. Use 'current' to check the active appliance."
|
282
|
-
opts.on("-a",'--all', "Refresh all appliances") do
|
283
|
-
checkall = true
|
284
|
-
end
|
285
|
-
build_common_options(opts, options, [:quiet])
|
330
|
+
opts.banner = subcommand_usage("[name]")
|
331
|
+
build_common_options(opts, options, [:json, :yaml, :csv, :fields, :quiet, :dry_run, :remote])
|
286
332
|
opts.footer = <<-EOT
|
287
|
-
|
288
|
-
|
289
|
-
|
333
|
+
Check the status of a remote appliance.
|
334
|
+
[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.
|
335
|
+
This makes a request to the configured appliance url and updates the status and version.
|
290
336
|
EOT
|
291
337
|
end
|
292
338
|
optparse.parse!(args)
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
# id_list = ::Morpheus::Cli::Remote.appliances.keys # sort ?
|
297
|
-
return _check_all_appliances()
|
298
|
-
elsif args.count < 1
|
299
|
-
print_error Morpheus::Terminal.angry_prompt
|
300
|
-
puts_error "#{command_name} update expects argument [name] or option --all"
|
301
|
-
puts_error optparse
|
302
|
-
return 1
|
339
|
+
|
340
|
+
if args.count == 0
|
341
|
+
id_list = ['current']
|
303
342
|
else
|
304
343
|
id_list = parse_id_list(args)
|
305
344
|
end
|
345
|
+
# trick for remote check all
|
346
|
+
if id_list.length == 1 && id_list[0].to_s.downcase == 'all'
|
347
|
+
return _check_all_appliances(options)
|
348
|
+
end
|
306
349
|
#connect(options)
|
307
350
|
return run_command_for_each_arg(id_list) do |arg|
|
308
351
|
_check_appliance(arg, options)
|
309
352
|
end
|
310
353
|
end
|
311
354
|
|
312
|
-
def _check_all_appliances()
|
313
|
-
# reresh all appliances and then display the list view
|
314
|
-
id_list = ::Morpheus::Cli::Remote.appliances.keys # sort ?
|
315
|
-
if id_list.size > 1
|
316
|
-
print cyan
|
317
|
-
print "Checking #{id_list.size} appliances "
|
318
|
-
end
|
319
|
-
id_list.each do |appliance_name|
|
320
|
-
print "."
|
321
|
-
::Morpheus::Cli::Remote.refresh_remote(appliance_name)
|
322
|
-
end
|
323
|
-
print "\n"
|
324
|
-
list([])
|
325
|
-
|
326
|
-
end
|
327
|
-
|
328
355
|
def _check_appliance(appliance_name, options)
|
356
|
+
exit_code, err = 0, nil
|
329
357
|
begin
|
330
358
|
appliance = nil
|
331
359
|
if appliance_name == "current"
|
@@ -337,35 +365,35 @@ EOT
|
|
337
365
|
else
|
338
366
|
appliance = ::Morpheus::Cli::Remote.load_remote(appliance_name)
|
339
367
|
if !appliance
|
340
|
-
raise_command_error "Remote
|
368
|
+
raise_command_error "Remote not found by the name '#{appliance_name}'"
|
341
369
|
end
|
342
370
|
end
|
343
371
|
|
344
|
-
# found appliance
|
345
|
-
# now refresh it
|
372
|
+
# found appliance, now refresh it
|
346
373
|
|
347
374
|
start_time = Time.now
|
348
375
|
|
349
|
-
|
376
|
+
# print cyan
|
377
|
+
# print "Checking remote url: #{appliance[:host]} ..."
|
350
378
|
|
351
|
-
appliance = ::Morpheus::Cli::Remote.refresh_remote(appliance_name)
|
379
|
+
appliance, check_json_response = ::Morpheus::Cli::Remote.refresh_remote(appliance_name)
|
352
380
|
|
353
381
|
took_sec = (Time.now - start_time)
|
354
382
|
|
355
|
-
|
356
|
-
return 0
|
357
|
-
end
|
383
|
+
exit_code = (appliance[:status] == 'ready' || appliance[:status] == 'fresh') ? 0 : 1
|
358
384
|
|
359
|
-
|
385
|
+
if exit_code == 0
|
386
|
+
if appliance[:error]
|
387
|
+
exit_code = 1
|
388
|
+
err = "Check Failed: #{appliance[:error]}"
|
389
|
+
end
|
390
|
+
end
|
360
391
|
|
361
|
-
|
392
|
+
render_result = render_with_format(check_json_response, options)
|
393
|
+
return exit_code if render_result
|
362
394
|
|
363
|
-
#
|
364
|
-
# print JSON.pretty_generate(json_response), "\n"
|
365
|
-
# return
|
366
|
-
# end
|
395
|
+
print_green_success "Completed remote check of #{appliance_name} in #{took_sec.round(3)}s"
|
367
396
|
|
368
|
-
# show user latest info
|
369
397
|
return _get(appliance[:name], {})
|
370
398
|
|
371
399
|
rescue RestClient::Exception => e
|
@@ -374,16 +402,119 @@ EOT
|
|
374
402
|
end
|
375
403
|
end
|
376
404
|
|
405
|
+
def check_all(args)
|
406
|
+
options = {}
|
407
|
+
checkall = false
|
408
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
409
|
+
opts.banner = subcommand_usage()
|
410
|
+
build_common_options(opts, options, [:quiet])
|
411
|
+
opts.footer = <<-EOT
|
412
|
+
Refresh all remote appliances.
|
413
|
+
This makes a request to each of the configured appliance urls and updates the status and version.
|
414
|
+
EOT
|
415
|
+
end
|
416
|
+
optparse.parse!(args)
|
417
|
+
|
418
|
+
if args.count != 0
|
419
|
+
raise_command_error "wrong number of arguments, expected 0-1 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
|
420
|
+
end
|
421
|
+
connect() # needed?
|
422
|
+
_check_all_appliances(options)
|
423
|
+
end
|
424
|
+
|
425
|
+
def _check_all_appliances(options)
|
426
|
+
start_time = Time.now
|
427
|
+
# reresh all appliances and then display the list view
|
428
|
+
id_list = ::Morpheus::Cli::Remote.appliances.keys # sort ?
|
429
|
+
if id_list.size > 1
|
430
|
+
print cyan
|
431
|
+
puts "Checking #{id_list.size} appliances"
|
432
|
+
elsif id_list.size == 1
|
433
|
+
puts "Checking #{Morpheus::Cli::Remote.appliances.keys.first}"
|
434
|
+
end
|
435
|
+
id_list.each do |appliance_name|
|
436
|
+
#print "."
|
437
|
+
appliance, check_json_response = ::Morpheus::Cli::Remote.refresh_remote(appliance_name)
|
438
|
+
end
|
439
|
+
took_sec = (Time.now - start_time)
|
440
|
+
print_green_success "Completed remote check of #{id_list.size} #{id_list.size == 1 ? 'appliance' : 'appliances'} in #{took_sec.round(3)}s"
|
441
|
+
|
442
|
+
if options[:quiet]
|
443
|
+
return 0
|
444
|
+
end
|
445
|
+
list([])
|
446
|
+
return 0
|
447
|
+
end
|
448
|
+
|
449
|
+
def rename(args)
|
450
|
+
options = {}
|
451
|
+
params = {}
|
452
|
+
use_it = false
|
453
|
+
is_insecure = nil
|
454
|
+
new_name = nil
|
455
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
456
|
+
opts.banner = subcommand_usage("[name] [new name]")
|
457
|
+
opts.on(nil, "--name NAME", "Update the name of your remote appliance") do |val|
|
458
|
+
new_name = val
|
459
|
+
end
|
460
|
+
|
461
|
+
# opts.on(nil, '--use', "Make this the current appliance" ) do
|
462
|
+
# use_it = true
|
463
|
+
# params[:active] = true
|
464
|
+
# end
|
465
|
+
build_common_options(opts, options, [:auto_confirm, :quiet])
|
466
|
+
opts.footer = <<-EOT
|
467
|
+
Rename a remote.
|
468
|
+
This changes your client configuration remote name, not the appliance itself.
|
469
|
+
[name] is required. This is the current name of a remote.
|
470
|
+
[new name] is required. This is the new name for the remote. This must not already be in use.
|
471
|
+
EOT
|
472
|
+
end
|
473
|
+
optparse.parse!(args)
|
474
|
+
if args.count != 2
|
475
|
+
print_error Morpheus::Terminal.angry_prompt
|
476
|
+
puts_error "#{command_name} rename expects argument [name]."
|
477
|
+
puts_error optparse
|
478
|
+
return 1
|
479
|
+
end
|
480
|
+
appliance_name = args[0].to_sym
|
481
|
+
new_appliance_name = args[1].to_sym
|
482
|
+
appliance = ::Morpheus::Cli::Remote.load_remote(appliance_name)
|
483
|
+
if !appliance
|
484
|
+
raise_command_error "Remote appliance not found by the name '#{appliance_name}'"
|
485
|
+
end
|
486
|
+
# don't allow overwrite yet
|
487
|
+
matching_appliance = ::Morpheus::Cli::Remote.load_remote(new_appliance_name)
|
488
|
+
if matching_appliance
|
489
|
+
raise_command_error "Remote appliance already exists with the name '#{new_appliance_name}'"
|
490
|
+
end
|
491
|
+
|
492
|
+
unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like to rename #{appliance_name} to #{new_appliance_name}?", options)
|
493
|
+
return 9, "aborted command"
|
494
|
+
end
|
495
|
+
# this does all the work
|
496
|
+
::Morpheus::Cli::Remote.rename_remote(appliance_name, new_appliance_name)
|
497
|
+
|
498
|
+
print_green_success "Renamed remote #{appliance_name} to #{new_appliance_name}"
|
499
|
+
# todo: just go ahead and refresh it now...
|
500
|
+
# _check(appliance_name, {:quiet => true})
|
501
|
+
# appliance, check_json_response = ::Morpheus::Cli::Remote.refresh_remote(new_appliance_name)
|
502
|
+
# print new appliance details
|
503
|
+
_get(new_appliance_name, {})
|
504
|
+
return 0, nil
|
505
|
+
end
|
506
|
+
|
377
507
|
def update(args)
|
378
508
|
options = {}
|
379
509
|
params = {}
|
380
510
|
use_it = false
|
381
511
|
is_insecure = nil
|
512
|
+
new_name = nil
|
382
513
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
383
514
|
opts.banner = subcommand_usage("[name]")
|
384
|
-
|
385
|
-
|
386
|
-
|
515
|
+
opts.on(nil, "--name NAME", "Update the name of your remote appliance") do |val|
|
516
|
+
new_name = val
|
517
|
+
end
|
387
518
|
opts.on("--url URL", String, "Update the url of your remote appliance") do |val|
|
388
519
|
params[:host] = val
|
389
520
|
end
|
@@ -437,7 +568,7 @@ EOT
|
|
437
568
|
print_green_success "Updated remote #{appliance_name}"
|
438
569
|
# todo: just go ahead and refresh it now...
|
439
570
|
# _check(appliance_name, {:quiet => true})
|
440
|
-
appliance = ::Morpheus::Cli::Remote.refresh_remote(appliance_name)
|
571
|
+
appliance, check_json_response = ::Morpheus::Cli::Remote.refresh_remote(appliance_name)
|
441
572
|
# print new appliance details
|
442
573
|
_get(appliance[:name], {})
|
443
574
|
return 0, nil
|
@@ -467,37 +598,56 @@ EOT
|
|
467
598
|
end
|
468
599
|
|
469
600
|
def _get(appliance_name, options)
|
601
|
+
exit_code, err = 0, nil
|
470
602
|
begin
|
471
603
|
appliance = nil
|
472
604
|
if appliance_name == "current"
|
473
605
|
appliance = ::Morpheus::Cli::Remote.load_active_remote()
|
474
606
|
if !appliance
|
475
|
-
|
607
|
+
err = "No current appliance, see `remote use`."
|
608
|
+
exit_code = 1
|
476
609
|
end
|
477
610
|
appliance_name = appliance[:name]
|
478
611
|
else
|
479
612
|
appliance = ::Morpheus::Cli::Remote.load_remote(appliance_name)
|
480
613
|
if !appliance
|
481
|
-
|
614
|
+
err = "Remote appliance not found by the name '#{appliance_name}'"
|
615
|
+
exit_code = 1
|
482
616
|
end
|
483
617
|
end
|
484
618
|
|
619
|
+
if options[:quiet]
|
620
|
+
return exit_code, err
|
621
|
+
end
|
622
|
+
|
485
623
|
if options[:json]
|
486
|
-
json_response = {
|
487
|
-
puts as_json(json_response, options)
|
488
|
-
return
|
624
|
+
json_response = {'appliance' => appliance} # mock payload
|
625
|
+
puts as_json(json_response, options, "appliance")
|
626
|
+
return exit_code, err
|
489
627
|
end
|
490
628
|
|
491
|
-
if options[:
|
492
|
-
|
493
|
-
|
629
|
+
if options[:yaml]
|
630
|
+
json_response = {'appliance' => appliance} # mock payload
|
631
|
+
puts as_yaml(json_response, options, "appliance")
|
632
|
+
return exit_code, err
|
494
633
|
end
|
495
|
-
# expando
|
496
|
-
# appliance = OStruct.new(appliance)
|
497
634
|
|
498
|
-
|
499
|
-
|
500
|
-
|
635
|
+
|
636
|
+
|
637
|
+
if options[:url_only]
|
638
|
+
if appliance
|
639
|
+
print cyan, (appliance[:url] || appliance[:host]),"\n",reset
|
640
|
+
return exit_code, err
|
641
|
+
else
|
642
|
+
print_error red, err,"\n",reset
|
643
|
+
return exit_code, err
|
644
|
+
end
|
645
|
+
end
|
646
|
+
|
647
|
+
if exit_code != 0
|
648
|
+
print_error red, err,"\n",reset
|
649
|
+
return exit_code, err
|
650
|
+
end
|
501
651
|
|
502
652
|
if appliance[:active]
|
503
653
|
# print_h1 "Current Remote Appliance: #{appliance[:name]}"
|
@@ -542,39 +692,58 @@ EOT
|
|
542
692
|
options = {}
|
543
693
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
544
694
|
opts.banner = subcommand_usage("[name]")
|
545
|
-
# opts.on( '-f', '--force', "Remote appliance anyway??" ) do
|
546
|
-
# options[:default] = true
|
547
|
-
# end
|
548
|
-
opts.footer = "This will delete an appliance from your list."
|
549
695
|
build_common_options(opts, options, [:auto_confirm, :quiet])
|
696
|
+
opts.footer = <<-EOT
|
697
|
+
This will delete the specified remote appliance(s) from your local configuration.
|
698
|
+
[name] is required. This is the name of a remote. More than one can be passed.
|
699
|
+
EOT
|
550
700
|
end
|
551
701
|
optparse.parse!(args)
|
552
|
-
if args.count
|
553
|
-
#
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
return 1, nil
|
702
|
+
if args.count == 0
|
703
|
+
#id_list = ['current']
|
704
|
+
raise_command_error "wrong number of arguments, expected 1-N and got 0\n#{optparse}"
|
705
|
+
else
|
706
|
+
id_list = parse_id_list(args)
|
558
707
|
end
|
559
|
-
|
708
|
+
#connect(options)
|
709
|
+
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)
|
710
|
+
return 9, "aborted command"
|
711
|
+
end
|
712
|
+
return run_command_for_each_arg(id_list) do |arg|
|
713
|
+
_remove_appliance(arg, options)
|
714
|
+
end
|
715
|
+
end
|
716
|
+
|
717
|
+
def _remove_appliance(appliance_name, options)
|
718
|
+
|
719
|
+
appliance_name = appliance_name.to_sym
|
560
720
|
appliance = ::Morpheus::Cli::Remote.load_remote(appliance_name)
|
561
721
|
if !appliance
|
562
722
|
raise_command_error "Remote appliance not found by the name '#{appliance_name}'"
|
563
723
|
end
|
564
|
-
|
565
|
-
|
724
|
+
|
725
|
+
|
726
|
+
appliances = ::Morpheus::Cli::Remote.appliances
|
727
|
+
|
728
|
+
if appliances[appliance_name].nil?
|
729
|
+
if options[:quiet]
|
730
|
+
return 1
|
731
|
+
end
|
732
|
+
print_red_alert "Remote does not exist with name '#{appliance_name.to_s}'"
|
733
|
+
return 1
|
566
734
|
end
|
567
735
|
|
568
736
|
# ok, delete it
|
737
|
+
|
569
738
|
::Morpheus::Cli::Remote.delete_remote(appliance_name)
|
570
739
|
|
571
740
|
# return result
|
572
741
|
if options[:quiet]
|
573
|
-
return 0
|
742
|
+
return 0
|
574
743
|
end
|
575
744
|
print_green_success "Deleted remote #{appliance_name}"
|
576
|
-
list([])
|
577
|
-
return 0
|
745
|
+
# list([])
|
746
|
+
return 0
|
578
747
|
end
|
579
748
|
|
580
749
|
def use(args)
|
@@ -587,36 +756,37 @@ EOT
|
|
587
756
|
"You may override this with the --remote option in your commands."
|
588
757
|
end
|
589
758
|
optparse.parse!(args)
|
590
|
-
if args.count
|
759
|
+
if args.count != 1
|
591
760
|
print_error Morpheus::Terminal.angry_prompt
|
592
761
|
puts_error "#{command_name} use expects argument [name]."
|
593
762
|
puts_error optparse
|
594
763
|
return 1
|
595
764
|
end
|
765
|
+
current_appliance_name, current_appliance_url = @appliance_name, @appliance_url
|
596
766
|
appliance_name = args[0].to_sym
|
597
767
|
appliance = ::Morpheus::Cli::Remote.load_remote(appliance_name)
|
598
768
|
if !appliance
|
599
769
|
raise_command_error "Remote appliance not found by the name '#{appliance_name}'"
|
600
770
|
end
|
601
771
|
|
602
|
-
if appliance[:active] == true
|
603
|
-
if !options[:quiet]
|
604
|
-
print cyan
|
605
|
-
puts "Using remote #{appliance_name} (still)"
|
606
|
-
end
|
607
|
-
return true
|
608
|
-
end
|
609
772
|
# appliance = ::Morpheus::Cli::Remote.set_active_appliance(appliance_name)
|
610
773
|
appliance[:active] = true
|
611
774
|
appliance = ::Morpheus::Cli::Remote.save_remote(appliance_name, appliance)
|
775
|
+
|
776
|
+
if options[:quiet]
|
777
|
+
return 0
|
778
|
+
end
|
779
|
+
|
780
|
+
if current_appliance_name.to_s == appliance_name.to_s
|
781
|
+
print green, "Using remote #{appliance_name} (still)", reset, "\n"
|
782
|
+
else
|
783
|
+
print green, "Using remote #{appliance_name}", reset, "\n"
|
784
|
+
end
|
612
785
|
|
613
786
|
# recalculate session variables
|
614
787
|
::Morpheus::Cli::Remote.recalculate_variable_map()
|
615
788
|
|
616
|
-
|
617
|
-
puts "#{cyan}Using remote #{appliance_name}#{reset}"
|
618
|
-
end
|
619
|
-
return true
|
789
|
+
return 0
|
620
790
|
end
|
621
791
|
|
622
792
|
def unuse(args)
|
@@ -624,18 +794,21 @@ EOT
|
|
624
794
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
625
795
|
opts.banner = subcommand_usage()
|
626
796
|
opts.footer = "" +
|
627
|
-
"This clears the current remote appliance.\n"
|
628
|
-
"You will need to use an appliance, or pass the --remote option to your commands."
|
797
|
+
"This clears the current remote appliance.\n"
|
629
798
|
build_common_options(opts, options, [])
|
630
799
|
end
|
631
800
|
optparse.parse!(args)
|
801
|
+
if args.count != 0
|
802
|
+
raise_command_error "wrong number of arguments, expected 0-1 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
|
803
|
+
end
|
804
|
+
#connect(options)
|
632
805
|
@appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
|
633
806
|
if !@appliance_name
|
634
|
-
|
635
|
-
return
|
807
|
+
print yellow,"You are not using any appliance",reset,"\n"
|
808
|
+
return 0
|
636
809
|
end
|
637
810
|
Morpheus::Cli::Remote.clear_active_appliance()
|
638
|
-
|
811
|
+
print cyan, "You are no longer using the appliance #{@appliance_name}", reset, "\n"
|
639
812
|
# recalculate session variables
|
640
813
|
::Morpheus::Cli::Remote.recalculate_variable_map()
|
641
814
|
return true
|
@@ -658,12 +831,15 @@ EOT
|
|
658
831
|
"The default behavior is the same as 'remote get current'."
|
659
832
|
end
|
660
833
|
optparse.parse!(args)
|
661
|
-
|
662
|
-
|
663
|
-
print yellow, "No current appliance, see `remote use`\n", reset
|
664
|
-
return 1
|
834
|
+
if args.count != 0
|
835
|
+
raise_command_error "wrong number of arguments, expected 0 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
|
665
836
|
end
|
666
|
-
|
837
|
+
connect(options)
|
838
|
+
# if !@appliance_name
|
839
|
+
# print yellow, "No current appliance, see `remote use`\n", reset
|
840
|
+
# return 1
|
841
|
+
# end
|
842
|
+
#connect(options)
|
667
843
|
if name_only
|
668
844
|
print cyan, @appliance_name,"\n",reset
|
669
845
|
return 0
|
@@ -683,67 +859,223 @@ EOT
|
|
683
859
|
options = {}
|
684
860
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
685
861
|
opts.banner = subcommand_usage()
|
686
|
-
build_common_options(opts, options, [:options, :json, :dry_run])
|
687
|
-
opts.on('
|
688
|
-
options[:
|
689
|
-
Morpheus::RestClient.enable_ssl_verification = false
|
862
|
+
build_common_options(opts, options, [:payload, :options, :json, :dry_run, :quiet, :remote])
|
863
|
+
opts.on('--hubmode MODE','--hubmode MODE', "Choose an option for hub registration possible values are login, register, skip.") do |val|
|
864
|
+
options[:hubmode] = val.to_s.downcase
|
690
865
|
end
|
691
|
-
opts.footer = "
|
692
|
-
"You will be prompted to create the master
|
693
|
-
"
|
866
|
+
opts.footer = "Initialize a fresh appliance.\n" +
|
867
|
+
"You will be prompted to create the master tenant and admin user.\n" +
|
868
|
+
"If Morpheus Hub registration is enabled, you may login or register to retrieve a license key.\n" +
|
869
|
+
"Setup is only available on a new, freshly installed, remote appliance\n" +
|
870
|
+
"and it may only be used successfully once."
|
694
871
|
end
|
695
872
|
optparse.parse!(args)
|
873
|
+
|
874
|
+
# first arg as remote name otherwise the active appliance is connected to
|
875
|
+
if args.count > 1
|
876
|
+
raise_command_error "wrong number of arguments, expected 0-1 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
|
877
|
+
end
|
878
|
+
if args[0]
|
879
|
+
options[:remote] = args[0]
|
880
|
+
end
|
881
|
+
connect(options)
|
696
882
|
|
697
883
|
if !@appliance_name
|
698
884
|
print yellow, "No active appliance, see `remote use`\n", reset
|
699
885
|
return false
|
700
886
|
end
|
701
887
|
|
702
|
-
#
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
888
|
+
# construct payload
|
889
|
+
payload = nil
|
890
|
+
if options[:payload]
|
891
|
+
payload = options[:payload]
|
892
|
+
else
|
893
|
+
params = {}
|
894
|
+
params.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
|
895
|
+
|
896
|
+
# this works without any authentication!
|
897
|
+
# it will allow anyone to use it, if there are no users/accounts in the system.
|
898
|
+
#@api_client = establish_remote_appliance_connection(options)
|
899
|
+
@setup_interface = @api_client.setup #use me
|
900
|
+
# @setup_interface = Morpheus::SetupInterface.new({url:@appliance_url,access_token:@access_token})
|
901
|
+
appliance_status_json = nil
|
902
|
+
begin
|
903
|
+
appliance_status_json = @setup_interface.get()
|
904
|
+
if appliance_status_json['success'] != true
|
905
|
+
print_error red, "Setup not available for appliance #{@appliance_name} - #{@appliance_url}.\n", reset
|
906
|
+
print_error red, "#{appliance_status_json['msg']}\n", reset
|
907
|
+
return false
|
908
|
+
end
|
909
|
+
rescue RestClient::Exception => e
|
910
|
+
print_rest_exception(e, options)
|
713
911
|
return false
|
714
912
|
end
|
715
|
-
rescue RestClient::Exception => e
|
716
|
-
print_rest_exception(e, options)
|
717
|
-
return false
|
718
|
-
end
|
719
|
-
|
720
|
-
payload = {}
|
721
|
-
|
722
|
-
if appliance_status_json['hubRegistrationEnabled']
|
723
|
-
link = File.join(@appliance_url, '/setup')
|
724
|
-
print red, "Sorry, setup with hub registration is not yet available.\n", reset
|
725
|
-
print "You can use the UI to setup your appliance.\n"
|
726
|
-
print "Go to #{link}\n", reset
|
727
|
-
# if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
|
728
|
-
# system "start #{link}"
|
729
|
-
# elsif RbConfig::CONFIG['host_os'] =~ /darwin/
|
730
|
-
# system "open #{link}"
|
731
|
-
# elsif RbConfig::CONFIG['host_os'] =~ /linux|bsd/
|
732
|
-
# system "xdg-open #{link}"
|
733
|
-
# end
|
734
|
-
return false
|
735
|
-
else
|
736
|
-
print_h1 "Morpheus Appliance Setup", [], options
|
737
|
-
|
738
|
-
puts "It looks like you're the first one here."
|
739
|
-
puts "Let's initialize your remote appliance at #{@appliance_url}"
|
740
913
|
|
914
|
+
# retrieved hub.enabled and hub.url
|
915
|
+
hub_settings = appliance_status_json['hubSettings'] || appliance_status_json['hub'] || {}
|
741
916
|
|
917
|
+
# store login/registration info in here, for prompt default values
|
918
|
+
hub_info = nil
|
919
|
+
print cyan
|
920
|
+
print_h2 "Remote Setup: #{@appliance_name} - #{@appliance_url}"
|
742
921
|
|
922
|
+
print cyan
|
923
|
+
puts "Welcome to the setup of your new Morpheus Appliance #{@appliance_name} @ #{@appliance_url}"
|
924
|
+
puts "It looks like you're the first here, so let's begin."
|
925
|
+
|
926
|
+
hubmode = nil
|
927
|
+
hub_init_payload = nil # gets included as payload for hub scoped like hub.email
|
928
|
+
if hub_settings['enabled']
|
929
|
+
|
930
|
+
# Hub Registration
|
931
|
+
hub_action_dropdown = [
|
932
|
+
{'name' => 'Login to existing hub account', 'value' => 'login', 'isDefault' => true},
|
933
|
+
{'name' => 'Register a new hub account', 'value' => 'register'},
|
934
|
+
{'name' => 'Skip this step and manually install a license later.', 'value' => 'skip'},
|
935
|
+
{'name' => 'Abort', 'value' => 'abort'}
|
936
|
+
]
|
937
|
+
|
938
|
+
|
939
|
+
print cyan
|
940
|
+
puts "Morpheus Hub registration is enabled for your appliance."
|
941
|
+
puts "This step will connect to the Morpheus Hub at #{hub_settings['url']}"
|
942
|
+
puts "This is done to retrieve and install the license key for your appliance."
|
943
|
+
puts "You have several options for how to proceed:"
|
944
|
+
hub_action_dropdown.each_with_index do |hub_action, idx|
|
945
|
+
puts "#{idx+1}. #{hub_action['name']} [#{hub_action['value']}]"
|
946
|
+
end
|
947
|
+
print "\n", reset
|
948
|
+
|
949
|
+
while hubmode == nil do
|
950
|
+
|
951
|
+
options[:options]['hubmode'] = options[:hubmode] if options.key?(:hubmode)
|
952
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'hubmode', 'fieldLabel' => 'Choose Hub Mode', 'type' => 'select', 'selectOptions' => hub_action_dropdown, 'required' => true, 'defaultValue' => 'login'}], options[:options])
|
953
|
+
hubmode = v_prompt['hubmode']
|
954
|
+
|
955
|
+
if hubmode == 'login'
|
956
|
+
|
957
|
+
# print cyan
|
958
|
+
# puts "MORPHEUS HUB #{hub_settings['url']}"
|
959
|
+
# puts "The Command Center for DevOps"
|
960
|
+
# print reset
|
961
|
+
|
962
|
+
# Hub Login
|
963
|
+
print_h2 "Morpheus Hub Login @ #{hub_settings['url']}", options
|
964
|
+
hub_login_option_types = [
|
965
|
+
{'fieldContext' => 'hub', 'fieldName' => 'email', 'fieldLabel' => 'Email', 'type' => 'text', 'required' => true, 'description' => 'Email Address of existing Morpheus Hub user to link with.'},
|
966
|
+
{'fieldContext' => 'hub', 'fieldName' => 'password', 'fieldLabel' => 'Password', 'type' => 'password', 'required' => true, 'description' => 'Password of existing Morpheus Hub user.'},
|
967
|
+
]
|
968
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt(hub_login_option_types, options[:options])
|
969
|
+
hub_login_payload = v_prompt['hub']
|
970
|
+
hub_login_response = nil
|
971
|
+
begin
|
972
|
+
hub_login_response = @setup_interface.hub_login(hub_login_payload)
|
973
|
+
hub_init_payload = hub_login_payload
|
974
|
+
hub_info = {'email' => hub_login_payload['email'], 'password' => hub_login_payload['password'] }
|
975
|
+
hub_info.deep_merge!(hub_login_response['data']['info']) if (hub_login_response['data'] && hub_login_response['data']['info'])
|
976
|
+
hub_info.deep_merge!(hub_login_response['hub']) if hub_login_response['hub'].is_a?(Hash)
|
977
|
+
print_green_success "Logged into Morpheus Hub as #{hub_info['email']}"
|
978
|
+
rescue RestClient::Exception => e
|
979
|
+
hub_login_response = parse_rest_exception(e)
|
980
|
+
error_msg = hub_login_response["msg"] || "Hub login failed."
|
981
|
+
print_error red,error_msg,reset,"\n"
|
982
|
+
hubmode = nil
|
983
|
+
#print_rest_exception(e, options)
|
984
|
+
#exit 1
|
985
|
+
end
|
986
|
+
|
987
|
+
# DEBUG
|
988
|
+
if options[:debug] && hub_login_response
|
989
|
+
print_h2 "JSON response for hub login"
|
990
|
+
Morpheus::Logging::DarkPrinter.puts as_json(hub_login_response)
|
991
|
+
end
|
992
|
+
|
993
|
+
elsif hubmode == 'register'
|
994
|
+
# Hub Registration
|
995
|
+
print_h2 "Morpheus Hub Registration", options
|
996
|
+
hub_register_option_types = [
|
997
|
+
{'fieldContext' => 'hub', 'fieldName' => 'companyName', 'fieldLabel' => 'Company Name', 'type' => 'text', 'required' => true, 'description' => 'Company Name of new Morpheus Hub account to be created.'},
|
998
|
+
{'fieldContext' => 'hub', 'fieldName' => 'firstName', 'fieldLabel' => 'First Name', 'type' => 'text', 'required' => true, 'description' => 'First Name of new Morpheus Hub user.'},
|
999
|
+
{'fieldContext' => 'hub', 'fieldName' => 'lastName', 'fieldLabel' => 'Last Name', 'type' => 'text', 'required' => true, 'description' => 'Last Name of new Morpheus Hub user.'},
|
1000
|
+
{'fieldContext' => 'hub', 'fieldName' => 'email', 'fieldLabel' => 'Email', 'type' => 'text', 'required' => true, 'description' => 'Email Address of new Morpheus Hub user.'}
|
1001
|
+
]
|
1002
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt(hub_register_option_types, options[:options])
|
1003
|
+
hub_register_payload = v_prompt['hub']
|
1004
|
+
|
1005
|
+
# Password prompt with re-prompting if no match
|
1006
|
+
need_password = true
|
1007
|
+
if options[:no_prompt]
|
1008
|
+
if options[:options]['hub'] && options[:options]['hub']['password']
|
1009
|
+
options[:options]['hub']['confirmPassword'] = options[:options]['hub']['password']
|
1010
|
+
end
|
1011
|
+
end
|
1012
|
+
while need_password do
|
1013
|
+
password_option_types = [
|
1014
|
+
{'fieldContext' => 'hub', 'fieldName' => 'password', 'fieldLabel' => 'Create Password', 'type' => 'password', 'required' => true, 'description' => 'Confirm password of new Morpheus Hub user.'},
|
1015
|
+
{'fieldContext' => 'hub', 'fieldName' => 'confirmPassword', 'fieldLabel' => 'Confirm Password', 'type' => 'password', 'required' => true, 'description' => 'Confirm password of new Morpheus Hub user.'}
|
1016
|
+
]
|
1017
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt(password_option_types, options[:options])
|
1018
|
+
if v_prompt['hub']['password'] == v_prompt['hub']['confirmPassword']
|
1019
|
+
hub_register_payload.deep_merge!(v_prompt['hub'])
|
1020
|
+
need_password = false
|
1021
|
+
else
|
1022
|
+
print_error red, "Password confirmation does not match. Re-enter your new password.", reset, "\n"
|
1023
|
+
end
|
1024
|
+
end
|
1025
|
+
|
1026
|
+
begin
|
1027
|
+
hub_register_response = @setup_interface.hub_register(hub_register_payload)
|
1028
|
+
hub_init_payload = hub_register_payload
|
1029
|
+
hub_info = {'email' => hub_register_payload['email'], 'password' => hub_register_payload['password'] }
|
1030
|
+
hub_info.deep_merge!(hub_register_payload)
|
1031
|
+
hub_info.deep_merge!(hub_register_response['data']['info']) if (hub_register_response['data'] && hub_register_response['data']['info'])
|
1032
|
+
hub_info.deep_merge!(hub_register_response['hub']) if hub_register_response['hub'].is_a?(Hash)
|
1033
|
+
print_green_success "Registered with Morpheus Hub as #{hub_info['email']}"
|
1034
|
+
# uh ok so that means the init() request can use login
|
1035
|
+
# this avoid duplicate email error
|
1036
|
+
# but it can also just omit hubMode from the init() payload to achieve the same thing.
|
1037
|
+
# hubmode = nil
|
1038
|
+
rescue RestClient::Exception => e
|
1039
|
+
hub_register_response = parse_rest_exception(e)
|
1040
|
+
error_msg = hub_register_response["msg"] || "Hub Registration failed."
|
1041
|
+
print_error red,error_msg,reset,"\n"
|
1042
|
+
hubmode = nil
|
1043
|
+
#print_rest_exception(e, options)
|
1044
|
+
#exit 1
|
1045
|
+
end
|
1046
|
+
|
1047
|
+
# DEBUG
|
1048
|
+
if options[:debug] && hub_register_response
|
1049
|
+
print_h2 "JSON response for hub registration"
|
1050
|
+
Morpheus::Logging::DarkPrinter.puts as_json(hub_register_response)
|
1051
|
+
end
|
1052
|
+
|
1053
|
+
elsif hubmode == 'skip'
|
1054
|
+
print cyan,"Skipping hub registraton for now...",reset,"\n"
|
1055
|
+
# puts "You may enter a license key later."
|
1056
|
+
elsif hubmode == 'abort'
|
1057
|
+
return 9, "aborted command"
|
1058
|
+
else
|
1059
|
+
hubmode = nil
|
1060
|
+
end
|
1061
|
+
end
|
1062
|
+
end
|
1063
|
+
|
1064
|
+
# ok, we're done with the hub.
|
1065
|
+
# now build the payload for POST /api/setup/init
|
1066
|
+
|
1067
|
+
payload = {}
|
1068
|
+
payload.deep_merge!(params)
|
1069
|
+
|
1070
|
+
# print cyan
|
1071
|
+
#print_h1 "Morpheus Appliance Setup", [], options
|
1072
|
+
#print cyan
|
1073
|
+
#puts "Initializing remote appliance at URL: #{@appliance_url}"
|
1074
|
+
|
743
1075
|
# Master Account
|
744
|
-
print_h2 "Create Master
|
1076
|
+
print_h2 "Create Master Tenant", options
|
745
1077
|
account_option_types = [
|
746
|
-
{'fieldName' => 'accountName', 'fieldLabel' => 'Master
|
1078
|
+
{'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).'},
|
747
1079
|
]
|
748
1080
|
v_prompt = Morpheus::Cli::OptionTypes.prompt(account_option_types, options[:options])
|
749
1081
|
payload.merge!(v_prompt)
|
@@ -751,88 +1083,207 @@ EOT
|
|
751
1083
|
# Master User
|
752
1084
|
print_h2 "Create Master User", options
|
753
1085
|
user_option_types = [
|
754
|
-
{'fieldName' => 'firstName', 'fieldLabel' => 'First Name', 'type' => 'text', 'required' => false, '
|
755
|
-
{'fieldName' => 'lastName', 'fieldLabel' => 'Last Name', 'type' => 'text', 'required' => false, '
|
756
|
-
{'fieldName' => '
|
757
|
-
{'fieldName' => '
|
1086
|
+
{'fieldName' => 'firstName', 'fieldLabel' => 'First Name', 'type' => 'text', 'required' => false, 'defaultValue' => (hub_info ? hub_info['firstName'] : nil), 'description' => 'First name of the user.'},
|
1087
|
+
{'fieldName' => 'lastName', 'fieldLabel' => 'Last Name', 'type' => 'text', 'required' => false, 'defaultValue' => (hub_info ? hub_info['lastName'] : nil), 'description' => 'Last name of the user.'},
|
1088
|
+
{'fieldName' => 'email', 'fieldLabel' => 'Email', 'type' => 'text', 'required' => true, 'defaultValue' => (hub_info ? hub_info['email'] : nil), 'description' => 'A unique email address for the user.'},
|
1089
|
+
{'fieldName' => 'username', 'fieldLabel' => 'Username', 'type' => 'text', 'required' => true, 'description' => 'A unique username for the master user.'}
|
758
1090
|
]
|
759
1091
|
v_prompt = Morpheus::Cli::OptionTypes.prompt(user_option_types, options[:options])
|
760
1092
|
payload.merge!(v_prompt)
|
761
1093
|
|
762
1094
|
# Password prompt with re-prompting if no match
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
while
|
769
|
-
|
1095
|
+
need_password = true
|
1096
|
+
if options[:no_prompt]
|
1097
|
+
options[:options]['confirmPassword'] = payload['password']
|
1098
|
+
payload['confirmPassword'] = payload['password'] if payload['password']
|
1099
|
+
end
|
1100
|
+
while need_password do
|
1101
|
+
password_option_types = [
|
1102
|
+
{'fieldName' => 'password', 'fieldLabel' => 'Create Password', 'type' => 'password', 'required' => true, 'description' => 'Create a new password for the user.'},
|
1103
|
+
{'fieldName' => 'confirmPassword', 'fieldLabel' => 'Confirm Password', 'type' => 'password', 'required' => true, 'description' => 'Confirm the new password for the user.'},
|
1104
|
+
]
|
770
1105
|
v_prompt = Morpheus::Cli::OptionTypes.prompt(password_option_types, options[:options])
|
1106
|
+
if v_prompt['password'] == v_prompt['confirmPassword']
|
1107
|
+
payload.deep_merge!(v_prompt)
|
1108
|
+
need_password = false
|
1109
|
+
else
|
1110
|
+
print_error red, "Password confirmation does not match. Re-enter your new password.", reset, "\n"
|
1111
|
+
end
|
771
1112
|
end
|
772
|
-
payload.merge!(v_prompt)
|
773
1113
|
|
774
|
-
#
|
1114
|
+
# Appliance Settings
|
1115
|
+
default_appliance_url = appliance_status_json['applianceUrl']
|
1116
|
+
if default_appliance_url && default_appliance_url.include?('10.0.2.2:8080') # ignore this default value.
|
1117
|
+
default_appliance_url = @appliance_url
|
1118
|
+
end
|
1119
|
+
default_appliance_name = appliance_status_json['applianceName']
|
1120
|
+
if default_appliance_name.nil?
|
1121
|
+
default_appliance_name = @appliance_name
|
1122
|
+
end
|
775
1123
|
print_h2 "Initial Setup", options
|
776
1124
|
extra_option_types = [
|
777
|
-
{'fieldName' => 'applianceName', 'fieldLabel' => 'Appliance Name', 'type' => 'text', 'required' => true, 'defaultValue' =>
|
778
|
-
{'fieldName' => 'applianceUrl', 'fieldLabel' => 'Appliance URL', 'type' => 'text', 'required' => true, 'defaultValue' =>
|
779
|
-
{'fieldName' => 'backups', 'fieldLabel' => 'Enable Backups', 'type' => 'checkbox', 'required' => false, 'defaultValue' => 'off'},
|
780
|
-
{'fieldName' => 'monitoring', 'fieldLabel' => 'Enable Monitoring', 'type' => 'checkbox', 'required' => false, 'defaultValue' => 'on'},
|
781
|
-
{'fieldName' => 'logs', 'fieldLabel' => 'Enable Logs', 'type' => 'checkbox', 'required' => false, 'defaultValue' => 'on'}
|
1125
|
+
{'fieldName' => 'applianceName', 'fieldLabel' => 'Appliance Name', 'type' => 'text', 'required' => true, 'defaultValue' => default_appliance_name, 'description' => 'A name for identifying your morpheus appliance.'},
|
1126
|
+
{'fieldName' => 'applianceUrl', 'fieldLabel' => 'Appliance URL', 'type' => 'text', 'required' => true, 'defaultValue' => default_appliance_url, 'description' => 'Appliance URL. Can be used for integrations and callbacks.'},
|
1127
|
+
{'fieldName' => 'backups', 'fieldLabel' => 'Enable Backups', 'type' => 'checkbox', 'required' => false, 'defaultValue' => 'off', 'description' => 'Backups. Default is off. This means backups are created automatically during provisioning.'},
|
1128
|
+
{'fieldName' => 'monitoring', 'fieldLabel' => 'Enable Monitoring', 'type' => 'checkbox', 'required' => false, 'defaultValue' => 'on', 'description' => 'Enable Monitoring. This means checks are created automatically during provisioning.'},
|
1129
|
+
{'fieldName' => 'logs', 'fieldLabel' => 'Enable Logs', 'type' => 'checkbox', 'required' => false, 'defaultValue' => 'on', 'description' => 'Enable Logs. This means container logs are collected.'}
|
782
1130
|
]
|
783
1131
|
v_prompt = Morpheus::Cli::OptionTypes.prompt(extra_option_types, options[:options])
|
784
1132
|
payload.merge!(v_prompt)
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
if !options[:json]
|
793
|
-
print "Initializing the appliance...\n"
|
794
|
-
end
|
795
|
-
json_response = @setup_interface.init(payload)
|
796
|
-
rescue RestClient::Exception => e
|
797
|
-
print_rest_exception(e, options)
|
798
|
-
return false
|
1133
|
+
|
1134
|
+
# include hubmode and hub params for login or registration
|
1135
|
+
# actually we remove hubMode because it has already been setup, probably just now,
|
1136
|
+
# and the init() request will just used the same creds instead of
|
1137
|
+
# reauthenticated/registering with the hub
|
1138
|
+
if hubmode
|
1139
|
+
payload['hubMode'] = hubmode
|
799
1140
|
end
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
1141
|
+
if hub_init_payload
|
1142
|
+
payload['hub'] = hub_init_payload
|
1143
|
+
end
|
1144
|
+
if hubmode == 'register' || hubmode == 'login'
|
1145
|
+
payload.delete('hubMode')
|
1146
|
+
payload.delete('hub')
|
805
1147
|
end
|
806
|
-
print "\n"
|
807
|
-
print cyan, "You have successfully setup the appliance.\n"
|
808
|
-
#print cyan, "You may now login with the command `login`.\n"
|
809
|
-
# uh, just use Credentials.login(username, password, {save: true})
|
810
|
-
cmd_res = Morpheus::Cli::Login.new.login(['--username', payload['username'], '--password', payload['password'], '-q'])
|
811
|
-
# print "\n"
|
812
|
-
print cyan, "You are now logged in as the System Admin #{payload['username']}.\n"
|
813
|
-
print reset
|
814
|
-
#print "\n"
|
815
1148
|
|
1149
|
+
end
|
1150
|
+
|
1151
|
+
# ok, make the api request
|
1152
|
+
@setup_interface.setopts(options)
|
1153
|
+
if options[:dry_run]
|
1154
|
+
print_dry_run @setup_interface.dry.init(payload)
|
1155
|
+
return
|
1156
|
+
end
|
1157
|
+
|
1158
|
+
json_response = @setup_interface.init(payload)
|
1159
|
+
|
1160
|
+
render_result = render_with_format(json_response, options)
|
1161
|
+
return 0 if render_result
|
1162
|
+
|
1163
|
+
if options[:json]
|
1164
|
+
print JSON.pretty_generate(json_response)
|
1165
|
+
print "\n"
|
1166
|
+
return
|
1167
|
+
end
|
1168
|
+
print "\n"
|
1169
|
+
print green,"Setup complete for remote #{@appliance_name} - #{@appliance_url}",reset,"\n"
|
1170
|
+
#print cyan, "You may now login with the command `login`.\n"
|
1171
|
+
# uh, just use Credentials.login(username, password, {save: true})
|
1172
|
+
cmd_res = Morpheus::Cli::Login.new.login(['--username', payload['username'], '--password', payload['password'], '-q'] + (options[:remote] ? ["-r",options[:remote]] : []))
|
1173
|
+
# print "\n"
|
1174
|
+
print cyan, "You are now logged in as the System Admin #{payload['username']}.\n"
|
1175
|
+
print reset
|
1176
|
+
#print "\n"
|
1177
|
+
|
1178
|
+
if hubmode == 'skip'
|
816
1179
|
if ::Morpheus::Cli::OptionTypes::confirm("Would you like to apply your License Key now?", options.merge({:default => true}))
|
817
|
-
cmd_res = Morpheus::Cli::License.new.apply([])
|
1180
|
+
cmd_res = Morpheus::Cli::License.new.apply([] + (options[:remote] ? ["-r",options[:remote]] : []))
|
818
1181
|
# license_is_valid = cmd_res != false
|
819
1182
|
end
|
1183
|
+
end
|
820
1184
|
|
821
|
-
|
822
|
-
|
1185
|
+
if ::Morpheus::Cli::OptionTypes::confirm("Do you want to create the first group now?", options.merge({:default => true}))
|
1186
|
+
cmd_res = Morpheus::Cli::Groups.new.add(['--use'] + (options[:remote] ? ["-r",options[:remote]] : []))
|
823
1187
|
|
824
|
-
|
1188
|
+
#print "\n"
|
825
1189
|
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
1190
|
+
# if cmd_res !=
|
1191
|
+
if ::Morpheus::Cli::OptionTypes::confirm("Do you want to create the first cloud now?", options.merge({:default => true}))
|
1192
|
+
cmd_res = Morpheus::Cli::Clouds.new.add([] + (options[:remote] ? ["-r",options[:remote]] : []))
|
1193
|
+
#print "\n"
|
1194
|
+
end
|
1195
|
+
# end
|
1196
|
+
end
|
1197
|
+
print "\n",reset
|
1198
|
+
|
1199
|
+
end
|
1200
|
+
|
1201
|
+
|
1202
|
+
# this is just for testing new appliances really
|
1203
|
+
# it can be used
|
1204
|
+
def teardown(args)
|
1205
|
+
options = {}
|
1206
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
1207
|
+
opts.banner = subcommand_usage()
|
1208
|
+
build_common_options(opts, options, [:json, :dry_run, :quiet, :remote])
|
1209
|
+
opts.footer = "Provides a way to uninitialize a fresh appliance. Useful for testing appliance setup."
|
1210
|
+
end
|
1211
|
+
optparse.parse!(args)
|
1212
|
+
|
1213
|
+
# first arg as remote name otherwise the active appliance is connected to
|
1214
|
+
if args.count > 1
|
1215
|
+
raise_command_error "wrong number of arguments, expected 0-1 and got (#{args.count}) #{args.join(' ')}\n#{optparse}"
|
1216
|
+
end
|
1217
|
+
if args[0]
|
1218
|
+
options[:remote] = args[0]
|
1219
|
+
end
|
1220
|
+
connect(options)
|
1221
|
+
|
1222
|
+
if !@appliance_name
|
1223
|
+
print yellow, "No active appliance, see `remote use`\n", reset
|
1224
|
+
return false
|
1225
|
+
end
|
1226
|
+
|
1227
|
+
unless options[:quiet]
|
1228
|
+
print yellow
|
1229
|
+
print "\n"
|
1230
|
+
puts "WARNING: You are about to reset your appliance installation."
|
1231
|
+
puts "It's only possible to perform teardown when the appliance has just been installed."
|
1232
|
+
puts "This provides a way to reset your appliance and run setup again."
|
1233
|
+
print reset
|
1234
|
+
print "\n"
|
1235
|
+
end
|
1236
|
+
|
1237
|
+
unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like teardown appliance '#{@appliance_name}'.", options)
|
1238
|
+
return 9, "aborted command" # new exit code for aborting confirmation
|
1239
|
+
end
|
1240
|
+
|
1241
|
+
#@setup_interface = @api_client.setup
|
1242
|
+
|
1243
|
+
# construct payload
|
1244
|
+
|
1245
|
+
params = {}
|
1246
|
+
params.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
|
1247
|
+
|
1248
|
+
# this works without any authentication!
|
1249
|
+
# it will allow anyone to use it, if there are no users/accounts in the system.
|
1250
|
+
#@api_client = establish_remote_appliance_connection(options)
|
1251
|
+
#@setup_interface = @api_client.setup
|
1252
|
+
@setup_interface = Morpheus::SetupInterface.new({url:@appliance_url,access_token:@access_token, very_ssl:false})
|
1253
|
+
json_response = nil
|
1254
|
+
begin
|
1255
|
+
json_response = @setup_interface.teardown(params)
|
1256
|
+
if json_response['success'] != true
|
1257
|
+
print_error red, (json_response['msg'] || "Teardown failed").to_s, reset, "\n"
|
1258
|
+
return false
|
832
1259
|
end
|
833
|
-
|
1260
|
+
rescue RestClient::Exception => e
|
1261
|
+
print_rest_exception(e, options)
|
1262
|
+
return false
|
1263
|
+
end
|
1264
|
+
|
1265
|
+
|
1266
|
+
# ok, make the api request and render the response or print a message
|
1267
|
+
@setup_interface.setopts(options)
|
1268
|
+
if options[:dry_run]
|
1269
|
+
print_dry_run @setup_interface.dry.teardown(params)
|
1270
|
+
return
|
1271
|
+
end
|
834
1272
|
|
1273
|
+
json_response = @setup_interface.teardown(params)
|
1274
|
+
|
1275
|
+
render_result = render_with_format(json_response, options)
|
1276
|
+
return 0 if render_result
|
1277
|
+
if options[:quiet]
|
1278
|
+
return 0
|
835
1279
|
end
|
1280
|
+
if json_response['msg']
|
1281
|
+
print_green_success json_response['msg']
|
1282
|
+
else
|
1283
|
+
print_green_success "Teardown complete for remote #{@appliance_name} - #{@appliance_url}. Now see `remote setup`"
|
1284
|
+
end
|
1285
|
+
return 0
|
1286
|
+
|
836
1287
|
end
|
837
1288
|
|
838
1289
|
def format_appliance_status(app_map, return_color=cyan)
|
@@ -842,18 +1293,18 @@ EOT
|
|
842
1293
|
out = ""
|
843
1294
|
if status_str == "new"
|
844
1295
|
out << "#{cyan}#{status_str.upcase}#{return_color}"
|
1296
|
+
elsif status_str == "fresh"
|
1297
|
+
# maybe just green instead?
|
1298
|
+
out << "#{magenta}#{status_str.upcase}#{return_color}"
|
845
1299
|
elsif status_str == "ready"
|
846
1300
|
out << "#{green}#{status_str.upcase}#{return_color}"
|
847
|
-
elsif status_str == "
|
1301
|
+
elsif status_str == "http-error"
|
1302
|
+
out << "#{red}#{status_str.upcase}#{return_color}"
|
1303
|
+
elsif ['error', 'net-error', 'ssl-error', 'http-timeout', 'unreachable', 'unrecognized'].include?(status_str)
|
848
1304
|
out << "#{red}#{status_str.upcase}#{return_color}"
|
849
|
-
elsif ['error', 'net-error', 'ssl-error', 'http-timeout', 'unreachable']
|
850
|
-
out << "#{red}#{status_str.upcase.gsub('-',' ')}#{return_color}"
|
851
|
-
elsif status_str == "fresh"
|
852
|
-
# cold appliance, needs setup
|
853
|
-
out << "#{magenta}#{status_str.upcase}#{return_color}"
|
854
1305
|
else
|
855
1306
|
# dunno
|
856
|
-
out << "#{status_str}"
|
1307
|
+
out << "#{yellow}#{status_str.upcase}#{return_color}"
|
857
1308
|
end
|
858
1309
|
out
|
859
1310
|
end
|
@@ -915,7 +1366,8 @@ EOT
|
|
915
1366
|
blurbs << "Last checked #{format_duration(app_map[:last_check][:timestamp])} ago."
|
916
1367
|
end
|
917
1368
|
if app_map[:last_check][:error]
|
918
|
-
|
1369
|
+
last_error_msg = truncate_string(app_map[:last_check][:error], 250)
|
1370
|
+
blurbs << "Error: #{last_error_msg}"
|
919
1371
|
end
|
920
1372
|
if app_map[:last_check][:http_status]
|
921
1373
|
blurbs << "HTTP #{app_map[:last_check][:http_status]}"
|
@@ -987,6 +1439,39 @@ EOT
|
|
987
1439
|
# last_command_result: v[:last_command_result]
|
988
1440
|
# }
|
989
1441
|
end
|
1442
|
+
|
1443
|
+
# filter results
|
1444
|
+
params[:phrase] = params['phrase'] if params['phrase']
|
1445
|
+
params[:name] = params['name'] if params['name']
|
1446
|
+
params[:url] = params['url'] if params['url']
|
1447
|
+
# params[:insecure] = params['insecure'] if params['insecure']
|
1448
|
+
params[:max] = params['max'] if params['max']
|
1449
|
+
params[:offset] = params['offset'] if params['offset']
|
1450
|
+
params[:sort] = params['sort'] if params['sort']
|
1451
|
+
params[:direction] = params['direction'] if params['direction']
|
1452
|
+
|
1453
|
+
|
1454
|
+
if all_appliances
|
1455
|
+
# apply filters
|
1456
|
+
if params[:phrase]
|
1457
|
+
all_appliances = all_appliances.select do |app|
|
1458
|
+
app_name = app[:name] || app['name']
|
1459
|
+
app_url = app[:url] || app['url'] || app[:host]
|
1460
|
+
app_name.to_s.include?(params[:phrase]) || app_url.to_s.include?(params[:phrase])
|
1461
|
+
end
|
1462
|
+
end
|
1463
|
+
# apply sort
|
1464
|
+
sort_key = params[:sort] ? params[:sort].to_sym : :name
|
1465
|
+
if params['direction'] == 'desc'
|
1466
|
+
all_appliances = all_appliances.sort {|a,b| b[sort_key] <=> a[sort_key] }
|
1467
|
+
else
|
1468
|
+
all_appliances = all_appliances.sort {|a,b| a[sort_key] <=> b[sort_key] }
|
1469
|
+
end
|
1470
|
+
# limit
|
1471
|
+
if params[:max]
|
1472
|
+
all_appliances = all_appliances.first(params[:max])
|
1473
|
+
end
|
1474
|
+
end
|
990
1475
|
return all_appliances
|
991
1476
|
end
|
992
1477
|
|
@@ -1110,6 +1595,76 @@ EOT
|
|
1110
1595
|
return app_map
|
1111
1596
|
end
|
1112
1597
|
|
1598
|
+
# use this to rename, it update appliances file and others.
|
1599
|
+
# oh maybe just put this in the command handler
|
1600
|
+
#
|
1601
|
+
# first check if the requested name exits
|
1602
|
+
# and that the new name does not exist.
|
1603
|
+
#
|
1604
|
+
# clone it and delete the old one.
|
1605
|
+
# todo: switch replace symbols with strings please, makes for nicer appliances.yaml
|
1606
|
+
def rename_remote(app_name, new_app_name)
|
1607
|
+
app_name = app_name.to_sym
|
1608
|
+
new_app_name = new_app_name.to_sym
|
1609
|
+
cur_appliances = self.appliances #.clone
|
1610
|
+
app_map = cur_appliances[app_name]
|
1611
|
+
if app_map.nil?
|
1612
|
+
print_red_alert "A remote not found by the name '#{app_name}'"
|
1613
|
+
#print "Did you mean one of these commands: #{suggestions.join(', ')?", reset, "\n"
|
1614
|
+
return nil
|
1615
|
+
end
|
1616
|
+
if cur_appliances[new_app_name]
|
1617
|
+
print_red_alert "A remote already exists with name '#{new_app_name}'."
|
1618
|
+
puts "First, you must rename or remove the existing remote."
|
1619
|
+
return nil
|
1620
|
+
end
|
1621
|
+
|
1622
|
+
# clone the existing data
|
1623
|
+
|
1624
|
+
# copy remote
|
1625
|
+
new_appliance_map = app_map.clone()
|
1626
|
+
new_appliance_map[:name] = new_app_name # inject name
|
1627
|
+
save_remote(new_app_name, new_appliance_map)
|
1628
|
+
|
1629
|
+
# clone credentials...just overwrite keys there, f it.
|
1630
|
+
old_wallet = ::Morpheus::Cli::Credentials.new(app_name, nil).load_saved_credentials()
|
1631
|
+
if old_wallet
|
1632
|
+
::Morpheus::Cli::Credentials.new(new_app_name, nil).save_credentials(new_app_name, old_wallet)
|
1633
|
+
#::Morpheus::Cli::Credentials.new(app_name, nil).clear_saved_credentials(app_name)
|
1634
|
+
end
|
1635
|
+
# clone groups...just overwrite keys there, f it.
|
1636
|
+
old_active_group = ::Morpheus::Cli::Groups.active_group(app_name)
|
1637
|
+
if old_active_group
|
1638
|
+
::Morpheus::Cli::Groups.set_active_group(new_app_name, old_active_group)
|
1639
|
+
#::Morpheus::Cli::Groups.clear_active_group(app_name)
|
1640
|
+
end
|
1641
|
+
|
1642
|
+
# delete stuff last
|
1643
|
+
|
1644
|
+
# delete creds
|
1645
|
+
if old_wallet
|
1646
|
+
::Morpheus::Cli::Credentials.new(app_name, nil).clear_saved_credentials(app_name)
|
1647
|
+
end
|
1648
|
+
|
1649
|
+
# delete groups
|
1650
|
+
if old_active_group
|
1651
|
+
::Morpheus::Cli::Groups.clear_active_group(app_name)
|
1652
|
+
end
|
1653
|
+
|
1654
|
+
# delete remote
|
1655
|
+
delete_remote(app_name)
|
1656
|
+
|
1657
|
+
# this is all redundant after above
|
1658
|
+
# # this should be a class method too
|
1659
|
+
# ::Morpheus::Cli::Credentials.new(app_name, nil).clear_saved_credentials(app_name)
|
1660
|
+
# # delete from groups too..
|
1661
|
+
# ::Morpheus::Cli::Groups.clear_active_group(app_name)
|
1662
|
+
# # recalculate session variables
|
1663
|
+
# recalculate_variable_map()
|
1664
|
+
# return the deleted value
|
1665
|
+
return app_map
|
1666
|
+
end
|
1667
|
+
|
1113
1668
|
def delete_remote(app_name)
|
1114
1669
|
app_name = app_name.to_sym
|
1115
1670
|
cur_appliances = self.appliances #.clone
|
@@ -1149,7 +1704,8 @@ EOT
|
|
1149
1704
|
Morpheus::RestClient.enable_ssl_verification = false
|
1150
1705
|
end
|
1151
1706
|
# Morpheus::RestClient.enable_http = app_map[:insecure].to_s == 'true'
|
1152
|
-
setup_interface = Morpheus::SetupInterface.new(app_url)
|
1707
|
+
setup_interface = Morpheus::SetupInterface.new({url:app_url, verify_ssl: (app_map[:insecure] != true)})
|
1708
|
+
check_json_response = nil
|
1153
1709
|
begin
|
1154
1710
|
now = Time.now.to_i
|
1155
1711
|
app_map[:last_check] = {}
|
@@ -1191,6 +1747,9 @@ EOT
|
|
1191
1747
|
rescue OpenSSL::SSL::SSLError => err
|
1192
1748
|
app_map[:status] = 'ssl-error'
|
1193
1749
|
app_map[:last_check][:error] = err.message
|
1750
|
+
rescue JSON::ParserError => err
|
1751
|
+
app_map[:status] = 'unrecognized'
|
1752
|
+
app_map[:last_check][:error] = err.message
|
1194
1753
|
rescue RestClient::Exception => err
|
1195
1754
|
app_map[:status] = 'http-error'
|
1196
1755
|
app_map[:http_status] = err.response ? err.response.code : nil
|
@@ -1198,7 +1757,7 @@ EOT
|
|
1198
1757
|
# fallback to /ping for older appliance versions (pre 2.10.5)
|
1199
1758
|
begin
|
1200
1759
|
Morpheus::Logging::DarkPrinter.puts "falling back to remote check via /ping ..." if Morpheus::Logging.debug?
|
1201
|
-
setup_interface.ping()
|
1760
|
+
check_json_response = @setup_interface.ping()
|
1202
1761
|
app_map[:last_check][:ping_fallback] = true
|
1203
1762
|
app_map[:last_check][:http_status] = 200
|
1204
1763
|
app_map[:last_check][:success] = true
|
@@ -1228,7 +1787,7 @@ EOT
|
|
1228
1787
|
save_remote(app_name, app_map)
|
1229
1788
|
|
1230
1789
|
# return the updated data
|
1231
|
-
return app_map
|
1790
|
+
return app_map, check_json_response
|
1232
1791
|
|
1233
1792
|
end
|
1234
1793
|
|