morpheus-cli 2.10.3 → 2.11.0
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/bin/morpheus +5 -96
- data/lib/morpheus/api/api_client.rb +23 -1
- data/lib/morpheus/api/checks_interface.rb +106 -0
- data/lib/morpheus/api/incidents_interface.rb +102 -0
- data/lib/morpheus/api/monitoring_apps_interface.rb +47 -0
- data/lib/morpheus/api/monitoring_contacts_interface.rb +47 -0
- data/lib/morpheus/api/monitoring_groups_interface.rb +47 -0
- data/lib/morpheus/api/monitoring_interface.rb +36 -0
- data/lib/morpheus/api/option_type_lists_interface.rb +47 -0
- data/lib/morpheus/api/option_types_interface.rb +47 -0
- data/lib/morpheus/api/roles_interface.rb +0 -1
- data/lib/morpheus/api/setup_interface.rb +19 -9
- data/lib/morpheus/cli.rb +20 -1
- data/lib/morpheus/cli/accounts.rb +8 -3
- data/lib/morpheus/cli/app_templates.rb +19 -11
- data/lib/morpheus/cli/apps.rb +52 -37
- data/lib/morpheus/cli/cli_command.rb +229 -53
- data/lib/morpheus/cli/cli_registry.rb +48 -40
- data/lib/morpheus/cli/clouds.rb +55 -26
- data/lib/morpheus/cli/command_error.rb +12 -0
- data/lib/morpheus/cli/credentials.rb +68 -26
- data/lib/morpheus/cli/curl_command.rb +98 -0
- data/lib/morpheus/cli/dashboard_command.rb +2 -7
- data/lib/morpheus/cli/deployments.rb +4 -4
- data/lib/morpheus/cli/deploys.rb +1 -2
- data/lib/morpheus/cli/dot_file.rb +5 -8
- data/lib/morpheus/cli/error_handler.rb +179 -15
- data/lib/morpheus/cli/groups.rb +21 -13
- data/lib/morpheus/cli/hosts.rb +220 -110
- data/lib/morpheus/cli/instance_types.rb +2 -2
- data/lib/morpheus/cli/instances.rb +257 -167
- data/lib/morpheus/cli/key_pairs.rb +15 -9
- data/lib/morpheus/cli/library.rb +673 -27
- data/lib/morpheus/cli/license.rb +2 -2
- data/lib/morpheus/cli/load_balancers.rb +4 -4
- data/lib/morpheus/cli/log_level_command.rb +6 -4
- data/lib/morpheus/cli/login.rb +17 -3
- data/lib/morpheus/cli/logout.rb +25 -11
- data/lib/morpheus/cli/man_command.rb +388 -0
- data/lib/morpheus/cli/mixins/accounts_helper.rb +1 -1
- data/lib/morpheus/cli/mixins/monitoring_helper.rb +434 -0
- data/lib/morpheus/cli/mixins/print_helper.rb +620 -112
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +1 -1
- data/lib/morpheus/cli/monitoring_apps_command.rb +29 -0
- data/lib/morpheus/cli/monitoring_checks_command.rb +427 -0
- data/lib/morpheus/cli/monitoring_contacts_command.rb +373 -0
- data/lib/morpheus/cli/monitoring_groups_command.rb +29 -0
- data/lib/morpheus/cli/monitoring_incidents_command.rb +711 -0
- data/lib/morpheus/cli/option_types.rb +10 -1
- data/lib/morpheus/cli/recent_activity_command.rb +2 -5
- data/lib/morpheus/cli/remote.rb +874 -134
- data/lib/morpheus/cli/roles.rb +54 -27
- data/lib/morpheus/cli/security_group_rules.rb +2 -2
- data/lib/morpheus/cli/security_groups.rb +23 -19
- data/lib/morpheus/cli/set_prompt_command.rb +50 -0
- data/lib/morpheus/cli/shell.rb +222 -157
- data/lib/morpheus/cli/tasks.rb +19 -15
- data/lib/morpheus/cli/users.rb +27 -17
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/virtual_images.rb +28 -13
- data/lib/morpheus/cli/whoami.rb +131 -52
- data/lib/morpheus/cli/workflows.rb +24 -9
- data/lib/morpheus/formatters.rb +195 -3
- data/lib/morpheus/logging.rb +86 -0
- data/lib/morpheus/terminal.rb +371 -0
- data/scripts/generate_morpheus_commands_help.morpheus +60 -0
- metadata +21 -2
@@ -52,7 +52,7 @@ class Morpheus::Cli::InstanceTypes
|
|
52
52
|
if instance_type.nil?
|
53
53
|
puts yellow,"No instance type found by name #{name}.",reset
|
54
54
|
else
|
55
|
-
|
55
|
+
print_h1 "Instance Type Details"
|
56
56
|
versions = instance_type['versions'].join(', ')
|
57
57
|
print cyan, "= #{instance_type['name']} (#{instance_type['code']}) - #{versions}\n"
|
58
58
|
layout_names = instance_type['instanceTypeLayouts'].collect { |layout| layout['name'] }.uniq.sort
|
@@ -97,7 +97,7 @@ class Morpheus::Cli::InstanceTypes
|
|
97
97
|
end
|
98
98
|
|
99
99
|
instance_types = json_response['instanceTypes']
|
100
|
-
|
100
|
+
print_h1 "Morpheus Instance Types"
|
101
101
|
if instance_types.empty?
|
102
102
|
puts yellow,"No instance types currently configured.",reset
|
103
103
|
else
|
@@ -11,7 +11,7 @@ class Morpheus::Cli::Instances
|
|
11
11
|
include Morpheus::Cli::CliCommand
|
12
12
|
include Morpheus::Cli::ProvisioningHelper
|
13
13
|
|
14
|
-
register_subcommands :list, :get, :add, :update, :remove, :stats, :stop, :start, :restart, :suspend, :eject, :backup, :backups, :stop_service, :start_service, :restart_service, :resize, :clone, :envs, :setenv, :delenv, :security_groups, :apply_security_groups, :firewall_enable, :firewall_disable, :run_workflow, :import_snapshot, :console, :status_check
|
14
|
+
register_subcommands :list, :get, :add, :update, :remove, :logs, :stats, :stop, :start, :restart, :suspend, :eject, :backup, :backups, :stop_service, :start_service, :restart_service, :resize, :clone, :envs, :setenv, :delenv, :security_groups, :apply_security_groups, :firewall_enable, :firewall_disable, :run_workflow, :import_snapshot, :console, :status_check
|
15
15
|
alias_subcommand :details, :get
|
16
16
|
set_default_subcommand :list
|
17
17
|
|
@@ -83,8 +83,7 @@ class Morpheus::Cli::Instances
|
|
83
83
|
end
|
84
84
|
json_response = @instances_interface.create(payload)
|
85
85
|
if options[:json]
|
86
|
-
|
87
|
-
print "\n"
|
86
|
+
puts as_json(json_response, options)
|
88
87
|
else
|
89
88
|
instance_name = json_response["instance"]["name"]
|
90
89
|
print_green_success "Provisioning instance #{instance_name}"
|
@@ -145,8 +144,7 @@ class Morpheus::Cli::Instances
|
|
145
144
|
json_response = @instances_interface.update(instance["id"], payload)
|
146
145
|
|
147
146
|
if options[:json]
|
148
|
-
|
149
|
-
print "\n"
|
147
|
+
puts as_json(json_response, options)
|
150
148
|
else
|
151
149
|
print_green_success "Updated instance #{instance['name']}"
|
152
150
|
list([])
|
@@ -179,7 +177,7 @@ class Morpheus::Cli::Instances
|
|
179
177
|
end
|
180
178
|
if options[:json]
|
181
179
|
mock_json = {status: instance['status'], exit: exit_code}
|
182
|
-
out <<
|
180
|
+
out << as_json(mock_json, options)
|
183
181
|
out << "\n"
|
184
182
|
elsif !options[:quiet]
|
185
183
|
out << cyan
|
@@ -195,7 +193,7 @@ class Morpheus::Cli::Instances
|
|
195
193
|
options = {}
|
196
194
|
optparse = OptionParser.new do|opts|
|
197
195
|
opts.banner = subcommand_usage("[name]")
|
198
|
-
build_common_options(opts, options, [:json, :dry_run, :remote])
|
196
|
+
build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
|
199
197
|
end
|
200
198
|
optparse.parse!(args)
|
201
199
|
if args.count < 1
|
@@ -203,33 +201,40 @@ class Morpheus::Cli::Instances
|
|
203
201
|
exit 1
|
204
202
|
end
|
205
203
|
connect(options)
|
204
|
+
ids = args
|
205
|
+
id_list = parse_id_list(args)
|
206
|
+
return run_command_for_each_arg(id_list) do |arg|
|
207
|
+
_stats(arg, options)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
def _stats(arg, options)
|
206
212
|
begin
|
207
|
-
instance = find_instance_by_name_or_id(
|
213
|
+
instance = find_instance_by_name_or_id(arg)
|
208
214
|
if options[:dry_run]
|
209
215
|
print_dry_run @instances_interface.dry.get(instance['id'])
|
210
|
-
return
|
216
|
+
return 0
|
211
217
|
end
|
212
218
|
json_response = @instances_interface.get(instance['id'])
|
213
219
|
if options[:json]
|
214
|
-
|
215
|
-
return
|
220
|
+
puts as_json(json_response, options)
|
221
|
+
return 0
|
222
|
+
elsif options[:yaml]
|
223
|
+
if options[:include_fields]
|
224
|
+
json_response = {"stats" => filter_data(json_response["stats"], options[:include_fields]) }
|
225
|
+
end
|
226
|
+
puts as_yaml(json_response, options)
|
227
|
+
return 0
|
216
228
|
end
|
217
229
|
instance = json_response['instance']
|
218
230
|
stats = json_response['stats'] || {}
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
# stats_map[:cpu] = "#{stats['usedCpu'].to_f.round(2)}%"
|
227
|
-
# tp [stats_map], :memory,:storage,:cpu
|
228
|
-
# print "\n"
|
229
|
-
print_stats_usage(stats)
|
230
|
-
else
|
231
|
-
print cyan, "No data.", "\n", reset
|
232
|
-
end
|
231
|
+
title = "Instance Stats: #{instance['name']} (#{instance['instanceType']['name']})"
|
232
|
+
print_h1 title
|
233
|
+
puts cyan + "Status: ".rjust(12) + format_instance_status(instance).to_s
|
234
|
+
puts cyan + "Nodes: ".rjust(12) + (instance['containers'] ? instance['containers'].count : '').to_s
|
235
|
+
# print "\n"
|
236
|
+
#print_h2 "Instance Usage"
|
237
|
+
print_stats_usage(stats)
|
233
238
|
print reset, "\n"
|
234
239
|
rescue RestClient::Exception => e
|
235
240
|
print_rest_exception(e, options)
|
@@ -281,7 +286,7 @@ class Morpheus::Cli::Instances
|
|
281
286
|
opts.on( '-n', '--node NODE_ID', "Scope logs to specific Container or VM" ) do |node_id|
|
282
287
|
options[:node_id] = node_id.to_i
|
283
288
|
end
|
284
|
-
build_common_options(opts, options, [:list, :json, :dry_run, :remote])
|
289
|
+
build_common_options(opts, options, [:list, :json, :csv, :dry_run, :remote])
|
285
290
|
end
|
286
291
|
optparse.parse!(args)
|
287
292
|
if args.count < 1
|
@@ -295,32 +300,52 @@ class Morpheus::Cli::Instances
|
|
295
300
|
if options[:node_id] && container_ids.include?(options[:node_id])
|
296
301
|
container_ids = [options[:node_id]]
|
297
302
|
end
|
298
|
-
|
303
|
+
params = {}
|
304
|
+
[:phrase, :offset, :max, :sort, :direction].each do |k|
|
305
|
+
params[k] = options[k] unless options[k].nil?
|
306
|
+
end
|
307
|
+
params[:query] = params.delete(:phrase) unless params[:phrase].nil?
|
299
308
|
if options[:dry_run]
|
300
|
-
print_dry_run @logs_interface.dry.
|
309
|
+
print_dry_run @logs_interface.dry.server_logs([server['id']], params)
|
301
310
|
return
|
302
311
|
end
|
303
|
-
|
312
|
+
if options[:dry_run]
|
313
|
+
print_dry_run @logs_interface.dry.container_logs(container_ids, params)
|
314
|
+
return
|
315
|
+
end
|
316
|
+
logs = @logs_interface.container_logs(container_ids, params)
|
317
|
+
output = ""
|
304
318
|
if options[:json]
|
305
|
-
|
319
|
+
output << as_json(logs, options)
|
306
320
|
else
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
321
|
+
title = "Instance Logs: #{instance['name']} (#{instance['instanceType'] ? instance['instanceType']['name'] : ''})"
|
322
|
+
subtitles = []
|
323
|
+
if params[:query]
|
324
|
+
subtitles << "Search: #{params[:query]}".strip
|
325
|
+
end
|
326
|
+
# todo: startMs, endMs, sorts insteaad of sort..etc
|
327
|
+
print_h1 title, subtitles
|
328
|
+
if logs['data'].empty?
|
329
|
+
output << "#{cyan}No logs found.#{reset}\n"
|
330
|
+
else
|
331
|
+
logs['data'].reverse.each do |log_entry|
|
332
|
+
log_level = ''
|
333
|
+
case log_entry['level']
|
334
|
+
when 'INFO'
|
335
|
+
log_level = "#{blue}#{bold}INFO#{reset}"
|
336
|
+
when 'DEBUG'
|
337
|
+
log_level = "#{white}#{bold}DEBUG#{reset}"
|
338
|
+
when 'WARN'
|
339
|
+
log_level = "#{yellow}#{bold}WARN#{reset}"
|
340
|
+
when 'ERROR'
|
341
|
+
log_level = "#{red}#{bold}ERROR#{reset}"
|
342
|
+
when 'FATAL'
|
343
|
+
log_level = "#{red}#{bold}FATAL#{reset}"
|
344
|
+
end
|
345
|
+
output << "[#{log_entry['ts']}] #{log_level} - #{log_entry['message']}\n"
|
320
346
|
end
|
321
|
-
puts "[#{log_entry['ts']}] #{log_level} - #{log_entry['message']}"
|
322
347
|
end
|
323
|
-
print reset,"\n"
|
348
|
+
print output, reset, "\n"
|
324
349
|
end
|
325
350
|
rescue RestClient::Exception => e
|
326
351
|
print_rest_exception(e, options)
|
@@ -332,7 +357,7 @@ class Morpheus::Cli::Instances
|
|
332
357
|
options = {}
|
333
358
|
optparse = OptionParser.new do|opts|
|
334
359
|
opts.banner = subcommand_usage("[name]")
|
335
|
-
build_common_options(opts, options, [:json, :dry_run, :remote])
|
360
|
+
build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
|
336
361
|
end
|
337
362
|
optparse.parse!(args)
|
338
363
|
if args.count < 1
|
@@ -340,54 +365,67 @@ class Morpheus::Cli::Instances
|
|
340
365
|
exit 1
|
341
366
|
end
|
342
367
|
connect(options)
|
368
|
+
id_list = parse_id_list(args)
|
369
|
+
return run_command_for_each_arg(id_list) do |arg|
|
370
|
+
_get(arg, options)
|
371
|
+
end
|
372
|
+
end
|
373
|
+
|
374
|
+
def _get(arg, options)
|
343
375
|
begin
|
344
376
|
if options[:dry_run]
|
345
|
-
if
|
346
|
-
print_dry_run @instances_interface.dry.get(
|
377
|
+
if arg.to_s =~ /\A\d{1,}\Z/
|
378
|
+
print_dry_run @instances_interface.dry.get(arg.to_i)
|
347
379
|
else
|
348
|
-
print_dry_run @instances_interface.dry.get({name:
|
380
|
+
print_dry_run @instances_interface.dry.get({name:arg})
|
349
381
|
end
|
350
382
|
return
|
351
383
|
end
|
352
|
-
instance = find_instance_by_name_or_id(
|
384
|
+
instance = find_instance_by_name_or_id(arg)
|
353
385
|
json_response = @instances_interface.get(instance['id'])
|
354
386
|
if options[:json]
|
355
|
-
|
356
|
-
|
387
|
+
if options[:include_fields]
|
388
|
+
json_response = {"instance" => filter_data(json_response["instance"], options[:include_fields]) }
|
389
|
+
end
|
390
|
+
puts as_json(json_response, options)
|
391
|
+
return 0
|
392
|
+
elsif options[:yaml]
|
393
|
+
if options[:include_fields]
|
394
|
+
json_response = {"instance" => filter_data(json_response["instance"], options[:include_fields]) }
|
395
|
+
end
|
396
|
+
puts as_yaml(json_response, options)
|
397
|
+
return 0
|
398
|
+
end
|
399
|
+
|
400
|
+
if options[:csv]
|
401
|
+
puts records_as_csv([json_response['instance']], options)
|
402
|
+
return 0
|
357
403
|
end
|
358
404
|
instance = json_response['instance']
|
359
405
|
stats = json_response['stats'] || {}
|
360
406
|
# load_balancers = stats = json_response['loadBalancers'] || {}
|
361
407
|
|
362
|
-
|
363
|
-
if !instance['connectionInfo'].nil? && instance['connectionInfo'].empty? == false
|
364
|
-
connection_string = "#{instance['connectionInfo'][0]['ip']}:#{instance['connectionInfo'][0]['port']}"
|
365
|
-
end
|
366
|
-
|
367
|
-
print "\n" ,cyan, bold, "Instance Details\n","==================", reset, "\n\n"
|
408
|
+
print_h1 "Instance Details"
|
368
409
|
print cyan
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
# tp [stats_map], :memory,:storage,:cpu
|
410
|
+
description_cols = {
|
411
|
+
"ID" => 'id',
|
412
|
+
"Name" => 'name',
|
413
|
+
"Description" => 'description',
|
414
|
+
"Group" => lambda {|it| it['group'] ? it['group']['name'] : '' },
|
415
|
+
"Cloud" => lambda {|it| it['cloud'] ? it['cloud']['name'] : '' },
|
416
|
+
"Type" => lambda {|it| it['instanceType']['name'] },
|
417
|
+
"Plan" => lambda {|it| it['plan'] ? it['plan']['name'] : '' },
|
418
|
+
"Environment" => 'instanceContext',
|
419
|
+
"Nodes" => lambda {|it| it['containers'] ? it['containers'].count : 0 },
|
420
|
+
"Connection" => lambda {|it| format_instance_connection_string(it) },
|
421
|
+
#"Account" => lambda {|it| it['account'] ? it['account']['name'] : '' },
|
422
|
+
"Status" => lambda {|it| format_instance_status(it) }
|
423
|
+
}
|
424
|
+
print_description_list(description_cols, instance)
|
425
|
+
|
426
|
+
if (stats)
|
427
|
+
print_h2 "Instance Usage"
|
388
428
|
print_stats_usage(stats)
|
389
|
-
else
|
390
|
-
# print cyan, "No data.", "\n", reset
|
391
429
|
end
|
392
430
|
print reset, "\n"
|
393
431
|
|
@@ -419,19 +457,14 @@ class Morpheus::Cli::Instances
|
|
419
457
|
end
|
420
458
|
json_response = @instances_interface.backups(instance['id'], params)
|
421
459
|
if options[:json]
|
422
|
-
|
460
|
+
puts as_json(json_response, options)
|
423
461
|
return
|
424
462
|
end
|
425
463
|
backups = json_response['backups']
|
426
464
|
stats = json_response['stats'] || {}
|
427
465
|
# load_balancers = stats = json_response['loadBalancers'] || {}
|
428
466
|
|
429
|
-
|
430
|
-
print cyan
|
431
|
-
puts "ID: #{instance['id']}"
|
432
|
-
puts "Name: #{instance['name']}"
|
433
|
-
print "\n"
|
434
|
-
puts "Backups:"
|
467
|
+
print_h1 "Instance Backups: #{instance['name']} (#{instance['instanceType']['name']})"
|
435
468
|
backup_rows = backups.collect {|it| {id: it['id'], name: it['name'], dateCreated: it['dateCreated']} }
|
436
469
|
print cyan
|
437
470
|
tp backup_rows, [
|
@@ -494,8 +527,7 @@ class Morpheus::Cli::Instances
|
|
494
527
|
end
|
495
528
|
json_response = @instances_interface.clone(instance['id'], payload)
|
496
529
|
if options[:json]
|
497
|
-
|
498
|
-
print "\n"
|
530
|
+
puts as_json(json_response, options)
|
499
531
|
else
|
500
532
|
print_green_success "Cloning instance #{instance['name']} to '#{payload['name']}'"
|
501
533
|
end
|
@@ -527,16 +559,17 @@ class Morpheus::Cli::Instances
|
|
527
559
|
end
|
528
560
|
json_response = @instances_interface.get_envs(instance['id'])
|
529
561
|
if options[:json]
|
530
|
-
|
562
|
+
puts as_json(json_response, options)
|
531
563
|
return
|
532
564
|
end
|
533
|
-
|
565
|
+
print_h1 "Instance Envs: #{instance['name']} (#{instance['instanceType']['name']})"
|
566
|
+
print cyan
|
534
567
|
envs = json_response['envs'] || {}
|
535
568
|
if json_response['readOnlyEnvs']
|
536
569
|
envs += json_response['readOnlyEnvs'].map { |k,v| {:name => k, :value => k.downcase.include?("password") || v['masked'] ? "********" : v['value'], :export => true}}
|
537
570
|
end
|
538
571
|
tp envs, :name, :value, :export
|
539
|
-
|
572
|
+
print_h2 "Imported Envs"
|
540
573
|
imported_envs = json_response['importedEnvs'].map { |k,v| {:name => k, :value => k.downcase.include?("password") || v['masked'] ? "********" : v['value']}}
|
541
574
|
tp imported_envs
|
542
575
|
print reset, "\n"
|
@@ -575,7 +608,7 @@ class Morpheus::Cli::Instances
|
|
575
608
|
end
|
576
609
|
json_response = @instances_interface.create_env(instance['id'], payload)
|
577
610
|
if options[:json]
|
578
|
-
|
611
|
+
puts as_json(json_response, options)
|
579
612
|
return
|
580
613
|
end
|
581
614
|
if !options[:quiet]
|
@@ -607,7 +640,7 @@ class Morpheus::Cli::Instances
|
|
607
640
|
end
|
608
641
|
json_response = @instances_interface.del_env(instance['id'], args[1])
|
609
642
|
if options[:json]
|
610
|
-
|
643
|
+
puts as_json(json_response, options)
|
611
644
|
return
|
612
645
|
end
|
613
646
|
if !options[:quiet]
|
@@ -642,7 +675,7 @@ class Morpheus::Cli::Instances
|
|
642
675
|
end
|
643
676
|
json_response = @instances_interface.stop(instance['id'])
|
644
677
|
if options[:json]
|
645
|
-
|
678
|
+
puts as_json(json_response, options)
|
646
679
|
print "\n"
|
647
680
|
end
|
648
681
|
return
|
@@ -672,8 +705,8 @@ class Morpheus::Cli::Instances
|
|
672
705
|
end
|
673
706
|
json_response = @instances_interface.start(instance['id'])
|
674
707
|
if options[:json]
|
675
|
-
|
676
|
-
|
708
|
+
puts as_json(json_response, options)
|
709
|
+
return 0
|
677
710
|
end
|
678
711
|
return
|
679
712
|
rescue RestClient::Exception => e
|
@@ -705,8 +738,7 @@ class Morpheus::Cli::Instances
|
|
705
738
|
end
|
706
739
|
json_response = @instances_interface.restart(instance['id'])
|
707
740
|
if options[:json]
|
708
|
-
|
709
|
-
print "\n"
|
741
|
+
puts as_json(json_response, options)
|
710
742
|
end
|
711
743
|
return
|
712
744
|
rescue RestClient::Exception => e
|
@@ -738,10 +770,9 @@ class Morpheus::Cli::Instances
|
|
738
770
|
end
|
739
771
|
json_response = @instances_interface.suspend(instance['id'])
|
740
772
|
if options[:json]
|
741
|
-
|
742
|
-
print "\n"
|
773
|
+
puts as_json(json_response, options)
|
743
774
|
end
|
744
|
-
return
|
775
|
+
return 0
|
745
776
|
rescue RestClient::Exception => e
|
746
777
|
print_rest_exception(e, options)
|
747
778
|
exit 1
|
@@ -771,10 +802,9 @@ class Morpheus::Cli::Instances
|
|
771
802
|
end
|
772
803
|
json_response = @instances_interface.eject(instance['id'])
|
773
804
|
if options[:json]
|
774
|
-
|
775
|
-
print "\n"
|
805
|
+
puts as_json(json_response, options)
|
776
806
|
end
|
777
|
-
return
|
807
|
+
return 0
|
778
808
|
rescue RestClient::Exception => e
|
779
809
|
print_rest_exception(e, options)
|
780
810
|
exit 1
|
@@ -804,12 +834,11 @@ class Morpheus::Cli::Instances
|
|
804
834
|
end
|
805
835
|
json_response = @instances_interface.stop(instance['id'],false)
|
806
836
|
if options[:json]
|
807
|
-
|
808
|
-
print "\n"
|
837
|
+
puts as_json(json_response, options)
|
809
838
|
else
|
810
839
|
puts "Stopping service on #{args[0]}"
|
811
840
|
end
|
812
|
-
return
|
841
|
+
return 0
|
813
842
|
rescue RestClient::Exception => e
|
814
843
|
print_rest_exception(e, options)
|
815
844
|
exit 1
|
@@ -836,12 +865,11 @@ class Morpheus::Cli::Instances
|
|
836
865
|
end
|
837
866
|
json_response = @instances_interface.start(instance['id'],false)
|
838
867
|
if options[:json]
|
839
|
-
|
840
|
-
print "\n"
|
868
|
+
puts as_json(json_response, options)
|
841
869
|
else
|
842
870
|
puts "Starting service on #{args[0]}"
|
843
871
|
end
|
844
|
-
return
|
872
|
+
return 0
|
845
873
|
rescue RestClient::Exception => e
|
846
874
|
print_rest_exception(e, options)
|
847
875
|
exit 1
|
@@ -871,8 +899,7 @@ class Morpheus::Cli::Instances
|
|
871
899
|
end
|
872
900
|
json_response = @instances_interface.restart(instance['id'],false)
|
873
901
|
if options[:json]
|
874
|
-
|
875
|
-
print "\n"
|
902
|
+
puts as_json(json_response, options)
|
876
903
|
else
|
877
904
|
puts "Restarting service on instance #{args[0]}"
|
878
905
|
end
|
@@ -947,8 +974,8 @@ class Morpheus::Cli::Instances
|
|
947
974
|
end
|
948
975
|
json_response = @instances_interface.resize(instance['id'], payload)
|
949
976
|
if options[:json]
|
950
|
-
|
951
|
-
|
977
|
+
puts as_json(json_response, options)
|
978
|
+
return 0
|
952
979
|
else
|
953
980
|
print_green_success "Resizing instance #{instance['name']}"
|
954
981
|
list([])
|
@@ -982,12 +1009,12 @@ class Morpheus::Cli::Instances
|
|
982
1009
|
end
|
983
1010
|
json_response = @instances_interface.backup(instance['id'])
|
984
1011
|
if options[:json]
|
985
|
-
|
986
|
-
|
1012
|
+
puts as_json(json_response, options)
|
1013
|
+
return 0
|
987
1014
|
else
|
988
1015
|
puts "Backup initiated."
|
1016
|
+
return 0
|
989
1017
|
end
|
990
|
-
return
|
991
1018
|
rescue RestClient::Exception => e
|
992
1019
|
print_rest_exception(e, options)
|
993
1020
|
exit 1
|
@@ -1004,7 +1031,7 @@ class Morpheus::Cli::Instances
|
|
1004
1031
|
opts.on( '-c', '--cloud CLOUD', "Cloud Name or ID" ) do |val|
|
1005
1032
|
options[:cloud] = val
|
1006
1033
|
end
|
1007
|
-
build_common_options(opts, options, [:list, :json, :dry_run, :remote])
|
1034
|
+
build_common_options(opts, options, [:list, :json, :yaml, :csv, :fields, :dry_run, :remote])
|
1008
1035
|
end
|
1009
1036
|
optparse.parse!(args)
|
1010
1037
|
connect(options)
|
@@ -1032,8 +1059,26 @@ class Morpheus::Cli::Instances
|
|
1032
1059
|
end
|
1033
1060
|
json_response = @instances_interface.get(params)
|
1034
1061
|
if options[:json]
|
1035
|
-
|
1036
|
-
|
1062
|
+
if options[:include_fields]
|
1063
|
+
json_response = {"instances" => filter_data(json_response["instances"], options[:include_fields]) }
|
1064
|
+
end
|
1065
|
+
puts as_json(json_response, options)
|
1066
|
+
return 0
|
1067
|
+
elsif options[:yaml]
|
1068
|
+
if options[:include_fields]
|
1069
|
+
json_response = {"instances" => filter_data(json_response["instances"], options[:include_fields]) }
|
1070
|
+
end
|
1071
|
+
puts as_yaml(json_response, options)
|
1072
|
+
return 0
|
1073
|
+
elsif options[:csv]
|
1074
|
+
# merge stats to be nice here..
|
1075
|
+
if json_response['instances']
|
1076
|
+
all_stats = json_response['stats'] || {}
|
1077
|
+
json_response['instances'].each do |it|
|
1078
|
+
it['stats'] ||= all_stats[it['id'].to_s] || all_stats[it['id']]
|
1079
|
+
end
|
1080
|
+
end
|
1081
|
+
puts records_as_csv(json_response['instances'], options)
|
1037
1082
|
else
|
1038
1083
|
instances = json_response['instances']
|
1039
1084
|
|
@@ -1048,12 +1093,55 @@ class Morpheus::Cli::Instances
|
|
1048
1093
|
if params[:phrase]
|
1049
1094
|
subtitles << "Search: #{params[:phrase]}".strip
|
1050
1095
|
end
|
1051
|
-
|
1052
|
-
print "\n" ,cyan, bold, title, (subtitle.empty? ? "" : " - #{subtitle}"), "\n", "==================", reset, "\n\n"
|
1096
|
+
print_h1 title, subtitles
|
1053
1097
|
if instances.empty?
|
1054
|
-
|
1098
|
+
print yellow,"No instances found.",reset,"\n"
|
1055
1099
|
else
|
1056
|
-
print_instances_table(instances)
|
1100
|
+
# print_instances_table(instances)
|
1101
|
+
# server returns stats in a separate key stats => {"id" => {} }
|
1102
|
+
# the id is a string right now..for some reason..
|
1103
|
+
all_stats = json_response['stats'] || {}
|
1104
|
+
instances.each do |it|
|
1105
|
+
if !it['stats']
|
1106
|
+
found_stats = all_stats[it['id'].to_s] || all_stats[it['id']]
|
1107
|
+
it['stats'] = found_stats # || {}
|
1108
|
+
end
|
1109
|
+
end
|
1110
|
+
|
1111
|
+
rows = instances.collect {|instance|
|
1112
|
+
stats = instance['stats']
|
1113
|
+
cpu_usage_str = !stats ? "" : generate_usage_bar((stats['usedCpu'] || stats['cpuUsage']).to_f, 100, {max_bars: 10})
|
1114
|
+
memory_usage_str = !stats ? "" : generate_usage_bar(stats['usedMemory'], stats['maxMemory'], {max_bars: 10})
|
1115
|
+
storage_usage_str = !stats ? "" : generate_usage_bar(stats['usedStorage'], stats['maxStorage'], {max_bars: 10})
|
1116
|
+
row = {
|
1117
|
+
id: instance['id'],
|
1118
|
+
name: instance['name'],
|
1119
|
+
connection: format_instance_connection_string(instance),
|
1120
|
+
environment: instance['instanceContext'],
|
1121
|
+
nodes: instance['containers'].count,
|
1122
|
+
status: format_instance_status(instance, cyan),
|
1123
|
+
type: instance['instanceType']['name'],
|
1124
|
+
group: !instance['group'].nil? ? instance['group']['name'] : nil,
|
1125
|
+
cloud: !instance['cloud'].nil? ? instance['cloud']['name'] : nil,
|
1126
|
+
version: instance['instanceVersion'] ? instance['instanceVersion'] : '',
|
1127
|
+
cpu: cpu_usage_str + cyan,
|
1128
|
+
memory: memory_usage_str + cyan,
|
1129
|
+
storage: storage_usage_str + cyan
|
1130
|
+
}
|
1131
|
+
row
|
1132
|
+
}
|
1133
|
+
columns = [:id, :name, :group, :cloud, :type, :version, :environment, :nodes, {:connection => {max_width: 20}}, :status]
|
1134
|
+
term_width = current_terminal_width()
|
1135
|
+
if term_width > 190
|
1136
|
+
columns += [:cpu, :memory, :storage]
|
1137
|
+
end
|
1138
|
+
# custom pretty table columns ...
|
1139
|
+
if options[:include_fields]
|
1140
|
+
columns = options[:include_fields]
|
1141
|
+
end
|
1142
|
+
print cyan
|
1143
|
+
print as_pretty_table(rows, columns, options)
|
1144
|
+
print reset
|
1057
1145
|
print_results_pagination(json_response)
|
1058
1146
|
end
|
1059
1147
|
print reset,"\n"
|
@@ -1095,8 +1183,8 @@ class Morpheus::Cli::Instances
|
|
1095
1183
|
end
|
1096
1184
|
json_response = @instances_interface.destroy(instance['id'],query_params)
|
1097
1185
|
if options[:json]
|
1098
|
-
print
|
1099
|
-
|
1186
|
+
print as_json(json_response, options), "\n"
|
1187
|
+
return
|
1100
1188
|
elsif !options[:quiet]
|
1101
1189
|
list([])
|
1102
1190
|
end
|
@@ -1126,8 +1214,8 @@ class Morpheus::Cli::Instances
|
|
1126
1214
|
end
|
1127
1215
|
json_response = @instances_interface.firewall_disable(instance['id'])
|
1128
1216
|
if options[:json]
|
1129
|
-
print
|
1130
|
-
|
1217
|
+
print as_json(json_response, options), "\n"
|
1218
|
+
return
|
1131
1219
|
elsif !options[:quiet]
|
1132
1220
|
security_groups([args[0]])
|
1133
1221
|
end
|
@@ -1157,8 +1245,8 @@ class Morpheus::Cli::Instances
|
|
1157
1245
|
end
|
1158
1246
|
json_response = @instances_interface.firewall_enable(instance['id'])
|
1159
1247
|
if options[:json]
|
1160
|
-
print
|
1161
|
-
|
1248
|
+
print as_json(json_response, options), "\n"
|
1249
|
+
return
|
1162
1250
|
elsif !options[:quiet]
|
1163
1251
|
security_groups([args[0]])
|
1164
1252
|
end
|
@@ -1188,21 +1276,24 @@ class Morpheus::Cli::Instances
|
|
1188
1276
|
end
|
1189
1277
|
json_response = @instances_interface.security_groups(instance['id'])
|
1190
1278
|
if options[:json]
|
1191
|
-
print
|
1192
|
-
print "\n"
|
1279
|
+
print as_json(json_response, options), "\n"
|
1193
1280
|
return
|
1194
1281
|
end
|
1195
1282
|
securityGroups = json_response['securityGroups']
|
1196
|
-
|
1197
|
-
print cyan
|
1283
|
+
print_h1 "Morpheus Security Groups for Instance: #{instance['name']}"
|
1284
|
+
print cyan
|
1285
|
+
print_description_list({"Firewall Enabled" => lambda {|it| format_boolean it['firewallEnabled'] } }, json_response)
|
1286
|
+
#print cyan, "Firewall Enabled=#{json_response['firewallEnabled']}\n\n"
|
1198
1287
|
if securityGroups.empty?
|
1199
|
-
|
1288
|
+
print yellow,"\n","No security groups currently applied.",reset,"\n"
|
1200
1289
|
else
|
1290
|
+
print "\n"
|
1201
1291
|
securityGroups.each do |securityGroup|
|
1202
1292
|
print cyan, "= #{securityGroup['id']} (#{securityGroup['name']}) - (#{securityGroup['description']})\n"
|
1203
1293
|
end
|
1294
|
+
print "\n"
|
1204
1295
|
end
|
1205
|
-
print reset,"\n"
|
1296
|
+
print reset, "\n"
|
1206
1297
|
|
1207
1298
|
rescue RestClient::Exception => e
|
1208
1299
|
print_rest_exception(e, options)
|
@@ -1245,8 +1336,7 @@ class Morpheus::Cli::Instances
|
|
1245
1336
|
end
|
1246
1337
|
json_response = @instances_interface.apply_security_groups(instance['id'], payload)
|
1247
1338
|
if options[:json]
|
1248
|
-
print
|
1249
|
-
print "\n"
|
1339
|
+
print as_json(json_response, options), "\n"
|
1250
1340
|
return
|
1251
1341
|
end
|
1252
1342
|
if !options[:quiet]
|
@@ -1303,8 +1393,8 @@ class Morpheus::Cli::Instances
|
|
1303
1393
|
end
|
1304
1394
|
json_response = @instances_interface.workflow(instance['id'],workflow['id'], workflow_payload)
|
1305
1395
|
if options[:json]
|
1306
|
-
print
|
1307
|
-
|
1396
|
+
print as_json(json_response, options), "\n"
|
1397
|
+
return
|
1308
1398
|
else
|
1309
1399
|
puts "Running workflow..."
|
1310
1400
|
end
|
@@ -1358,12 +1448,11 @@ class Morpheus::Cli::Instances
|
|
1358
1448
|
end
|
1359
1449
|
json_response = @instances_interface.import_snapshot(instance['id'], payload)
|
1360
1450
|
if options[:json]
|
1361
|
-
|
1362
|
-
print "\n"
|
1451
|
+
puts as_json(json_response, options)
|
1363
1452
|
else
|
1364
1453
|
puts "Snapshot import initiated."
|
1365
1454
|
end
|
1366
|
-
return
|
1455
|
+
return 0
|
1367
1456
|
rescue RestClient::Exception => e
|
1368
1457
|
print_rest_exception(e, options)
|
1369
1458
|
exit 1
|
@@ -1405,30 +1494,25 @@ class Morpheus::Cli::Instances
|
|
1405
1494
|
end
|
1406
1495
|
end
|
1407
1496
|
|
1408
|
-
def print_instances_table(instances, opts={})
|
1409
|
-
|
1410
|
-
|
1411
|
-
|
1412
|
-
|
1413
|
-
|
1414
|
-
|
1415
|
-
|
1416
|
-
|
1417
|
-
|
1418
|
-
|
1419
|
-
|
1420
|
-
|
1421
|
-
|
1422
|
-
|
1423
|
-
|
1424
|
-
|
1425
|
-
|
1426
|
-
|
1427
|
-
|
1428
|
-
print table_color
|
1429
|
-
tp rows, :id, :name, :group, :cloud, :type, :environment, :nodes, :connection, :status
|
1430
|
-
print reset
|
1431
|
-
end
|
1497
|
+
# def print_instances_table(instances, opts={})
|
1498
|
+
# table_color = opts[:color] || cyan
|
1499
|
+
# rows = instances.collect {|instance|
|
1500
|
+
# {
|
1501
|
+
# id: instance['id'],
|
1502
|
+
# name: instance['name'],
|
1503
|
+
# connection: format_instance_connection_string(instance),
|
1504
|
+
# environment: instance['instanceContext'],
|
1505
|
+
# nodes: instance['containers'].count,
|
1506
|
+
# status: format_instance_status(instance, table_color),
|
1507
|
+
# type: instance['instanceType']['name'],
|
1508
|
+
# group: !instance['group'].nil? ? instance['group']['name'] : nil,
|
1509
|
+
# cloud: !instance['cloud'].nil? ? instance['cloud']['name'] : nil
|
1510
|
+
# }
|
1511
|
+
# }
|
1512
|
+
# print table_color
|
1513
|
+
# tp rows, :id, :name, :group, :cloud, :type, :environment, :nodes, :connection, :status
|
1514
|
+
# print reset
|
1515
|
+
# end
|
1432
1516
|
|
1433
1517
|
def format_instance_status(instance, return_color=cyan)
|
1434
1518
|
out = ""
|
@@ -1445,6 +1529,12 @@ class Morpheus::Cli::Instances
|
|
1445
1529
|
out
|
1446
1530
|
end
|
1447
1531
|
|
1532
|
+
def format_instance_connection_string(instance)
|
1533
|
+
if !instance['connectionInfo'].nil? && instance['connectionInfo'].empty? == false
|
1534
|
+
connection_string = "#{instance['connectionInfo'][0]['ip']}:#{instance['connectionInfo'][0]['port']}"
|
1535
|
+
end
|
1536
|
+
end
|
1537
|
+
|
1448
1538
|
def clone_instance_option_types(connected=true)
|
1449
1539
|
[
|
1450
1540
|
{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'description' => 'Enter a name for the new instance'},
|