morpheus-cli 2.10.3 → 2.11.0
Sign up to get free protection for your applications and to get access to all the features.
- 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'},
|