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.
- checksums.yaml +4 -4
- data/lib/morpheus/api/instances_interface.rb +7 -0
- data/lib/morpheus/api/storage_providers_interface.rb +11 -11
- data/lib/morpheus/cli/accounts.rb +4 -4
- data/lib/morpheus/cli/apps.rb +67 -16
- data/lib/morpheus/cli/boot_scripts_command.rb +5 -5
- data/lib/morpheus/cli/clouds.rb +8 -8
- data/lib/morpheus/cli/containers_command.rb +29 -6
- data/lib/morpheus/cli/dashboard_command.rb +1 -1
- data/lib/morpheus/cli/deployments.rb +5 -5
- data/lib/morpheus/cli/hosts.rb +46 -23
- data/lib/morpheus/cli/image_builder_command.rb +6 -6
- data/lib/morpheus/cli/instances.rb +243 -82
- data/lib/morpheus/cli/key_pairs.rb +6 -6
- data/lib/morpheus/cli/load_balancers.rb +6 -6
- data/lib/morpheus/cli/login.rb +8 -5
- data/lib/morpheus/cli/logout.rb +1 -1
- data/lib/morpheus/cli/monitoring_contacts_command.rb +6 -6
- data/lib/morpheus/cli/monitoring_incidents_command.rb +8 -8
- data/lib/morpheus/cli/preseed_scripts_command.rb +5 -5
- data/lib/morpheus/cli/recent_activity_command.rb +1 -1
- data/lib/morpheus/cli/remote.rb +1 -1
- data/lib/morpheus/cli/security_group_rules.rb +4 -4
- data/lib/morpheus/cli/security_groups.rb +5 -5
- data/lib/morpheus/cli/shell.rb +1 -1
- data/lib/morpheus/cli/storage_providers_command.rb +78 -78
- data/lib/morpheus/cli/tasks.rb +5 -5
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/version_command.rb +1 -1
- data/lib/morpheus/cli/whoami.rb +1 -1
- data/lib/morpheus/cli/workflows.rb +4 -4
- metadata +2 -2
@@ -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
|
data/lib/morpheus/cli/hosts.rb
CHANGED
@@ -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 = {
|
638
|
-
optparse = OptionParser.new do|opts|
|
639
|
-
opts.banner = subcommand_usage("[name]
|
640
|
-
opts.on( '-
|
641
|
-
|
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('--
|
650
|
-
query_params[:
|
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
|
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
|
-
|
98
|
-
|
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
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
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
|
-
|
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
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
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
|
-
|
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
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
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
|
-
|
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 = {
|
1809
|
+
query_params = {}
|
1650
1810
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
1651
|
-
opts.banner = subcommand_usage("[name]
|
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('--
|
1659
|
-
query_params[:
|
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
|
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
|