morpheus-cli 5.5.0 → 5.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/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'] } },
|