morpheus-cli 5.5.0 → 5.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Dockerfile +1 -1
- data/lib/morpheus/api/api_client.rb +4 -0
- data/lib/morpheus/api/clusters_interface.rb +12 -0
- data/lib/morpheus/api/network_pool_servers_interface.rb +7 -0
- data/lib/morpheus/api/scale_thresholds_interface.rb +9 -0
- data/lib/morpheus/cli/cli_command.rb +39 -20
- data/lib/morpheus/cli/commands/apps.rb +1 -1
- data/lib/morpheus/cli/commands/cloud_resource_pools_command.rb +33 -2
- data/lib/morpheus/cli/commands/clouds.rb +12 -6
- data/lib/morpheus/cli/commands/clusters.rb +66 -5
- data/lib/morpheus/cli/commands/hosts.rb +5 -1
- data/lib/morpheus/cli/commands/instances.rb +1 -1
- data/lib/morpheus/cli/commands/integrations_command.rb +1 -1
- data/lib/morpheus/cli/commands/invoices_command.rb +8 -1
- data/lib/morpheus/cli/commands/jobs_command.rb +45 -225
- data/lib/morpheus/cli/commands/library_container_types_command.rb +52 -3
- data/lib/morpheus/cli/commands/library_option_types_command.rb +56 -62
- data/lib/morpheus/cli/commands/load_balancers.rb +11 -19
- data/lib/morpheus/cli/commands/network_pool_servers_command.rb +5 -2
- data/lib/morpheus/cli/commands/roles.rb +475 -70
- data/lib/morpheus/cli/commands/scale_thresholds.rb +103 -0
- data/lib/morpheus/cli/commands/tasks.rb +19 -12
- data/lib/morpheus/cli/commands/user_sources_command.rb +107 -39
- data/lib/morpheus/cli/commands/users.rb +10 -10
- data/lib/morpheus/cli/commands/view.rb +1 -0
- data/lib/morpheus/cli/commands/workflows.rb +21 -14
- data/lib/morpheus/cli/error_handler.rb +13 -4
- data/lib/morpheus/cli/mixins/accounts_helper.rb +1 -1
- data/lib/morpheus/cli/mixins/execution_request_helper.rb +1 -1
- data/lib/morpheus/cli/mixins/infrastructure_helper.rb +3 -3
- data/lib/morpheus/cli/mixins/jobs_helper.rb +173 -0
- data/lib/morpheus/cli/mixins/print_helper.rb +120 -38
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +1 -3
- data/lib/morpheus/cli/mixins/rest_command.rb +41 -14
- data/lib/morpheus/cli/option_types.rb +68 -37
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/logging.rb +6 -8
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0f9a8ef29c8d96c51593c8c762e94e34409426fb787ce3944396af9fc1e71279
|
4
|
+
data.tar.gz: 9a89c3ce4161499a9cf9df9ec30d48f0f8e9f4faf04746a19f966c1dc6cda7fd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2d4ef36713c80b4ce6c9037b5ac971f8abdcd65ad4ff732a7e1c9ab89e46ca7199fa4ce7f4bcb5cbe67e79236f9b90ee7b894d1d62ea5809c6da4c7b54e7ca7b
|
7
|
+
data.tar.gz: fc6fca36a81248ad7f44c8dd7aabb03fe60d7b9aaafd03311385a7b86a101a1cfb180dacf1a33d7306a5e5cf204d70ffb7e61ca02cef3c5180ff52df89d8fe65
|
data/Dockerfile
CHANGED
@@ -590,6 +590,10 @@ class Morpheus::APIClient
|
|
590
590
|
Morpheus::OptionTypeListsInterface.new(common_interface_options).setopts(@options)
|
591
591
|
end
|
592
592
|
|
593
|
+
def scale_thresholds
|
594
|
+
Morpheus::ScaleThresholdsInterface.new(common_interface_options).setopts(@options)
|
595
|
+
end
|
596
|
+
|
593
597
|
def power_schedules
|
594
598
|
Morpheus::PowerSchedulesInterface.new(common_interface_options).setopts(@options)
|
595
599
|
end
|
@@ -103,6 +103,18 @@ class Morpheus::ClustersInterface < Morpheus::APIClient
|
|
103
103
|
execute(method: :put, url: url, headers: headers)
|
104
104
|
end
|
105
105
|
|
106
|
+
def get_upgrade_versions(id, params={})
|
107
|
+
url = "#{base_path}/#{id}/upgrade-cluster"
|
108
|
+
headers = { params: params, authorization: "Bearer #{@access_token}" }
|
109
|
+
execute(method: :get, url: url, headers: headers)
|
110
|
+
end
|
111
|
+
|
112
|
+
def do_cluster_upgrade(id, params={})
|
113
|
+
url = "#{base_path}/#{id}/upgrade-cluster"
|
114
|
+
headers = { params: params, authorization: "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
|
115
|
+
execute(method: :post, url: url, headers: headers)
|
116
|
+
end
|
117
|
+
|
106
118
|
def list_services(id, params={})
|
107
119
|
url = "#{base_path}/#{id}/services"
|
108
120
|
headers = { params: params, authorization: "Bearer #{@access_token}" }
|
@@ -38,4 +38,11 @@ class Morpheus::NetworkPoolServersInterface < Morpheus::APIClient
|
|
38
38
|
execute(opts)
|
39
39
|
end
|
40
40
|
|
41
|
+
def get_type(id, params={})
|
42
|
+
raise "#{self.class}.get() passed a blank id!" if id.to_s == ''
|
43
|
+
url = "#{@base_url}/api/networks/pool-server-types/#{id}"
|
44
|
+
headers = { params: params, authorization: "Bearer #{@access_token}" }
|
45
|
+
opts = {method: :get, url: url, headers: headers}
|
46
|
+
execute(opts)
|
47
|
+
end
|
41
48
|
end
|
@@ -479,8 +479,10 @@ module Morpheus
|
|
479
479
|
options[:offset] = offset
|
480
480
|
end
|
481
481
|
|
482
|
-
|
483
|
-
|
482
|
+
if excludes.include?("search") == false
|
483
|
+
opts.on( '-s', '--search PHRASE', "Search Phrase" ) do |phrase|
|
484
|
+
options[:phrase] = phrase
|
485
|
+
end
|
484
486
|
end
|
485
487
|
|
486
488
|
opts.on( '-S', '--sort ORDER', "Sort Order. DIRECTION may be included as \"ORDER [asc|desc]\"." ) do |v|
|
@@ -741,7 +743,15 @@ module Morpheus
|
|
741
743
|
options[:include_fields] = val
|
742
744
|
end
|
743
745
|
end
|
744
|
-
opts.
|
746
|
+
opts.on('--raw-fields [x,y,z]', String, "Raw fields filters output like --fields except the properties [x,y,z] must be specified from the root of the response instead of relative to the the list or object context for this particular resource.") do |val|
|
747
|
+
if val.size == 1 && val[0].downcase == 'all'
|
748
|
+
options[:all_fields] = true
|
749
|
+
else
|
750
|
+
options[:include_fields] = val.split(',').collect {|r| r.strip}.compact
|
751
|
+
end
|
752
|
+
options[:raw_fields] = true
|
753
|
+
end
|
754
|
+
opts.add_hidden_option('--raw-fields') if opts.is_a?(Morpheus::Cli::OptionParser)
|
745
755
|
opts.on(nil, '--all-fields', "Show all fields present in the data.") do
|
746
756
|
options[:all_fields] = true
|
747
757
|
end
|
@@ -753,6 +763,11 @@ module Morpheus
|
|
753
763
|
opts.on('--select x,y,z', String, "Filter Output to just print the value(s) of specific fields.") do |val|
|
754
764
|
options[:select_fields] = val.split(',').collect {|r| r.strip}
|
755
765
|
end
|
766
|
+
opts.on('--raw-select x,y,z', String, "Raw select works like --select except the properties [x,y,z] must be specified from the root of the response instead of relative to the the list or object context for this particular resource.") do |val|
|
767
|
+
options[:select_fields] = val.split(',').collect {|r| r.strip}
|
768
|
+
options[:raw_fields] = true
|
769
|
+
end
|
770
|
+
opts.add_hidden_option('--raw-select') if opts.is_a?(Morpheus::Cli::OptionParser)
|
756
771
|
|
757
772
|
when :delim
|
758
773
|
opts.on('--delimiter [CHAR]', String, "Delimiter for output values. Default: ',', use with --select and --csv") do |val|
|
@@ -1397,29 +1412,33 @@ module Morpheus
|
|
1397
1412
|
def render_response(json_response, options, object_key=nil, &block)
|
1398
1413
|
output = nil
|
1399
1414
|
if options[:select_fields]
|
1400
|
-
|
1401
|
-
|
1402
|
-
|
1403
|
-
|
1404
|
-
|
1405
|
-
|
1406
|
-
|
1407
|
-
|
1408
|
-
|
1409
|
-
|
1410
|
-
|
1415
|
+
# support foos get --raw-select foo.x,foo.y,foo.z
|
1416
|
+
# and foos list --raw-select foos.x,foos.y,foos.z
|
1417
|
+
row = (object_key && !options[:raw_fields]) ? json_response[object_key] : json_response
|
1418
|
+
records = [row].flatten()
|
1419
|
+
# look for an array in the first field only now...
|
1420
|
+
field_parts = options[:select_fields][0].to_s.split(".")
|
1421
|
+
field_context = field_parts[0]
|
1422
|
+
context_data = json_response[field_context]
|
1423
|
+
if field_parts.size > 1 && context_data.is_a?(Array)
|
1424
|
+
# inject all the root level properties to be selectable too..
|
1425
|
+
context_data = json_response.delete(field_context)
|
1426
|
+
# records = context_data
|
1427
|
+
records = context_data.collect {|it| it.is_a?(Hash) ? json_response.merge(it) : json_response }
|
1428
|
+
options[:select_fields] = options[:select_fields].collect {|it| it.sub(field_context+'.', '')}
|
1411
1429
|
end
|
1430
|
+
output = records.collect { |record|
|
1431
|
+
options[:select_fields].collect { |field|
|
1432
|
+
value = get_object_value(record, field)
|
1433
|
+
value.is_a?(String) ? value : JSON.fast_generate(value)
|
1434
|
+
}.join(options[:delim] || ",")
|
1435
|
+
}.join(options[:newline] || "\n")
|
1412
1436
|
elsif options[:json]
|
1413
1437
|
output = as_json(json_response, options, object_key)
|
1414
1438
|
elsif options[:yaml]
|
1415
1439
|
output = as_yaml(json_response, options, object_key)
|
1416
1440
|
elsif options[:csv]
|
1417
|
-
|
1418
|
-
if row.is_a?(Array)
|
1419
|
-
output = records_as_csv(row, options)
|
1420
|
-
else
|
1421
|
-
output = records_as_csv([row], options)
|
1422
|
-
end
|
1441
|
+
output = as_csv(json_response, nil, options, object_key)
|
1423
1442
|
end
|
1424
1443
|
if options[:outfile]
|
1425
1444
|
full_outfile = File.expand_path(options[:outfile])
|
@@ -996,7 +996,7 @@ EOT
|
|
996
996
|
end
|
997
997
|
|
998
998
|
def apply(args)
|
999
|
-
default_refresh_interval =
|
999
|
+
default_refresh_interval = 10
|
1000
1000
|
params, payload, options = {}, {}, {}
|
1001
1001
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
1002
1002
|
opts.banner = subcommand_usage("[app] [options]")
|
@@ -35,7 +35,10 @@ class Morpheus::Cli::CloudResourcePoolsCommand
|
|
35
35
|
cloud_id = val
|
36
36
|
end
|
37
37
|
opts.add_hidden_option('-c') # prefer args[0] for [cloud]
|
38
|
-
|
38
|
+
opts.on( '-s', '--search PHRASE', "Search by Name and/or Display Name" ) do |phrase|
|
39
|
+
options[:phrase] = phrase
|
40
|
+
end
|
41
|
+
build_common_options(opts, options, [:list, :json, :yaml, :csv, :fields, :dry_run, :remote], ['search'])
|
39
42
|
opts.footer = "List resource pools for a cloud." + "\n" +
|
40
43
|
"[cloud] is required. This is the name or id of the cloud."
|
41
44
|
end
|
@@ -91,6 +94,7 @@ class Morpheus::Cli::CloudResourcePoolsCommand
|
|
91
94
|
type: resource_pool['type'].to_s.capitalize,
|
92
95
|
description: resource_pool['description'],
|
93
96
|
active: format_boolean(resource_pool['active']),
|
97
|
+
inventory: format_boolean(resource_pool['inventory']),
|
94
98
|
status: resource_pool['status'].to_s.upcase,
|
95
99
|
visibility: resource_pool['visibility'].to_s.capitalize,
|
96
100
|
default: format_boolean(resource_pool['defaultPool']),
|
@@ -99,7 +103,7 @@ class Morpheus::Cli::CloudResourcePoolsCommand
|
|
99
103
|
}
|
100
104
|
row
|
101
105
|
}
|
102
|
-
columns = [:id, :name, :description, :active, :default, :visibility, :tenants]
|
106
|
+
columns = [:id, :name, :description, :active,:inventory, :default, :visibility, :tenants]
|
103
107
|
if options[:include_fields]
|
104
108
|
columns = options[:include_fields]
|
105
109
|
end
|
@@ -179,10 +183,12 @@ class Morpheus::Cli::CloudResourcePoolsCommand
|
|
179
183
|
description_cols = {
|
180
184
|
"ID" => 'id',
|
181
185
|
"Name" => 'name',
|
186
|
+
"Display Name" => 'displayName',
|
182
187
|
"Description" => 'description',
|
183
188
|
#"Type" => lambda {|it| it['type'].to_s.capitalize },
|
184
189
|
"Cloud" => lambda {|it| it['zone'] ? it['zone']['name'] : '' },
|
185
190
|
"Active" => lambda {|it| format_boolean(it['active']) },
|
191
|
+
"Inventory" => lambda {|it| format_boolean(it['inventory']) },
|
186
192
|
"Default" => lambda {|it| format_boolean(it['defaultPool']) },
|
187
193
|
"Visibility" => lambda {|it| it['visibility'].to_s.capitalize },
|
188
194
|
"Status" => lambda {|it| it['status'].to_s.capitalize },
|
@@ -329,6 +335,9 @@ class Morpheus::Cli::CloudResourcePoolsCommand
|
|
329
335
|
opts.on('--active [on|off]', String, "Can be used to disable a resource pool") do |val|
|
330
336
|
options['active'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == ''
|
331
337
|
end
|
338
|
+
opts.on('--inventory [on|off]', String, "Enable or disable inventory sync for resource pool during cloud refresh") do |val|
|
339
|
+
options['inventory'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == ''
|
340
|
+
end
|
332
341
|
opts.on('--default-pool [on|off]', String, "Set resource pool as the default") do |val|
|
333
342
|
options['defaultPool'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == ''
|
334
343
|
end
|
@@ -447,6 +456,11 @@ class Morpheus::Cli::CloudResourcePoolsCommand
|
|
447
456
|
else
|
448
457
|
payload['resourcePool']['active'] = true
|
449
458
|
end
|
459
|
+
|
460
|
+
#inventory
|
461
|
+
if options['inventory'] != nil
|
462
|
+
payload['resourcePool']['inventory'] = options['inventory']
|
463
|
+
end
|
450
464
|
|
451
465
|
# Default
|
452
466
|
if options['defaultPool'] != nil
|
@@ -574,12 +588,18 @@ class Morpheus::Cli::CloudResourcePoolsCommand
|
|
574
588
|
opts.on('--active [on|off]', String, "Can be used to disable a resource pool") do |val|
|
575
589
|
options['active'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == ''
|
576
590
|
end
|
591
|
+
opts.on('--inventory [on|off]', String, "Enable or disable inventory sync for resource pool during cloud refresh") do |val|
|
592
|
+
options['inventory'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == ''
|
593
|
+
end
|
577
594
|
opts.on('--default-pool [on|off]', String, "Set resource pool as the default") do |val|
|
578
595
|
options['defaultPool'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == ''
|
579
596
|
end
|
580
597
|
opts.on("--description [TEXT]", String, "Description") do |val|
|
581
598
|
options['description'] = val.to_s
|
582
599
|
end
|
600
|
+
opts.on("--display-name [TEXT]", String, "Display Name") do |val|
|
601
|
+
options['displayName'] = val.to_s
|
602
|
+
end
|
583
603
|
opts.on( '--role ROLE', String, "Role Name or ID (applicable to select resource pools)" ) do |val|
|
584
604
|
options['role'] = val
|
585
605
|
end
|
@@ -599,6 +619,7 @@ class Morpheus::Cli::CloudResourcePoolsCommand
|
|
599
619
|
end
|
600
620
|
|
601
621
|
connect(options)
|
622
|
+
puts "options #{options}"
|
602
623
|
|
603
624
|
begin
|
604
625
|
# load cloud
|
@@ -672,6 +693,11 @@ class Morpheus::Cli::CloudResourcePoolsCommand
|
|
672
693
|
if options['active'] != nil
|
673
694
|
payload['resourcePool']['active'] = options['active']
|
674
695
|
end
|
696
|
+
|
697
|
+
#inventory
|
698
|
+
if options['inventory'] != nil
|
699
|
+
payload['resourcePool']['inventory'] = options['inventory']
|
700
|
+
end
|
675
701
|
|
676
702
|
# Default
|
677
703
|
if options['defaultPool'] != nil
|
@@ -688,6 +714,11 @@ class Morpheus::Cli::CloudResourcePoolsCommand
|
|
688
714
|
payload['resourcePool']['description'] = options['description']
|
689
715
|
end
|
690
716
|
|
717
|
+
# Display Name
|
718
|
+
if options['displayName'] != nil
|
719
|
+
payload['resourcePool']['displayName'] = options['displayName']
|
720
|
+
end
|
721
|
+
|
691
722
|
# Role
|
692
723
|
if options['role'] != nil
|
693
724
|
role_options = load_option_source_data('openstackRoles', {zoneId: cloud['id']})
|
@@ -260,7 +260,6 @@ class Morpheus::Cli::Clouds
|
|
260
260
|
# todo: pass groups as an array instead
|
261
261
|
|
262
262
|
# Cloud Name
|
263
|
-
|
264
263
|
if args[0]
|
265
264
|
cloud_payload[:name] = args[0]
|
266
265
|
options[:options]['name'] = args[0] # to skip prompt
|
@@ -270,7 +269,6 @@ class Morpheus::Cli::Clouds
|
|
270
269
|
end
|
271
270
|
|
272
271
|
# Cloud Type
|
273
|
-
|
274
272
|
cloud_type = nil
|
275
273
|
if params[:zone_type]
|
276
274
|
cloud_type = cloud_type_for_name(params[:zone_type])
|
@@ -459,7 +457,16 @@ class Morpheus::Cli::Clouds
|
|
459
457
|
query_params = {}
|
460
458
|
params = {}
|
461
459
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
462
|
-
opts.banner = subcommand_usage("[
|
460
|
+
opts.banner = subcommand_usage("[cloud] [options]")
|
461
|
+
opts.on( '-m', '--mode [daily|costing]', "Refresh Mode. Use this to run the daily or costing jobs instead of the default hourly refresh." ) do |val|
|
462
|
+
query_params[:mode] = val
|
463
|
+
end
|
464
|
+
opts.on( '--rebuild [on|off]', "Rebuild invoices for period. Only applies to mode=costing." ) do |val|
|
465
|
+
query_params[:rebuild] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
|
466
|
+
end
|
467
|
+
opts.on( '--period PERIOD', "Period in the format YYYYMM to process invoices for. Default is the current period. Only applies to mode=costing." ) do |val|
|
468
|
+
query_params[:period] = val.to_s
|
469
|
+
end
|
463
470
|
opts.on( '-f', '--force', "Force refresh. Useful if the cloud is disabled." ) do
|
464
471
|
query_params[:force] = 'true'
|
465
472
|
end
|
@@ -970,8 +977,7 @@ class Morpheus::Cli::Clouds
|
|
970
977
|
{'fieldName' => 'location', 'fieldLabel' => 'Location', 'type' => 'text', 'required' => false, 'displayOrder' => 3},
|
971
978
|
{'fieldName' => 'visibility', 'fieldLabel' => 'Visibility', 'type' => 'select', 'selectOptions' => [{'name' => 'Private', 'value' => 'private'},{'name' => 'Public', 'value' => 'public'}], 'required' => false, 'description' => 'Visibility', 'category' => 'permissions', 'defaultValue' => 'private', 'displayOrder' => 4},
|
972
979
|
{'fieldName' => 'enabled', 'fieldLabel' => 'Enabled', 'type' => 'checkbox', 'required' => false, 'defaultValue' => true, 'displayOrder' => 5},
|
973
|
-
{'fieldName' => 'autoRecoverPowerState', 'fieldLabel' => 'Automatically Power On VMs', 'type' => 'checkbox', 'required' => false, 'defaultValue' => false, 'displayOrder' => 6}
|
974
|
-
{'fieldName' => 'credential', 'fieldLabel' => 'Credentials', 'type' => 'select', 'optionSource' => 'credentials', 'description' => 'Credential ID or use "local" to specify username and password', 'displayOrder' => 9, 'defaultValue' => "local", 'required' => true, :for_help_only => true}, # hacky way to render this but not prompt for it
|
980
|
+
{'fieldName' => 'autoRecoverPowerState', 'fieldLabel' => 'Automatically Power On VMs', 'type' => 'checkbox', 'required' => false, 'defaultValue' => false, 'displayOrder' => 6}
|
975
981
|
]
|
976
982
|
|
977
983
|
# TODO: Account
|
@@ -1004,7 +1010,7 @@ class Morpheus::Cli::Clouds
|
|
1004
1010
|
end
|
1005
1011
|
|
1006
1012
|
def cloud_types_for_dropdown
|
1007
|
-
|
1013
|
+
@clouds_interface.cloud_types({max:1000, shallow:true})['zoneTypes'].select {|it| it['enabled'] }.collect {|it| {'name' => it['name'], 'value' => it['code']} }
|
1008
1014
|
end
|
1009
1015
|
|
1010
1016
|
def format_cloud_status(cloud, return_color=cyan)
|
@@ -10,6 +10,7 @@ class Morpheus::Cli::Clusters
|
|
10
10
|
register_subcommands :list, :count, :get, :view, :add, :update, :remove, :logs, :history, {:'history-details' => :history_details}, {:'history-event' => :history_event_details}
|
11
11
|
register_subcommands :list_workers, :add_worker, :remove_worker, :update_worker_count
|
12
12
|
register_subcommands :list_masters
|
13
|
+
register_subcommands :upgrade_cluster
|
13
14
|
register_subcommands :list_volumes, :remove_volume
|
14
15
|
register_subcommands :list_namespaces, :get_namespace, :add_namespace, :update_namespace, :remove_namespace
|
15
16
|
register_subcommands :list_containers, :remove_container, :restart_container
|
@@ -69,7 +70,6 @@ class Morpheus::Cli::Clusters
|
|
69
70
|
return
|
70
71
|
end
|
71
72
|
json_response = @clusters_interface.list(params)
|
72
|
-
|
73
73
|
render_result = render_with_format(json_response, options, 'clusters')
|
74
74
|
return 0 if render_result
|
75
75
|
|
@@ -859,7 +859,11 @@ class Morpheus::Cli::Clusters
|
|
859
859
|
print JSON.pretty_generate(json_response)
|
860
860
|
print "\n"
|
861
861
|
elsif !options[:quiet]
|
862
|
-
|
862
|
+
msg = "Cluster #{cluster['name']} is being removed..."
|
863
|
+
if json_response['msg'] != nil && json_response['msg'] != ''
|
864
|
+
msg = json_response['msg']
|
865
|
+
end
|
866
|
+
print_green_success msg
|
863
867
|
#list([])
|
864
868
|
end
|
865
869
|
rescue RestClient::Exception => e
|
@@ -1324,7 +1328,11 @@ class Morpheus::Cli::Clusters
|
|
1324
1328
|
if options[:json]
|
1325
1329
|
puts as_json(json_response)
|
1326
1330
|
elsif json_response['success']
|
1327
|
-
|
1331
|
+
if json_response['msg'] == nil
|
1332
|
+
print_green_success "Added worker to cluster #{cluster['name']}"
|
1333
|
+
else
|
1334
|
+
print_green_success json_response['msg']
|
1335
|
+
end
|
1328
1336
|
#get_args = [json_response["cluster"]["id"]] + (options[:remote] ? ["-r",options[:remote]] : [])
|
1329
1337
|
#get(get_args)
|
1330
1338
|
end
|
@@ -1377,7 +1385,11 @@ class Morpheus::Cli::Clusters
|
|
1377
1385
|
end
|
1378
1386
|
json_response = @clusters_interface.destroy_worker(cluster['id'], worker['id'], params)
|
1379
1387
|
render_response(json_response, options) do
|
1380
|
-
|
1388
|
+
msg = "Worker #{worker['name']} is being removed from cluster #{cluster['name']}..."
|
1389
|
+
if json_response['msg']
|
1390
|
+
msg = json_response['msg']
|
1391
|
+
end
|
1392
|
+
print_green_success msg
|
1381
1393
|
end
|
1382
1394
|
return 0, nil
|
1383
1395
|
end
|
@@ -1518,6 +1530,45 @@ class Morpheus::Cli::Clusters
|
|
1518
1530
|
end
|
1519
1531
|
end
|
1520
1532
|
|
1533
|
+
def upgrade_cluster(args)
|
1534
|
+
params = {}
|
1535
|
+
options = {}
|
1536
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
1537
|
+
opts.banner = subcommand_usage("[cluster]")
|
1538
|
+
build_standard_update_options(opts, options)
|
1539
|
+
opts.footer = "Updates kubernetes version (kubectl and kubeadm) of the specified cluster.\n" +
|
1540
|
+
"[cluster] is required. This is the name or id of an existing cluster.\n"
|
1541
|
+
end
|
1542
|
+
optparse.parse!(args)
|
1543
|
+
verify_args!(args:args, optparse:optparse, count:1)
|
1544
|
+
connect(options)
|
1545
|
+
|
1546
|
+
cluster = find_cluster_by_name_or_id(args[0])
|
1547
|
+
return 1 if cluster.nil?
|
1548
|
+
|
1549
|
+
version_options = get_valid_upgrade_versions(cluster['id'])
|
1550
|
+
version_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'targetVersion', 'type' => 'select', 'fieldLabel' => 'To Version', 'selectOptions' => version_options, 'required' => true, 'description' => 'Select target version.' }],options[:options],api_client,{})
|
1551
|
+
target_version = version_options.detect{ |element| element['value'] == version_prompt['targetVersion'] }['name']
|
1552
|
+
|
1553
|
+
payload = {}
|
1554
|
+
if options[:payload]
|
1555
|
+
payload = options[:payload]
|
1556
|
+
payload.deep_merge!({'targetVersion' => target_version})
|
1557
|
+
else
|
1558
|
+
payload.deep_merge!({'targetVersion' => target_version})
|
1559
|
+
end
|
1560
|
+
@clusters_interface.setopts(options)
|
1561
|
+
if options[:dry_run]
|
1562
|
+
print_dry_run @clusters_interface.dry.do_cluster_upgrade(cluster['id'], payload)
|
1563
|
+
return
|
1564
|
+
end
|
1565
|
+
json_response = @clusters_interface.do_cluster_upgrade(cluster['id'], payload)
|
1566
|
+
render_response(json_response, options) do
|
1567
|
+
print_green_success "Cluster #{cluster['name']} is being upgraded to #{target_version}..."
|
1568
|
+
end
|
1569
|
+
return 0, nil
|
1570
|
+
end
|
1571
|
+
|
1521
1572
|
def list_volumes(args)
|
1522
1573
|
options = {}
|
1523
1574
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
@@ -3573,6 +3624,7 @@ class Morpheus::Cli::Clusters
|
|
3573
3624
|
rows = clusters.collect do |cluster|
|
3574
3625
|
{
|
3575
3626
|
id: cluster['id'],
|
3627
|
+
display_name: cluster['displayName'],
|
3576
3628
|
name: cluster['name'],
|
3577
3629
|
type: (cluster['type']['name'] rescue ''),
|
3578
3630
|
layout: (cluster['layout']['name'] rescue ''),
|
@@ -3582,7 +3634,7 @@ class Morpheus::Cli::Clusters
|
|
3582
3634
|
}
|
3583
3635
|
end
|
3584
3636
|
columns = [
|
3585
|
-
:id, :name, :type, :layout, :workers, :cloud, :status
|
3637
|
+
:id, :name, :display_name, :type, :layout, :workers, :cloud, :status
|
3586
3638
|
]
|
3587
3639
|
print as_pretty_table(rows, columns, opts)
|
3588
3640
|
end
|
@@ -4107,6 +4159,15 @@ class Morpheus::Cli::Clusters
|
|
4107
4159
|
rtn
|
4108
4160
|
end
|
4109
4161
|
|
4162
|
+
def get_valid_upgrade_versions(cluster_id)
|
4163
|
+
result = @clusters_interface.get_upgrade_versions(cluster_id, {})
|
4164
|
+
rtn = []
|
4165
|
+
if result['versions']
|
4166
|
+
rtn = result['versions'].map.with_index {|value, idx| {'name' => value,'value' => idx}}
|
4167
|
+
end
|
4168
|
+
rtn
|
4169
|
+
end
|
4170
|
+
|
4110
4171
|
def update_wiki_page_option_types
|
4111
4172
|
[
|
4112
4173
|
{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => false, 'displayOrder' => 1, 'description' => 'The name of the wiki page for this instance. Default is the instance name.'},
|
@@ -1118,7 +1118,11 @@ class Morpheus::Cli::Hosts
|
|
1118
1118
|
print JSON.pretty_generate(json_response)
|
1119
1119
|
print "\n"
|
1120
1120
|
elsif !options[:quiet]
|
1121
|
-
|
1121
|
+
if json_response['deleteApprovalRequired'] == true
|
1122
|
+
print_green_success "Delete Request created for Host #{server['name']}"
|
1123
|
+
else
|
1124
|
+
print_green_success "Host #{server['name']} is being removed..."
|
1125
|
+
end
|
1122
1126
|
#list([])
|
1123
1127
|
end
|
1124
1128
|
rescue RestClient::Exception => e
|
@@ -4607,7 +4607,7 @@ EOT
|
|
4607
4607
|
end
|
4608
4608
|
|
4609
4609
|
def apply(args)
|
4610
|
-
default_refresh_interval =
|
4610
|
+
default_refresh_interval = 10
|
4611
4611
|
params, payload, options = {}, {}, {}
|
4612
4612
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
4613
4613
|
opts.banner = subcommand_usage("[instance] [options]")
|
@@ -275,7 +275,7 @@ EOT
|
|
275
275
|
opt['fieldContext'] = nil
|
276
276
|
end
|
277
277
|
end
|
278
|
-
config_prompt = Morpheus::Cli::OptionTypes.prompt(config_option_types, options[:options], @api_client, options[:params])
|
278
|
+
config_prompt = Morpheus::Cli::OptionTypes.prompt(config_option_types, options[:options], @api_client, options[:params], false, true)
|
279
279
|
config_prompt.deep_compact!
|
280
280
|
params.deep_merge!(config_prompt)
|
281
281
|
end
|
@@ -627,6 +627,12 @@ Update an invoice.
|
|
627
627
|
opts.on( '--date DATE', String, "Date to collect costing for. By default the cost data is collected for the end of the previous job interval (hour or day)." ) do |val|
|
628
628
|
payload[:date] = val.to_s
|
629
629
|
end
|
630
|
+
opts.on( '--period PERIOD', "Period in the format YYYYMM to process invoices for. Default is the current period. This is an alias for the --date option." ) do |val|
|
631
|
+
payload[:date] = val.to_s
|
632
|
+
end
|
633
|
+
opts.on( '--rebuild', "Rebuild invoices for period. Only applies to mode=costing." ) do |val|
|
634
|
+
query_params[:rebuild] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
|
635
|
+
end
|
630
636
|
build_standard_update_options(opts, options, [:query, :auto_confirm])
|
631
637
|
opts.footer = <<-EOT
|
632
638
|
Refresh invoice costing data for the specified clouds.
|
@@ -674,6 +680,7 @@ EOT
|
|
674
680
|
opts.on('-a', '--all', "Display all details, costs and prices." ) do
|
675
681
|
options[:show_actual_costs] = true
|
676
682
|
options[:show_costs] = true
|
683
|
+
options[:details] = true
|
677
684
|
end
|
678
685
|
# opts.on('--actuals', '--actuals', "Display all actual costs: Compute, Memory, Storage, Network, Extra" ) do
|
679
686
|
# options[:show_actual_costs] = true
|
@@ -861,7 +868,7 @@ EOT
|
|
861
868
|
{"COST" => lambda {|it| format_money(it['itemCost'], it['currency'] || 'USD', {sigdig:options[:sigdig]}) } },
|
862
869
|
{"TAX" => lambda {|it| format_money(it['itemTax'], it['currency'] || 'USD', {sigdig:options[:sigdig]}) } },
|
863
870
|
] : []) + [
|
864
|
-
{"ITEM ID" => lambda {|it| truncate_string_right(it['itemId'], 65) } },
|
871
|
+
{"ITEM ID" => lambda {|it| options[:details] ? it['itemId'] : truncate_string_right(it['itemId'], 65) } },
|
865
872
|
{"ITEM NAME" => lambda {|it| it['itemName'] } },
|
866
873
|
{"ITEM TYPE" => lambda {|it| it['itemType'] } },
|
867
874
|
{"ITEM DESCRIPTION" => lambda {|it| it['itemDescription'] } },
|