morpheus-cli 3.5.1.3 → 3.5.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -26,7 +26,7 @@ class Morpheus::Cli::DashboardCommand
26
26
 
27
27
  def show(args)
28
28
  options = {}
29
- optparse = OptionParser.new do|opts|
29
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
30
30
  opts.banner = usage
31
31
  build_common_options(opts, options, [:json, :dry_run]) # todo: support :account
32
32
  end
@@ -24,7 +24,7 @@ class Morpheus::Cli::Deployments
24
24
 
25
25
  def list(args)
26
26
  options = {}
27
- optparse = OptionParser.new do|opts|
27
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
28
28
  opts.banner = subcommand_usage()
29
29
  build_common_options(opts, options, [:list, :json, :dry_run, :remote])
30
30
  end
@@ -64,7 +64,7 @@ class Morpheus::Cli::Deployments
64
64
 
65
65
  def list_versions(args)
66
66
  options = {}
67
- optparse = OptionParser.new do|opts|
67
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
68
68
  opts.banner = subcommand_usage("[name] versions")
69
69
  build_common_options(opts, options, [:list, :json, :dry_run, :remote])
70
70
  end
@@ -114,7 +114,7 @@ class Morpheus::Cli::Deployments
114
114
  deployment_name = args[0]
115
115
  options = {}
116
116
  account_name = nil
117
- optparse = OptionParser.new do|opts|
117
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
118
118
  opts.banner = subcommand_usage("[name] [options]")
119
119
  build_common_options(opts, options, [:options, :json, :dry_run, :remote])
120
120
  end
@@ -169,7 +169,7 @@ class Morpheus::Cli::Deployments
169
169
 
170
170
  def add(args)
171
171
  options = {}
172
- optparse = OptionParser.new do|opts|
172
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
173
173
  opts.banner = subcommand_usage("[name]")
174
174
  opts.on( '-d', '--description DESCRIPTION', "Description" ) do |val|
175
175
  options[:description] = val
@@ -203,7 +203,7 @@ class Morpheus::Cli::Deployments
203
203
 
204
204
  def remove(args)
205
205
  options = {}
206
- optparse = OptionParser.new do|opts|
206
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
207
207
  opts.banner = subcommand_usage("[name]")
208
208
  build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :remote])
209
209
  end
@@ -230,8 +230,18 @@ class Morpheus::Cli::Hosts
230
230
 
231
231
  def get(args)
232
232
  options = {}
233
- optparse = OptionParser.new do|opts|
233
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
234
234
  opts.banner = subcommand_usage("[name]")
235
+ opts.on('--refresh-until [status]', String, "Refresh until status is reached. Default status is provisioned.") do |val|
236
+ if val.to_s.empty?
237
+ options[:refresh_until_status] = "provisioned"
238
+ else
239
+ options[:refresh_until_status] = val.to_s.downcase
240
+ end
241
+ end
242
+ opts.on('--refresh-interval seconds', String, "Refresh interval. Default is 5 seconds.") do |val|
243
+ options[:refresh_interval] = val.to_f
244
+ end
235
245
  build_common_options(opts, options, [:json, :csv, :yaml, :fields, :dry_run, :remote])
236
246
  end
237
247
  optparse.parse!(args)
@@ -297,6 +307,19 @@ class Morpheus::Cli::Hosts
297
307
  print_stats_usage(stats)
298
308
  print reset, "\n"
299
309
 
310
+ # refresh until a status is reached
311
+ if options[:refresh_until_status]
312
+ if options[:refresh_interval].nil? || options[:refresh_interval].to_f < 0
313
+ options[:refresh_interval] = 5
314
+ end
315
+ while server['status'].to_s.downcase != options[:refresh_until_status].to_s.downcase
316
+ print cyan
317
+ print "Refreshing until status #{options[:refresh_until_status]} ..."
318
+ sleep(options[:refresh_interval])
319
+ _get(arg, options)
320
+ end
321
+ end
322
+
300
323
  rescue RestClient::Exception => e
301
324
  print_rest_exception(e, options)
302
325
  exit 1
@@ -305,7 +328,7 @@ class Morpheus::Cli::Hosts
305
328
 
306
329
  def stats(args)
307
330
  options = {}
308
- optparse = OptionParser.new do|opts|
331
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
309
332
  opts.banner = subcommand_usage("[name]")
310
333
  build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
311
334
  end
@@ -365,7 +388,7 @@ class Morpheus::Cli::Hosts
365
388
 
366
389
  def logs(args)
367
390
  options = {}
368
- optparse = OptionParser.new do|opts|
391
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
369
392
  opts.banner = subcommand_usage("[name]")
370
393
  build_common_options(opts, options, [:list, :json, :dry_run, :remote])
371
394
  end
@@ -428,7 +451,7 @@ class Morpheus::Cli::Hosts
428
451
 
429
452
  def server_types(args)
430
453
  options = {}
431
- optparse = OptionParser.new do|opts|
454
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
432
455
  opts.banner = subcommand_usage("[cloud]")
433
456
  build_common_options(opts, options, [:json, :remote])
434
457
  end
@@ -463,7 +486,7 @@ class Morpheus::Cli::Hosts
463
486
 
464
487
  def add(args)
465
488
  options = {}
466
- optparse = OptionParser.new do|opts|
489
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
467
490
  opts.banner = subcommand_usage("[cloud]", "[name]")
468
491
  opts.on( '-g', '--group GROUP', "Group Name or ID" ) do |val|
469
492
  options[:group] = val
@@ -634,27 +657,27 @@ class Morpheus::Cli::Hosts
634
657
 
635
658
  def remove(args)
636
659
  options = {}
637
- query_params = {removeResources: 'on', force: 'off'}
638
- optparse = OptionParser.new do|opts|
639
- opts.banner = subcommand_usage("[name] [-fS]")
640
- opts.on( '-f', '--force', "Force Delete" ) do
641
- query_params[:force] = 'on'
642
- end
643
- opts.on( '-S', '--skip-remove-infrastructure', "Skip removal of underlying cloud infrastructure. Same as --remove-resources off" ) do
644
- query_params[:removeResources] = 'off'
645
- end
660
+ query_params = {}
661
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
662
+ opts.banner = subcommand_usage("[name]")
663
+ # opts.on( '-S', '--skip-remove-infrastructure', "Skip removal of underlying cloud infrastructure. Same as --remove-resources off" ) do
664
+ # query_params[:removeResources] = 'off'
665
+ # end
646
666
  opts.on('--remove-resources [on|off]', ['on','off'], "Remove Infrastructure. Default is on if server is managed.") do |val|
647
667
  query_params[:removeResources] = val
648
668
  end
649
- opts.on('--remove-volumes [on|off]', ['on','off'], "Remove Volumes. Default is on.") do |val|
650
- query_params[:removeVolumes] = val
669
+ opts.on('--preserve-volumes [on|off]', ['on','off'], "Preserve Volumes. Default is off.") do |val|
670
+ query_params[:preserveVolumes] = val
651
671
  end
652
- opts.on('--remove-instances [on|off]', ['on','off'], "Remove Associated Instances.") do |val|
672
+ opts.on('--remove-instances [on|off]', ['on','off'], "Remove Associated Instances. Default is off.") do |val|
653
673
  query_params[:removeInstances] = val
654
674
  end
655
- opts.on('--release-eips [on|off]', ['on','off'], "Release EIPs, default is true. Amazon only.") do |val|
675
+ opts.on('--release-eips [on|off]', ['on','off'], "Release EIPs, default is on. Amazon only.") do |val|
656
676
  params[:releaseEIPs] = val
657
677
  end
678
+ opts.on( '-f', '--force', "Force Delete" ) do
679
+ query_params[:force] = 'on'
680
+ end
658
681
  build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :quiet, :remote])
659
682
  end
660
683
  optparse.parse!(args)
@@ -689,7 +712,7 @@ class Morpheus::Cli::Hosts
689
712
 
690
713
  def start(args)
691
714
  options = {}
692
- optparse = OptionParser.new do|opts|
715
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
693
716
  opts.banner = subcommand_usage("[name]")
694
717
  build_common_options(opts, options, [:json, :dry_run, :quiet, :remote])
695
718
  end
@@ -721,7 +744,7 @@ class Morpheus::Cli::Hosts
721
744
 
722
745
  def stop(args)
723
746
  options = {}
724
- optparse = OptionParser.new do|opts|
747
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
725
748
  opts.banner = subcommand_usage("[name]")
726
749
  build_common_options(opts, options, [:json, :dry_run, :quiet, :remote])
727
750
  end
@@ -753,7 +776,7 @@ class Morpheus::Cli::Hosts
753
776
 
754
777
  def resize(args)
755
778
  options = {}
756
- optparse = OptionParser.new do|opts|
779
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
757
780
  opts.banner = subcommand_usage("[name]")
758
781
  build_common_options(opts, options, [:options, :json, :dry_run, :quiet, :remote])
759
782
  end
@@ -847,7 +870,7 @@ class Morpheus::Cli::Hosts
847
870
 
848
871
  def install_agent(args)
849
872
  options = {}
850
- optparse = OptionParser.new do|opts|
873
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
851
874
  opts.banner = subcommand_usage("[name]")
852
875
  build_option_type_options(opts, options, install_agent_option_types(false))
853
876
  build_common_options(opts, options, [:json, :dry_run, :quiet, :remote])
@@ -899,7 +922,7 @@ class Morpheus::Cli::Hosts
899
922
 
900
923
  def upgrade_agent(args)
901
924
  options = {}
902
- optparse = OptionParser.new do|opts|
925
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
903
926
  opts.banner = subcommand_usage("[name]")
904
927
  build_common_options(opts, options, [:json, :dry_run, :quiet, :remote])
905
928
  end
@@ -57,7 +57,7 @@ class Morpheus::Cli::ImageBuilderCommand
57
57
 
58
58
  def list(args)
59
59
  options = {}
60
- optparse = OptionParser.new do|opts|
60
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
61
61
  opts.banner = subcommand_usage()
62
62
  build_common_options(opts, options, [:list, :json, :dry_run])
63
63
  end
@@ -138,7 +138,7 @@ class Morpheus::Cli::ImageBuilderCommand
138
138
 
139
139
  def get(args)
140
140
  options = {}
141
- optparse = OptionParser.new do|opts|
141
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
142
142
  opts.banner = subcommand_usage("[image-build]")
143
143
  build_common_options(opts, options, [:json, :dry_run])
144
144
  end
@@ -275,7 +275,7 @@ class Morpheus::Cli::ImageBuilderCommand
275
275
 
276
276
  def add(args)
277
277
  options = {}
278
- optparse = OptionParser.new do|opts|
278
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
279
279
  opts.banner = subcommand_usage("[options]")
280
280
  # build_option_type_options(opts, options, add_image_build_option_types(false))
281
281
  opts.on( '-t', '--type TYPE', "Image Build Type" ) do |val|
@@ -397,7 +397,7 @@ class Morpheus::Cli::ImageBuilderCommand
397
397
 
398
398
  def update(args)
399
399
  options = {}
400
- optparse = OptionParser.new do|opts|
400
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
401
401
  opts.banner = subcommand_usage("[image-build] [options]")
402
402
  # build_option_type_options(opts, options, update_image_build_option_types(false))
403
403
  # cannot update type
@@ -517,7 +517,7 @@ class Morpheus::Cli::ImageBuilderCommand
517
517
  def remove(args)
518
518
  options = {}
519
519
  query_params = {}
520
- optparse = OptionParser.new do|opts|
520
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
521
521
  opts.banner = subcommand_usage("[image-build]")
522
522
  opts.on( '-K', '--keep-virtual-images', "Preserve associated virtual images" ) do
523
523
  query_params['keepVirtualImages'] = 'on'
@@ -566,7 +566,7 @@ class Morpheus::Cli::ImageBuilderCommand
566
566
  def run(args)
567
567
  options = {}
568
568
  query_params = {}
569
- optparse = OptionParser.new do|opts|
569
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
570
570
  opts.banner = subcommand_usage("[image-build]")
571
571
  build_common_options(opts, options, [:account, :auto_confirm, :json, :dry_run])
572
572
  end
@@ -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, :count, :get, :add, :update, :remove, :logs, :stats, :stop, :start, :restart, :actions, :action, :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, {:containers => :list_containers}, :scaling, {:'scaling-update' => :scaling_update}
14
+ register_subcommands :list, :count, :get, :add, :update, :update_notes, :remove, :logs, :stats, :stop, :start, :restart, :actions, :action, :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, {:containers => :list_containers}, :scaling, {:'scaling-update' => :scaling_update}
15
15
  # register_subcommands {:'lb-update' => :load_balancer_update}
16
16
  alias_subcommand :details, :get
17
17
  set_default_subcommand :list
@@ -83,19 +83,19 @@ class Morpheus::Cli::Instances
83
83
  end
84
84
  json_response = @instances_interface.list(params)
85
85
  if options[:json]
86
- json_response.delete('stats') if options[:include_fields]
87
86
  puts as_json(json_response, options, "instances")
88
87
  return 0
89
88
  elsif options[:yaml]
90
- json_response.delete('stats') if options[:include_fields]
91
89
  puts as_yaml(json_response, options, "instances")
92
90
  return 0
93
91
  elsif options[:csv]
94
92
  # merge stats to be nice here..
95
93
  if json_response['instances']
96
94
  all_stats = json_response['stats'] || {}
97
- json_response['instances'].each do |it|
98
- it['stats'] ||= all_stats[it['id'].to_s] || all_stats[it['id']]
95
+ if all_stats
96
+ json_response['instances'].each do |it|
97
+ it['stats'] ||= all_stats[it['id'].to_s] || all_stats[it['id']]
98
+ end
99
99
  end
100
100
  end
101
101
  puts records_as_csv(json_response['instances'], options)
@@ -122,10 +122,12 @@ class Morpheus::Cli::Instances
122
122
  # server returns stats in a separate key stats => {"id" => {} }
123
123
  # the id is a string right now..for some reason..
124
124
  all_stats = json_response['stats'] || {}
125
- instances.each do |it|
126
- if !it['stats']
127
- found_stats = all_stats[it['id'].to_s] || all_stats[it['id']]
128
- it['stats'] = found_stats # || {}
125
+ if all_stats
126
+ instances.each do |it|
127
+ if !it['stats']
128
+ found_stats = all_stats[it['id'].to_s] || all_stats[it['id']]
129
+ it['stats'] = found_stats # || {}
130
+ end
129
131
  end
130
132
  end
131
133
 
@@ -344,9 +346,35 @@ class Morpheus::Cli::Instances
344
346
  def update(args)
345
347
  usage = "Usage: morpheus instances update [name] [options]"
346
348
  options = {}
349
+ params = {}
347
350
  optparse = Morpheus::Cli::OptionParser.new do |opts|
348
351
  opts.banner = subcommand_usage("[name]")
349
- build_common_options(opts, options, [:options, :json, :dry_run, :remote])
352
+ opts.on('--name VALUE', String, "Name") do |val|
353
+ params['displayName'] = val
354
+ end
355
+ opts.on('--description VALUE', String, "Description") do |val|
356
+ params['description'] = val
357
+ end
358
+ opts.on('--environment VALUE', String, "Environment") do |val|
359
+ params['instanceContext'] = val
360
+ end
361
+ opts.on('--group GROUP', String, "Group Name or ID") do |val|
362
+ options[:group] = val
363
+ end
364
+ opts.on('--metadata LIST', String, "Metadata in the format 'name:value, name:value'") do |val|
365
+ options[:metadata] = val
366
+ end
367
+ opts.on('--tags LIST', String, "Tags") do |val|
368
+ params['tags'] = val
369
+ # params['tags'] = val.split(',').collect {|it| it.to_s.strip }.compact.uniq
370
+ end
371
+ opts.on('--power-schedule-type ID', String, "Power Schedule Type ID") do |val|
372
+ params['powerScheduleType'] = val == "null" ? nil : val
373
+ end
374
+ opts.on('--created-by ID', String, "Created By User ID") do |val|
375
+ params['createdById'] = val
376
+ end
377
+ build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
350
378
  end
351
379
  optparse.parse!(args)
352
380
  if args.count < 1
@@ -356,33 +384,55 @@ class Morpheus::Cli::Instances
356
384
  connect(options)
357
385
 
358
386
  begin
359
-
360
387
  instance = find_instance_by_name_or_id(args[0])
361
-
362
- payload = {
363
- 'instance' => {id: instance["id"]}
364
- }
365
-
366
- update_instance_option_types = [
367
- {'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'description' => 'Enter a name for this instance'},
368
- {'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'required' => false},
369
- {'fieldName' => 'instanceContext', 'fieldLabel' => 'Environment', 'type' => 'select', 'required' => false, 'selectOptions' => instance_context_options()},
370
- {'fieldName' => 'tags', 'fieldLabel' => 'Tags', 'type' => 'text', 'required' => false}
371
- ]
372
-
373
- params = options[:options] || {}
374
-
375
- if params.empty?
376
- puts "\n#{usage}\n"
377
- option_lines = update_instance_option_types.collect {|it| "\t-O #{it['fieldName']}=\"value\"" }.join("\n")
378
- puts "\nAvailable Options:\n#{option_lines}\n\n"
379
- exit 1
388
+ return 1 if instance.nil?
389
+ new_group = nil
390
+ if options[:group]
391
+ new_group = find_group_by_name_or_id_for_provisioning(options[:group])
392
+ return 1 if new_group.nil?
393
+ params['site'] = {'id' => new_group['id']}
394
+ end
395
+ if options[:metadata]
396
+ if options[:metadata] == "[]" || options[:metadata] == "null"
397
+ params['metadata'] = []
398
+ else
399
+ # parse string into format name:value, name:value
400
+ # merge IDs from current metadata
401
+ # todo: should allow quoted semicolons..
402
+ metadata_list = options[:metadata].split(",").select {|it| !it.to_s.empty? }
403
+ metadata_list = metadata_list.collect do |it|
404
+ metadata_pair = it.split(":")
405
+ row = {}
406
+ row['name'] = metadata_pair[0].to_s.strip
407
+ row['value'] = metadata_pair[1].to_s.strip
408
+ existing_metadata = (instance['metadata'] || []).find { |m| m['name'] == it['name'] }
409
+ if existing_metadata
410
+ row['id'] = existing_metadata['id']
411
+ end
412
+ row
413
+ end
414
+ params['metadata'] = metadata_list
415
+ end
416
+ end
417
+ params.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
418
+ payload = nil
419
+ if options[:payload]
420
+ payload = options[:payload]
421
+ # support args and option parameters on top of payload
422
+ if !params.empty?
423
+ payload['instance'] ||= {}
424
+ payload['instance'].deep_merge!(params)
425
+ end
426
+ else
427
+ if params.empty?
428
+ print_red_alert "Specify atleast one option to update"
429
+ puts optparse
430
+ exit 1
431
+ end
432
+ payload = {}
433
+ payload['instance'] = params
380
434
  end
381
435
 
382
- # instance_keys = ['name', 'description', 'instanceContext', 'tags','configId','configRole','configGroup']
383
- # params = params.select {|k,v| instance_keys.include?(k) }
384
- params['tags'] = params['tags'].split(',').collect {|it| it.to_s.strip }.compact.uniq if params['tags']
385
- payload['instance'].merge!(params)
386
436
  if options[:dry_run]
387
437
  print_dry_run @instances_interface.dry.update(instance["id"], payload)
388
438
  return
@@ -394,8 +444,85 @@ class Morpheus::Cli::Instances
394
444
  else
395
445
  print_green_success "Updated instance #{instance['name']}"
396
446
  #list([])
447
+ get([instance['id']])
448
+ end
449
+ return 0
450
+ rescue RestClient::Exception => e
451
+ print_rest_exception(e, options)
452
+ exit 1
453
+ end
454
+ end
455
+
456
+ def update_notes(args)
457
+ usage = "Usage: morpheus instances update-notes [name] [options]"
458
+ options = {}
459
+ params = {}
460
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
461
+ opts.banner = subcommand_usage("[name]")
462
+ opts.on('--notes VALUE', String, "Notes content (Markdown)") do |val|
463
+ params['notes'] = val
464
+ end
465
+ opts.on('--file FILE', "File containing the notes content. This can be used instead of --notes") do |filename|
466
+ full_filename = File.expand_path(filename)
467
+ if File.exists?(full_filename)
468
+ params['notes'] = File.read(full_filename)
469
+ else
470
+ print_red_alert "File not found: #{full_filename}"
471
+ return 1
472
+ end
473
+ # use the filename as the name by default.
474
+ if !params['name']
475
+ params['name'] = File.basename(full_filename)
476
+ end
477
+ end
478
+ opts.on(nil, '--clear', "Clear current notes") do |val|
479
+ params['notes'] = ""
480
+ end
481
+ build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
482
+ end
483
+ optparse.parse!(args)
484
+ if args.count != 1
485
+ puts_error "#{Morpheus::Terminal.angry_prompt}wrong number of arguments. Expected 1 and received #{args.count} #{args.inspect}\n#{optparse}"
486
+ return 1
487
+ end
488
+ connect(options)
489
+
490
+ begin
491
+ instance = find_instance_by_name_or_id(args[0])
492
+ return 1 if instance.nil?
493
+ new_group = nil
494
+ params.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
495
+ payload = nil
496
+ if options[:payload]
497
+ payload = options[:payload]
498
+ # support args and option parameters on top of payload
499
+ if !params.empty?
500
+ payload['instance'] ||= {}
501
+ payload['instance'].deep_merge!(params)
502
+ end
503
+ else
504
+ if params['notes'].nil?
505
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'notes', 'type' => 'code-editor', 'fieldLabel' => 'Notes', 'required' => true, 'description' => 'Notes (Markdown)'}], options[:options])
506
+ params['notes'] = v_prompt['notes']
507
+ end
508
+ payload = {}
509
+ payload['instance'] = params
397
510
  end
398
511
 
512
+ if options[:dry_run]
513
+ print_dry_run @instances_interface.dry.update_notes(instance["id"], payload)
514
+ return
515
+ end
516
+ json_response = @instances_interface.update_notes(instance["id"], payload)
517
+
518
+ if options[:json]
519
+ puts as_json(json_response, options)
520
+ else
521
+ print_green_success "Updated notes for instance #{instance['name']}"
522
+ #list([])
523
+ get([instance['id']])
524
+ end
525
+ return 0
399
526
  rescue RestClient::Exception => e
400
527
  print_rest_exception(e, options)
401
528
  exit 1
@@ -470,7 +597,7 @@ class Morpheus::Cli::Instances
470
597
  return 0
471
598
  end
472
599
  instance = json_response['instance']
473
- stats = json_response['stats'] || {}
600
+ stats = instance['stats'] || json_response['stats'] || {}
474
601
  title = "Instance Stats: #{instance['name']} (#{instance['instanceType']['name']})"
475
602
  print_h1 title
476
603
  puts cyan + "Status: ".rjust(12) + format_instance_status(instance).to_s
@@ -608,12 +735,22 @@ class Morpheus::Cli::Instances
608
735
  opts.on( nil, '--scaling', "Display Instance Scaling Settings" ) do
609
736
  options[:include_scaling] = true
610
737
  end
738
+ opts.on('--refresh-until [status]', String, "Refresh until status is reached. Default status is running.") do |val|
739
+ if val.to_s.empty?
740
+ options[:refresh_until_status] = "running"
741
+ else
742
+ options[:refresh_until_status] = val.to_s.downcase
743
+ end
744
+ end
745
+ opts.on('--refresh-interval seconds', String, "Refresh interval. Default is 5 seconds.") do |val|
746
+ options[:refresh_interval] = val.to_f
747
+ end
611
748
  # opts.on( nil, '--threshold', "Alias for --scaling" ) do
612
749
  # options[:include_scaling] = true
613
750
  # end
614
- opts.on( nil, '--lb', "Display Load Balancer Details" ) do
615
- options[:include_lb] = true
616
- end
751
+ # opts.on( nil, '--lb', "Display Load Balancer Details" ) do
752
+ # options[:include_lb] = true
753
+ # end
617
754
  build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
618
755
  end
619
756
  optparse.parse!(args)
@@ -641,11 +778,9 @@ class Morpheus::Cli::Instances
641
778
  instance = find_instance_by_name_or_id(arg)
642
779
  json_response = @instances_interface.get(instance['id'])
643
780
  if options[:json]
644
- json_response.delete('stats') if options[:include_fields]
645
781
  puts as_json(json_response, options, "instance")
646
782
  return 0
647
783
  elsif options[:yaml]
648
- json_response.delete('stats') if options[:include_fields]
649
784
  puts as_yaml(json_response, options, "instance")
650
785
  return 0
651
786
  end
@@ -655,7 +790,7 @@ class Morpheus::Cli::Instances
655
790
  return 0
656
791
  end
657
792
  instance = json_response['instance']
658
- stats = json_response['stats'] || {}
793
+ stats = instance['stats'] || json_response['stats'] || {}
659
794
  # load_balancers = json_response['loadBalancers'] || {}
660
795
 
661
796
  # containers are fetched via separate api call
@@ -673,14 +808,14 @@ class Morpheus::Cli::Instances
673
808
  # loadBalancers is returned via show
674
809
  # parse the current api format of loadBalancers.first.lbs.first
675
810
  current_instance_lb = nil
676
- current_load_balancer_port = nil
677
- # if options[:include_lb]
678
- # #load_balancers = @instances_interface.load_balancers(instance['id'])['loadBalancers']
679
- # end
680
- if json_response['loadBalancers'] && json_response['loadBalancers'][0] && json_response['loadBalancers'][0]['lbs'] && json_response['loadBalancers'][0]['lbs'][0]
811
+ if instance["currentLoadBalancerInstances"]
812
+ current_instance_lb = instance['currentLoadBalancerInstances'][0]
813
+ end
814
+
815
+ # support old format
816
+ if !current_instance_lb && json_response['loadBalancers'] && json_response['loadBalancers'][0] && json_response['loadBalancers'][0]['lbs'] && json_response['loadBalancers'][0]['lbs'][0]
681
817
  current_instance_lb = json_response['loadBalancers'][0]['lbs'][0]
682
818
  #current_load_balancer = current_instance_lb['loadBalancer']
683
- #current_load_balancer_port = current_instance_lb['port']
684
819
  end
685
820
 
686
821
  print_h1 "Instance Details"
@@ -692,8 +827,15 @@ class Morpheus::Cli::Instances
692
827
  "Group" => lambda {|it| it['group'] ? it['group']['name'] : '' },
693
828
  "Cloud" => lambda {|it| it['cloud'] ? it['cloud']['name'] : '' },
694
829
  "Type" => lambda {|it| it['instanceType']['name'] },
830
+ "Layout" => lambda {|it| it['layout'] ? it['layout']['name'] : '' },
831
+ "Version" => lambda {|it| it['instanceVersion'] },
695
832
  "Plan" => lambda {|it| it['plan'] ? it['plan']['name'] : '' },
696
833
  "Environment" => 'instanceContext',
834
+ "Tags" => lambda {|it| it['tags'] ? it['tags'].join(',') : '' },
835
+ "Metadata" => lambda {|it| it['metadata'] ? it['metadata'].collect {|m| "#{m['name']}: #{m['value']}" }.join(', ') : '' },
836
+ "Power Schedule" => lambda {|it| (it['powerSchedule'] && it['powerSchedule']['type']) ? it['powerSchedule']['type']['name'] : '' },
837
+ "Created By" => lambda {|it| it['createdBy'] ? (it['createdBy']['username'] || it['createdBy']['id']) : '' },
838
+ "Date Created" => lambda {|it| format_local_dt(it['dateCreated']) },
697
839
  "Nodes" => lambda {|it| it['containers'] ? it['containers'].count : 0 },
698
840
  "Connection" => lambda {|it| format_instance_connection_string(it) },
699
841
  #"Account" => lambda {|it| it['account'] ? it['account']['name'] : '' },
@@ -712,8 +854,11 @@ class Morpheus::Cli::Instances
712
854
  end
713
855
  if instance['errorMessage']
714
856
  print_h2 "Error Message"
715
- print red, instance['errorMessage'], reset
716
- print "\n"
857
+ print red, instance['errorMessage'], reset, "\n"
858
+ end
859
+ if !instance['notes'].to_s.empty?
860
+ print_h2 "Instance Notes"
861
+ print cyan, instance['notes'], reset, "\n"
717
862
  end
718
863
  if stats
719
864
  print_h2 "Instance Usage"
@@ -721,6 +866,27 @@ class Morpheus::Cli::Instances
721
866
  end
722
867
  print reset, "\n"
723
868
 
869
+ # if options[:include_lb]
870
+ if current_instance_lb
871
+ print_h2 "Load Balancer"
872
+ print cyan
873
+ description_cols = {
874
+ "LB ID" => lambda {|it| it['loadBalancer']['id'] },
875
+ "Name" => lambda {|it| it['loadBalancer']['name'] },
876
+ "Type" => lambda {|it| it['loadBalancer']['type'] ? it['loadBalancer']['type']['name'] : '' },
877
+ "Host Name" => lambda {|it| it['vipHostname'] || instance['hostName'] },
878
+ "Port" => lambda {|it| it['vipPort'] },
879
+ "Protocol" => lambda {|it| it['vipProtocol'] || 'tcp' },
880
+ "SSL Enabled" => lambda {|it| format_boolean(it['sslEnabled']) },
881
+ "SSL Cert" => lambda {|it| (it['sslCert']) ? it['sslCert']['name'] : '' },
882
+ "In" => lambda {|it| instance['currentLoadBalancerContainersIn'] },
883
+ "Out" => lambda {|it| instance['currentLoadBalancerContainersOutrelo'] }
884
+ }
885
+ print_description_list(description_cols, current_instance_lb)
886
+ print "\n", reset
887
+ end
888
+ # end
889
+
724
890
  if options[:include_containers]
725
891
  print_h2 "Instance Containers"
726
892
 
@@ -763,26 +929,6 @@ class Morpheus::Cli::Instances
763
929
  print reset,"\n"
764
930
  end
765
931
 
766
- # if options[:include_lb]
767
- if current_instance_lb
768
- print_h2 "Load Balancer"
769
- print cyan
770
- # this api response is going to change again.. port is no longer returned atm.
771
- description_cols = {
772
- "LB ID" => lambda {|it| it['loadBalancer']['id'] },
773
- "Name" => lambda {|it| it['loadBalancer']['name'] },
774
- "Type" => lambda {|it| it['loadBalancer']['type'] ? it['loadBalancer']['type']['name'] : '' },
775
- "Host Name" => lambda {|it| it['loadBalancer']['host'] }, # instance.hostName ?
776
- "Port" => lambda {|it| it['port'] ? it['port']['port'] : '' },
777
- "Protocol" => lambda {|it| it['port'] ? it['port']['proxyProtocol'] : '' },
778
- "SSL Enabled" => lambda {|it| it['port'] ? format_boolean(it['port']['sslEnabled']) : '' },
779
- "Cert" => lambda {|it| (it['port'] && it['port']['sslCert']) ? it['port']['sslCert']['name'] : '' }
780
- }
781
- print_description_list(description_cols, current_instance_lb)
782
- print "\n", reset
783
- end
784
- # end
785
-
786
932
  if options[:include_scaling]
787
933
  print_h2 "Instance Scaling"
788
934
  if instance_threshold.nil? || instance_threshold.empty?
@@ -793,6 +939,20 @@ class Morpheus::Cli::Instances
793
939
  print reset,"\n"
794
940
  end
795
941
  end
942
+
943
+ # refresh until a status is reached
944
+ if options[:refresh_until_status]
945
+ if options[:refresh_interval].nil? || options[:refresh_interval].to_f < 0
946
+ options[:refresh_interval] = 5
947
+ end
948
+ while instance['status'].to_s.downcase != options[:refresh_until_status].to_s.downcase
949
+ print cyan
950
+ print "Refreshing until status #{options[:refresh_until_status]} ..."
951
+ sleep(options[:refresh_interval])
952
+ _get(arg, options)
953
+ end
954
+ end
955
+
796
956
  return 0
797
957
  rescue RestClient::Exception => e
798
958
  print_rest_exception(e, options)
@@ -1646,21 +1806,21 @@ class Morpheus::Cli::Instances
1646
1806
 
1647
1807
  def remove(args)
1648
1808
  options = {}
1649
- query_params = {keepBackups: 'off', force: 'off'}
1809
+ query_params = {}
1650
1810
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1651
- opts.banner = subcommand_usage("[name] [-fB]")
1652
- opts.on( '-f', '--force', "Force Delete" ) do
1653
- query_params[:force] = 'on'
1654
- end
1811
+ opts.banner = subcommand_usage("[name]")
1655
1812
  opts.on( '-B', '--keep-backups', "Preserve copy of backups" ) do
1656
1813
  query_params[:keepBackups] = 'on'
1657
1814
  end
1658
- opts.on('--remove-volumes [on|off]', ['on','off'], "Remove Volumes. Default is on. Applies to certain types only.") do |val|
1659
- query_params[:removeVolumes] = val
1815
+ opts.on('--preserve-volumes [on|off]', ['on','off'], "Preserve Volumes. Default is off. Applies to certain types only.") do |val|
1816
+ query_params[:preserveVolumes] = val
1660
1817
  end
1661
- opts.on('--releaseEIPs [on|off]', ['on','off'], "Release EIPs. Default is false. Applies to Amazon only.") do |val|
1818
+ opts.on('--releaseEIPs [on|off]', ['on','off'], "Release EIPs. Default is on. Applies to Amazon only.") do |val|
1662
1819
  query_params[:releaseEIPs] = val
1663
1820
  end
1821
+ opts.on( '-f', '--force', "Force Delete" ) do
1822
+ query_params[:force] = 'on'
1823
+ end
1664
1824
  build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :quiet, :remote])
1665
1825
 
1666
1826
  end
@@ -1675,6 +1835,10 @@ class Morpheus::Cli::Instances
1675
1835
  unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like to remove the instance '#{instance['name']}'?", options)
1676
1836
  exit 1
1677
1837
  end
1838
+ # JD: removeVolumes to maintain the old behavior with pre-3.5.2 appliances, remove me later
1839
+ if query_params[:preserveVolumes].nil?
1840
+ query_params[:removeVolumes] = 'on'
1841
+ end
1678
1842
  if options[:dry_run]
1679
1843
  print_dry_run @instances_interface.dry.destroy(instance['id'],query_params)
1680
1844
  return
@@ -2170,7 +2334,6 @@ class Morpheus::Cli::Instances
2170
2334
  if json_response['loadBalancers'] && json_response['loadBalancers'][0] && json_response['loadBalancers'][0]['lbs'] && json_response['loadBalancers'][0]['lbs'][0]
2171
2335
  current_instance_lb = json_response['loadBalancers'][0]['lbs'][0]
2172
2336
  #current_load_balancer = current_instance_lb['loadBalancer']
2173
- #current_load_balancer_port = current_instance_lb['port']
2174
2337
  end
2175
2338
 
2176
2339
  #my_option_types = instance_load_balancer_option_types(instance)
@@ -2365,8 +2528,6 @@ private
2365
2528
  out << "#{cyan}#{status_string.upcase}#{return_color}"
2366
2529
  elsif status_string == 'stopped' or status_string == 'failed'
2367
2530
  out << "#{red}#{status_string.upcase}#{return_color}"
2368
- elsif status_string == 'unknown'
2369
- out << "#{yellow}#{status_string.upcase}#{return_color}"
2370
2531
  else
2371
2532
  out << "#{yellow}#{status_string.upcase}#{return_color}"
2372
2533
  end
@@ -2384,10 +2545,10 @@ private
2384
2545
  status_string = container['status'].to_s
2385
2546
  if status_string == 'running'
2386
2547
  out << "#{green}#{status_string.upcase}#{return_color}"
2548
+ elsif status_string == 'provisioning'
2549
+ out << "#{cyan}#{status_string.upcase}#{return_color}"
2387
2550
  elsif status_string == 'stopped' or status_string == 'failed'
2388
2551
  out << "#{red}#{status_string.upcase}#{return_color}"
2389
- elsif status_string == 'unknown'
2390
- out << "#{white}#{status_string.upcase}#{return_color}"
2391
2552
  else
2392
2553
  out << "#{yellow}#{status_string.upcase}#{return_color}"
2393
2554
  end