morpheus-cli 8.0.6 → 8.0.8
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/clouds_interface.rb +35 -0
- data/lib/morpheus/api/clusters_interface.rb +30 -0
- data/lib/morpheus/api/servers_interface.rb +7 -0
- data/lib/morpheus/cli/commands/clouds.rb +348 -0
- data/lib/morpheus/cli/commands/clusters.rb +361 -1
- data/lib/morpheus/cli/commands/hosts.rb +189 -42
- data/lib/morpheus/cli/commands/instances.rb +76 -21
- data/lib/morpheus/cli/commands/license.rb +7 -1
- data/lib/morpheus/cli/commands/service_plans_command.rb +1 -0
- data/lib/morpheus/cli/commands/snapshots.rb +4 -0
- data/lib/morpheus/cli/version.rb +1 -1
- metadata +2 -2
@@ -3,6 +3,7 @@ require 'morpheus/cli/cli_command'
|
|
3
3
|
class Morpheus::Cli::Hosts
|
4
4
|
include Morpheus::Cli::CliCommand
|
5
5
|
include Morpheus::Cli::AccountsHelper
|
6
|
+
include Morpheus::Cli::ProcessesHelper
|
6
7
|
include Morpheus::Cli::ProvisioningHelper
|
7
8
|
include Morpheus::Cli::LogsHelper
|
8
9
|
set_command_name :hosts
|
@@ -13,7 +14,8 @@ class Morpheus::Cli::Hosts
|
|
13
14
|
{:exec => :execution_request},
|
14
15
|
:wiki, :update_wiki,
|
15
16
|
:maintenance, :leave_maintenance, :placement,
|
16
|
-
:list_devices, :assign_device, :detach_device, :attach_device
|
17
|
+
:list_devices, :assign_device, :detach_device, :attach_device,
|
18
|
+
:snapshot
|
17
19
|
alias_subcommand :details, :get
|
18
20
|
set_default_subcommand :list
|
19
21
|
|
@@ -538,8 +540,9 @@ class Morpheus::Cli::Hosts
|
|
538
540
|
"Nodes" => lambda {|it| it['containers'] ? it['containers'].size : 0 },
|
539
541
|
# "Status" => lambda {|it| format_server_status(it) },
|
540
542
|
# "Power" => lambda {|it| format_server_power_state(it) },
|
541
|
-
"
|
542
|
-
"
|
543
|
+
"Managed" => lambda {|it| it['computeServerType'] ? it['computeServerType']['managed'] : ''},
|
544
|
+
"Instance" => lambda {|it| it['instance'] ? it['instance']['name'] : ''},
|
545
|
+
"Status" => lambda {|it| format_server_status_friendly(it) } # combo
|
543
546
|
}
|
544
547
|
server_columns.delete("Hostname") if server['hostname'].to_s.empty? || server['hostname'] == server['name']
|
545
548
|
server_columns.delete("IP") if server['externalIp'].to_s.empty?
|
@@ -548,6 +551,7 @@ class Morpheus::Cli::Hosts
|
|
548
551
|
server_columns.delete("Cost") if server['hourlyCost'].to_f == 0
|
549
552
|
server_columns.delete("Price") if server['hourlyPrice'].to_f == 0 || server['hourlyPrice'] == server['hourlyCost']
|
550
553
|
server_columns.delete("Labels") if server['labels'].nil? || server['labels'].empty?
|
554
|
+
server_columns.delete("Instance") if server['instance'].nil?
|
551
555
|
|
552
556
|
print_description_list(server_columns, server)
|
553
557
|
|
@@ -1477,33 +1481,56 @@ class Morpheus::Cli::Hosts
|
|
1477
1481
|
def upgrade_agent(args)
|
1478
1482
|
options = {}
|
1479
1483
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
1480
|
-
opts.banner = subcommand_usage("[
|
1481
|
-
|
1484
|
+
opts.banner = subcommand_usage("[host]")
|
1485
|
+
opts.on('--refresh [SECONDS]', String, "Refresh until execution is complete. Default interval is #{default_refresh_interval} seconds.") do |val|
|
1486
|
+
options[:refresh_interval] = val.to_s.empty? ? default_refresh_interval : val.to_f
|
1487
|
+
end
|
1488
|
+
opts.on(nil, '--no-refresh', "Do not refresh" ) do
|
1489
|
+
options[:no_refresh] = true
|
1490
|
+
end
|
1491
|
+
build_standard_update_options(opts, options, [:auto_confirm])
|
1492
|
+
opts.footer = <<-EOT
|
1493
|
+
Upgrade agent for a host.
|
1494
|
+
[host] is required. This is the name or id of a host.
|
1495
|
+
EOT
|
1482
1496
|
end
|
1483
1497
|
optparse.parse!(args)
|
1484
|
-
|
1485
|
-
puts optparse
|
1486
|
-
exit 1
|
1487
|
-
end
|
1498
|
+
verify_args!(args:args, optparse:optparse, count:1)
|
1488
1499
|
connect(options)
|
1489
|
-
|
1490
|
-
|
1491
|
-
|
1492
|
-
|
1493
|
-
|
1494
|
-
|
1495
|
-
|
1496
|
-
|
1497
|
-
|
1498
|
-
|
1499
|
-
|
1500
|
+
|
1501
|
+
host = find_host_by_name_or_id(args[0])
|
1502
|
+
return 1 if host.nil?
|
1503
|
+
|
1504
|
+
payload = {}
|
1505
|
+
if options[:payload]
|
1506
|
+
payload = options[:payload]
|
1507
|
+
payload.deep_merge!({'server' => parse_passed_options(options)})
|
1508
|
+
else
|
1509
|
+
payload.deep_merge!({'server' => parse_passed_options(options)})
|
1510
|
+
end
|
1511
|
+
|
1512
|
+
@servers_interface.setopts(options)
|
1513
|
+
if options[:dry_run]
|
1514
|
+
print_dry_run @servers_interface.dry.upgrade(host['id'], payload)
|
1515
|
+
return
|
1516
|
+
end
|
1517
|
+
json_response = @servers_interface.upgrade(host['id'], payload)
|
1518
|
+
render_response(json_response, options) do
|
1519
|
+
#get([host['id']])
|
1520
|
+
if json_response['success']
|
1521
|
+
if json_response['msg'] == nil
|
1522
|
+
print_green_success "Upgrading agent on host #{host['name']}..."
|
1523
|
+
else
|
1524
|
+
print_green_success json_response['msg']
|
1525
|
+
end
|
1526
|
+
execution_id = json_response['executionId']
|
1527
|
+
if !options[:no_refresh] && execution_id
|
1528
|
+
wait_for_execution_request(json_response['executionId'], options.merge({waiting_status:['new', 'pending', 'executing']}))
|
1529
|
+
end
|
1500
1530
|
else
|
1501
|
-
|
1531
|
+
# never reached because unsuccessful requests raise an exception
|
1532
|
+
print_red_alert "API Request failed: #{json_response['msg']}"
|
1502
1533
|
end
|
1503
|
-
return
|
1504
|
-
rescue RestClient::Exception => e
|
1505
|
-
print_rest_exception(e, options)
|
1506
|
-
exit 1
|
1507
1534
|
end
|
1508
1535
|
end
|
1509
1536
|
|
@@ -2020,13 +2047,18 @@ EOT
|
|
2020
2047
|
def snapshots(args)
|
2021
2048
|
options = {}
|
2022
2049
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
2023
|
-
opts.banner = subcommand_usage("[host]")
|
2050
|
+
opts.banner = subcommand_usage("[host] [snapshot]")
|
2024
2051
|
# no pagination yet
|
2025
2052
|
# build_standard_list_options(opts, options)
|
2026
|
-
|
2053
|
+
build_standard_list_options(opts, options, [:details])
|
2054
|
+
opts.footer = <<-EOT
|
2055
|
+
List snapshots for a host.
|
2056
|
+
[host] is required. This is the name or id of a host.
|
2057
|
+
[snapshot] is optional. This is the name or id of a snapshot.
|
2058
|
+
EOT
|
2027
2059
|
end
|
2028
2060
|
optparse.parse!(args)
|
2029
|
-
verify_args!(args:args, optparse:optparse,
|
2061
|
+
verify_args!(args:args, optparse:optparse, min:1)
|
2030
2062
|
connect(options)
|
2031
2063
|
begin
|
2032
2064
|
server = find_host_by_name_or_id(args[0])
|
@@ -2038,25 +2070,52 @@ EOT
|
|
2038
2070
|
return
|
2039
2071
|
end
|
2040
2072
|
json_response = @servers_interface.snapshots(server['id'], params)
|
2041
|
-
snapshots = json_response['snapshots']
|
2073
|
+
snapshots = json_response['snapshots']
|
2074
|
+
# [snapshots] is done with post api filtering by id or name or externalId
|
2075
|
+
if args[1]
|
2076
|
+
if args[1] =~ /\A\d{1,}\Z/
|
2077
|
+
snapshots = snapshots.select {|it| it['id'].to_s == args[1] }
|
2078
|
+
else
|
2079
|
+
# match beginning of name of externalId
|
2080
|
+
snapshots = snapshots.select {|it| it['name'].to_s.index(args[1]) == 0 || it['externalId'].to_s.index(args[1]) == 0 }
|
2081
|
+
end
|
2082
|
+
json_response['snapshots'] = snapshots # update response for -j filtering too
|
2083
|
+
end
|
2042
2084
|
render_response(json_response, options, 'snapshots') do
|
2043
2085
|
print_h1 "Snapshots: #{server['name']}", [], options
|
2044
2086
|
if snapshots.empty?
|
2045
|
-
|
2087
|
+
if args[1]
|
2088
|
+
print cyan,"No snapshots found for '#{args[1]}'",reset,"\n"
|
2089
|
+
elsif
|
2090
|
+
print cyan,"No snapshots found",reset,"\n"
|
2091
|
+
end
|
2092
|
+
print reset, "\n"
|
2046
2093
|
else
|
2047
|
-
|
2048
|
-
|
2049
|
-
|
2050
|
-
|
2051
|
-
|
2052
|
-
|
2053
|
-
|
2054
|
-
|
2055
|
-
|
2056
|
-
|
2057
|
-
|
2094
|
+
if options[:details]
|
2095
|
+
# this actually makes a request for each one here so don't go crazy...
|
2096
|
+
if snapshots.size > 3
|
2097
|
+
print cyan, "Showing first 3 snapshots. Use the ID to get more details.", reset, "\n"
|
2098
|
+
snapshots = snapshots.first(3)
|
2099
|
+
end
|
2100
|
+
snapshots.each do |snapshot|
|
2101
|
+
Morpheus::Cli::Snapshots.new.handle(["get", snapshot['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
|
2102
|
+
end
|
2103
|
+
else
|
2104
|
+
# Snapshots List
|
2105
|
+
snapshot_column_definitions = {
|
2106
|
+
"ID" => lambda {|it| it['id'] },
|
2107
|
+
"Name" => lambda {|it| it['name'] },
|
2108
|
+
"Description" => lambda {|it| it['description'] },
|
2109
|
+
# "Type" => lambda {|it| it['snapshotType'] },
|
2110
|
+
"Date Created" => lambda {|it| format_local_dt(it['snapshotCreated']) },
|
2111
|
+
"Status" => lambda {|it| format_snapshot_status(it) }
|
2112
|
+
}
|
2113
|
+
print cyan
|
2114
|
+
print as_pretty_table(snapshots, snapshot_column_definitions.upcase_keys!, options)
|
2115
|
+
print_results_pagination({size: snapshots.size, total: snapshots.size})
|
2116
|
+
print reset, "\n"
|
2117
|
+
end
|
2058
2118
|
end
|
2059
|
-
print reset, "\n"
|
2060
2119
|
end
|
2061
2120
|
return 0
|
2062
2121
|
rescue RestClient::Exception => e
|
@@ -2419,6 +2478,94 @@ EOT
|
|
2419
2478
|
return 0, nil
|
2420
2479
|
end
|
2421
2480
|
|
2481
|
+
def snapshot(args)
|
2482
|
+
options = {}
|
2483
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
2484
|
+
opts.banner = subcommand_usage("[host]")
|
2485
|
+
opts.on( '--name VALUE', String, "Snapshot Name. Default is \"{name}.{timestamp}\"" ) do |val|
|
2486
|
+
options[:options]['name'] = val
|
2487
|
+
end
|
2488
|
+
opts.on( '--description VALUE', String, "Snapshot Description." ) do |val|
|
2489
|
+
options[:options]['description'] = val
|
2490
|
+
end
|
2491
|
+
opts.on('--memory-snapshot [on|off]', String, "Memory Snapshot? Whether to include the memory state in the snapshot.") do |val|
|
2492
|
+
options[:options]['memorySnapshot'] = val.to_s == '' || val.to_s == 'on' || val.to_s == 'true'
|
2493
|
+
end
|
2494
|
+
opts.on('--for-export [on|off]', String, "For Export? Indicates the snapshot is intended for export to storage.") do |val|
|
2495
|
+
options[:options]['forExport'] = val.to_s == '' || val.to_s == 'on' || val.to_s == 'true'
|
2496
|
+
end
|
2497
|
+
opts.on('--refresh [SECONDS]', String, "Refresh until execution is complete. Default interval is #{default_refresh_interval} seconds.") do |val|
|
2498
|
+
options[:refresh_interval] = val.to_s.empty? ? default_refresh_interval : val.to_f
|
2499
|
+
end
|
2500
|
+
opts.on(nil, '--no-refresh', "Do not refresh" ) do
|
2501
|
+
options[:no_refresh] = true
|
2502
|
+
end
|
2503
|
+
build_standard_add_options(opts, options, [:auto_confirm])
|
2504
|
+
opts.footer = <<-EOT
|
2505
|
+
Create a snapshot for a host.
|
2506
|
+
[host] is required. This is the name or id of a host
|
2507
|
+
EOT
|
2508
|
+
end
|
2509
|
+
optparse.parse!(args)
|
2510
|
+
verify_args!(args:args, optparse:optparse, count:1)
|
2511
|
+
connect(options)
|
2512
|
+
server = find_host_by_name_or_id(args[0])
|
2513
|
+
payload = {}
|
2514
|
+
if options[:payload]
|
2515
|
+
payload = options[:payload]
|
2516
|
+
payload.deep_merge!({'snapshot' => parse_passed_options(options)})
|
2517
|
+
else
|
2518
|
+
payload.deep_merge!({'snapshot' => parse_passed_options(options)})
|
2519
|
+
# prompt for name and description
|
2520
|
+
name = prompt_value({'fieldName' => 'name', 'type' => 'text', 'fieldLabel' => 'Snapshot Name', 'description' => "Snapshot Name. Default is \"{name}.{timestamp}\""}, options)
|
2521
|
+
payload['snapshot']['name'] = name if !name.to_s.empty?
|
2522
|
+
description = prompt_value({'fieldName' => 'description', 'type' => 'text', 'fieldLabel' => 'Description', 'description' => "Snapshot Description."}, options)
|
2523
|
+
payload['snapshot']['description'] = description if !description.to_s.empty?
|
2524
|
+
# need to GET provision type for some settings...
|
2525
|
+
provision_type = nil
|
2526
|
+
begin
|
2527
|
+
provision_type_id = server['computeServerType']['provisionTypeId'] rescue nil
|
2528
|
+
if provision_type_id
|
2529
|
+
provision_type = @provision_types_interface.get(provision_type_id)['provisionType']
|
2530
|
+
end
|
2531
|
+
rescue => ex
|
2532
|
+
Morpheus::Logging::DarkPrinter.puts "Failed to load provision type!" if Morpheus::Logging.debug?
|
2533
|
+
end
|
2534
|
+
if provision_type && provision_type['hasMemorySnapshots']
|
2535
|
+
# prompt for memorySnapshot
|
2536
|
+
memory_snapshot = prompt_value({'fieldName' => 'memorySnapshot', 'type' => 'checkbox', 'fieldLabel' => 'Memory Snapshot?', 'description' => "Snapshot Description."}, options)
|
2537
|
+
payload['snapshot']['memorySnapshot'] = memory_snapshot if !memory_snapshot.to_s.empty?
|
2538
|
+
end
|
2539
|
+
# convert "on" and "off" to true/false
|
2540
|
+
payload.booleanize!
|
2541
|
+
end
|
2542
|
+
unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like to snapshot the host '#{server['name']}'?", options)
|
2543
|
+
exit 1
|
2544
|
+
end
|
2545
|
+
@servers_interface.setopts(options)
|
2546
|
+
if options[:dry_run]
|
2547
|
+
print_dry_run @servers_interface.dry.snapshot(server['id'], payload)
|
2548
|
+
return
|
2549
|
+
end
|
2550
|
+
json_response = @servers_interface.snapshot(server['id'], payload)
|
2551
|
+
render_response(json_response, options) do
|
2552
|
+
print_green_success "Snapshot initiated."
|
2553
|
+
process_id = json_response['processIds'][0] rescue nil
|
2554
|
+
if process_id
|
2555
|
+
unless options[:no_refresh]
|
2556
|
+
process = wait_for_process_execution(process_id, options)
|
2557
|
+
snapshot_id = process['resultId']
|
2558
|
+
if snapshot_id
|
2559
|
+
Morpheus::Cli::Snapshots.new.handle(["get", snapshot_id] + (options[:remote] ? ["-r",options[:remote]] : []))
|
2560
|
+
end
|
2561
|
+
end
|
2562
|
+
else
|
2563
|
+
# puts "No process returned"
|
2564
|
+
end
|
2565
|
+
end
|
2566
|
+
return 0, nil
|
2567
|
+
end
|
2568
|
+
|
2422
2569
|
## Server Devices
|
2423
2570
|
|
2424
2571
|
def list_devices(args)
|
@@ -2915,12 +2915,18 @@ class Morpheus::Cli::Instances
|
|
2915
2915
|
options = {}
|
2916
2916
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
2917
2917
|
opts.banner = subcommand_usage("[instance]")
|
2918
|
-
opts.on( '--name VALUE', String, "Snapshot Name. Default is
|
2918
|
+
opts.on( '--name VALUE', String, "Snapshot Name. Default is \"{name}.{timestamp}\"" ) do |val|
|
2919
2919
|
options[:options]['name'] = val
|
2920
2920
|
end
|
2921
2921
|
opts.on( '--description VALUE', String, "Snapshot Description." ) do |val|
|
2922
2922
|
options[:options]['description'] = val
|
2923
2923
|
end
|
2924
|
+
opts.on('--memory-snapshot [on|off]', String, "Memory Snapshot? Whether to include the memory state in the snapshot.") do |val|
|
2925
|
+
options[:options]['memorySnapshot'] = val.to_s == '' || val.to_s == 'on' || val.to_s == 'true'
|
2926
|
+
end
|
2927
|
+
opts.on('--for-export [on|off]', String, "For Export? Indicates the snapshot is intended for export to storage.") do |val|
|
2928
|
+
options[:options]['forExport'] = val.to_s == '' || val.to_s == 'on' || val.to_s == 'true'
|
2929
|
+
end
|
2924
2930
|
opts.on('--refresh [SECONDS]', String, "Refresh until execution is complete. Default interval is #{default_refresh_interval} seconds.") do |val|
|
2925
2931
|
options[:refresh_interval] = val.to_s.empty? ? default_refresh_interval : val.to_f
|
2926
2932
|
end
|
@@ -2937,15 +2943,36 @@ EOT
|
|
2937
2943
|
verify_args!(args:args, optparse:optparse, count:1)
|
2938
2944
|
connect(options)
|
2939
2945
|
instance = find_instance_by_name_or_id(args[0])
|
2940
|
-
|
2941
|
-
exit 1
|
2942
|
-
end
|
2946
|
+
|
2943
2947
|
payload = {}
|
2944
2948
|
if options[:payload]
|
2945
2949
|
payload = options[:payload]
|
2946
2950
|
payload.deep_merge!({'snapshot' => parse_passed_options(options)})
|
2947
2951
|
else
|
2948
2952
|
payload.deep_merge!({'snapshot' => parse_passed_options(options)})
|
2953
|
+
snapshot = payload['snapshot']
|
2954
|
+
# prompt for name and description
|
2955
|
+
name = prompt_value({'fieldName' => 'name', 'type' => 'text', 'fieldLabel' => 'Snapshot Name', 'description' => "Snapshot Name. Default is \"{name}.{timestamp}\""}, options)
|
2956
|
+
snapshot['name'] = name if !name.to_s.empty?
|
2957
|
+
description = prompt_value({'fieldName' => 'description', 'type' => 'text', 'fieldLabel' => 'Description', 'description' => "Snapshot Description."}, options)
|
2958
|
+
snapshot['description'] = description if !description.to_s.empty?
|
2959
|
+
# need to GET provision type for some settings...
|
2960
|
+
provision_type = nil
|
2961
|
+
begin
|
2962
|
+
provision_type = @provision_types_interface.get(instance['layout']['provisionTypeId'])['provisionType']
|
2963
|
+
rescue => ex
|
2964
|
+
Morpheus::Logging::DarkPrinter.puts "Failed to load provision type!" if Morpheus::Logging.debug?
|
2965
|
+
end
|
2966
|
+
if provision_type && provision_type['hasMemorySnapshots']
|
2967
|
+
# prompt for memorySnapshot
|
2968
|
+
memory_snapshot = prompt_value({'fieldName' => 'memorySnapshot', 'type' => 'checkbox', 'fieldLabel' => 'Memory Snapshot?', 'description' => "Snapshot Description."}, options)
|
2969
|
+
snapshot['memorySnapshot'] = memory_snapshot if !memory_snapshot.to_s.empty?
|
2970
|
+
end
|
2971
|
+
# convert "on" and "off" to true/false
|
2972
|
+
payload.booleanize!
|
2973
|
+
end
|
2974
|
+
unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like to snapshot the instance '#{instance['name']}'?", options)
|
2975
|
+
exit 1
|
2949
2976
|
end
|
2950
2977
|
@instances_interface.setopts(options)
|
2951
2978
|
if options[:dry_run]
|
@@ -3470,17 +3497,18 @@ EOT
|
|
3470
3497
|
def snapshots(args)
|
3471
3498
|
options = {}
|
3472
3499
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
3473
|
-
opts.banner = subcommand_usage("[instance]")
|
3500
|
+
opts.banner = subcommand_usage("[instance] [snapshot]")
|
3474
3501
|
# no pagination yet
|
3475
3502
|
# build_standard_list_options(opts, options)
|
3476
|
-
|
3503
|
+
build_standard_list_options(opts, options, [:details])
|
3477
3504
|
opts.footer = <<-EOT
|
3478
3505
|
List snapshots for an instance.
|
3479
3506
|
[instance] is required. This is the name or id of an instance
|
3507
|
+
[snapshot] is optional. this is the name or id a snapshot to filter by.
|
3480
3508
|
EOT
|
3481
3509
|
end
|
3482
3510
|
optparse.parse!(args)
|
3483
|
-
verify_args!(args:args, optparse:optparse,
|
3511
|
+
verify_args!(args:args, optparse:optparse, min:1, max: 2)
|
3484
3512
|
connect(options)
|
3485
3513
|
begin
|
3486
3514
|
instance = find_instance_by_name_or_id(args[0])
|
@@ -3491,25 +3519,52 @@ EOT
|
|
3491
3519
|
return
|
3492
3520
|
end
|
3493
3521
|
json_response = @instances_interface.snapshots(instance['id'], params)
|
3494
|
-
snapshots = json_response['snapshots']
|
3522
|
+
snapshots = json_response['snapshots']
|
3523
|
+
# [snapshots] is done with post api filtering by id or name or externalId
|
3524
|
+
if args[1]
|
3525
|
+
if args[1] =~ /\A\d{1,}\Z/
|
3526
|
+
snapshots = snapshots.select {|it| it['id'].to_s == args[1] }
|
3527
|
+
else
|
3528
|
+
# snapshots = snapshots.select {|it| it['name'] == args[1] || it['externalId'] == args[1] }
|
3529
|
+
# match beginning of name of externalId
|
3530
|
+
snapshots = snapshots.select {|it| it['name'].to_s.index(args[1]) == 0 || it['externalId'].to_s.index(args[1]) == 0 }
|
3531
|
+
end
|
3532
|
+
json_response['snapshots'] = snapshots # update response for -j filtering too
|
3533
|
+
end
|
3495
3534
|
render_response(json_response, options, 'snapshots') do
|
3496
3535
|
print_h1 "Snapshots: #{instance['name']} (#{instance['instanceType']['name']})", [], options
|
3497
3536
|
if snapshots.empty?
|
3498
|
-
|
3537
|
+
if args[1]
|
3538
|
+
print cyan,"No snapshots found for '#{args[1]}'",reset,"\n"
|
3539
|
+
elsif
|
3540
|
+
print cyan,"No snapshots found",reset,"\n"
|
3541
|
+
end
|
3542
|
+
print reset, "\n"
|
3499
3543
|
else
|
3500
|
-
|
3501
|
-
|
3502
|
-
|
3503
|
-
|
3504
|
-
|
3505
|
-
|
3506
|
-
|
3507
|
-
|
3508
|
-
|
3509
|
-
|
3510
|
-
|
3544
|
+
if options[:details]
|
3545
|
+
if snapshots.size > 3
|
3546
|
+
print cyan, "Showing first 3 snapshots. Use the ID to get more details.", reset, "\n"
|
3547
|
+
snapshots = snapshots.first(3) # this actually makes a request for each one here so don't go crazy...
|
3548
|
+
end
|
3549
|
+
snapshots.each do |snapshot|
|
3550
|
+
Morpheus::Cli::Snapshots.new.handle(["get", snapshot['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
|
3551
|
+
end
|
3552
|
+
else
|
3553
|
+
# Snapshots List
|
3554
|
+
snapshot_column_definitions = {
|
3555
|
+
"ID" => lambda {|it| it['id'] },
|
3556
|
+
"Name" => lambda {|it| it['name'] },
|
3557
|
+
"Description" => lambda {|it| it['description'] },
|
3558
|
+
# "Type" => lambda {|it| it['snapshotType'] },
|
3559
|
+
"Date Created" => lambda {|it| format_local_dt(it['snapshotCreated']) },
|
3560
|
+
"Status" => lambda {|it| format_snapshot_status(it) }
|
3561
|
+
}
|
3562
|
+
print cyan
|
3563
|
+
print as_pretty_table(snapshots, snapshot_column_definitions.upcase_keys!, options)
|
3564
|
+
print_results_pagination({size: snapshots.size, total: snapshots.size})
|
3565
|
+
print reset, "\n"
|
3566
|
+
end
|
3511
3567
|
end
|
3512
|
-
print reset, "\n"
|
3513
3568
|
end
|
3514
3569
|
return 0
|
3515
3570
|
rescue RestClient::Exception => e
|
@@ -326,6 +326,7 @@ class Morpheus::Cli::License
|
|
326
326
|
'Never'
|
327
327
|
end
|
328
328
|
},
|
329
|
+
"Version" => lambda {|it| it["licenseVersion"] },
|
329
330
|
"Multi-Tenant" => lambda {|it| format_boolean it["multiTenant"] },
|
330
331
|
"White Label" => lambda {|it| format_boolean it["whitelabel"] },
|
331
332
|
"Stats Reporting" => lambda {|it| format_boolean it["reportStatus"] },
|
@@ -361,6 +362,7 @@ class Morpheus::Cli::License
|
|
361
362
|
used_hosts = current_usage['hosts']
|
362
363
|
used_mvm = current_usage['mvm']
|
363
364
|
used_mvm_sockets = current_usage['mvmSockets']
|
365
|
+
used_sockets = current_usage['sockets'].to_f.round(1)
|
364
366
|
used_iac = current_usage['iac']
|
365
367
|
used_xaas = current_usage['xaas']
|
366
368
|
used_executions = current_usage['executions']
|
@@ -373,6 +375,7 @@ class Morpheus::Cli::License
|
|
373
375
|
max_hosts = license['maxHosts']
|
374
376
|
max_mvm = license['maxMvm']
|
375
377
|
max_mvm_sockets = license['maxMvmSockets']
|
378
|
+
max_sockets = license['maxSockets']
|
376
379
|
max_iac = license['maxIac']
|
377
380
|
max_xaas = license['maxXaas']
|
378
381
|
max_executions = license['maxExecutions']
|
@@ -381,6 +384,7 @@ class Morpheus::Cli::License
|
|
381
384
|
label_width = 20
|
382
385
|
chart_opts = {max_bars: 20, unlimited_label: '0%', percent_sigdig: 0}
|
383
386
|
out = ""
|
387
|
+
out << cyan + "Sockets".rjust(label_width, ' ') + ": " + generate_usage_bar(used_sockets, max_sockets, chart_opts) + cyan + used_sockets.to_s.rjust(8, ' ') + " / " + (max_sockets ? max_sockets.to_s : unlimited_label).to_s.ljust(15, ' ') + "\n"
|
384
388
|
out << cyan + "Managed Servers".rjust(label_width, ' ') + ": " + generate_usage_bar(used_managed_servers, max_managed_servers, chart_opts) + cyan + used_managed_servers.to_s.rjust(8, ' ') + " / " + (max_managed_servers ? max_managed_servers.to_s : unlimited_label).to_s.ljust(15, ' ') + "\n"
|
385
389
|
out << cyan + "Discovered Servers".rjust(label_width, ' ') + ": " + generate_usage_bar(used_discovered_servers, max_discovered_servers, chart_opts) + cyan + used_discovered_servers.to_s.rjust(8, ' ') + " / " + (max_discovered_servers ? max_discovered_servers.to_s : unlimited_label).to_s.ljust(15, ' ') + "\n"
|
386
390
|
out << cyan + "Hosts".rjust(label_width, ' ') + ": " + generate_usage_bar(used_hosts, max_hosts, chart_opts) + cyan + used_hosts.to_s.rjust(8, ' ') + " / " + (max_hosts ? max_hosts.to_s : unlimited_label).to_s.ljust(15, ' ') + "\n"
|
@@ -439,6 +443,7 @@ class Morpheus::Cli::License
|
|
439
443
|
'Never'
|
440
444
|
end
|
441
445
|
},
|
446
|
+
"Version" => lambda {|it| it["licenseVersion"] },
|
442
447
|
"Multi-Tenant" => lambda {|it| format_boolean it["multiTenant"] },
|
443
448
|
"White Label" => lambda {|it| format_boolean it["whitelabel"] },
|
444
449
|
"Stats Reporting" => lambda {|it| format_boolean it["reportStatus"] },
|
@@ -451,11 +456,12 @@ class Morpheus::Cli::License
|
|
451
456
|
})
|
452
457
|
else
|
453
458
|
license_columns.merge!({
|
459
|
+
"Sockets" => 'maxSockets',
|
460
|
+
"HPE VM Sockets" => 'maxMvmSockets',
|
454
461
|
"Managed Servers" => 'maxManagedServers',
|
455
462
|
"Discovered Servers" => 'maxDiscoveredServers',
|
456
463
|
"Hosts" => 'maxHosts',
|
457
464
|
"HPE VM Hosts" => 'maxMvm',
|
458
|
-
"HPE VM Sockets" => 'maxMvmSockets',
|
459
465
|
"Iac Deployments" => 'maxIac',
|
460
466
|
"Xaas Instances" => 'maxXaas',
|
461
467
|
"Executions" => 'maxExecutions',
|
@@ -153,6 +153,7 @@ class Morpheus::Cli::ServicePlanCommand
|
|
153
153
|
"Code" => lambda {|it| it['code']},
|
154
154
|
"Display Order" => lambda {|it| it['sortOrder']},
|
155
155
|
"Provision Type" => lambda {|it| it['provisionType'] ? it['provisionType']['name'] : ''},
|
156
|
+
"Server Type" => lambda {|it| it['serverType']},
|
156
157
|
"Storage" => lambda {|it| printable_byte_size(it, it['maxStorage'], 'storageSizeType', 'GB')}
|
157
158
|
}
|
158
159
|
|
@@ -77,11 +77,15 @@ class Morpheus::Cli::Snapshots
|
|
77
77
|
"Snapshot Type" => 'snapshotType',
|
78
78
|
"Cloud" => lambda {|it| format_name_and_id(it['zone']) },
|
79
79
|
"Datastore" => lambda {|it| format_name_and_id(it['datastore']) },
|
80
|
+
"Memory Snapshot" => lambda {|it| format_boolean(it['memorySnapshot']) },
|
81
|
+
"For Export" => lambda {|it| format_boolean(it['forExport']) },
|
80
82
|
"Parent Snapshot" => lambda {|it| format_name_and_id(it['parentSnapshot']) },
|
81
83
|
"Active" => lambda {|it| format_boolean(it['currentlyActive']) },
|
82
84
|
"Date Created" => lambda {|it| format_local_dt(it['dateCreated']) },
|
83
85
|
"Status" => lambda {|it| format_snapshot_status(it) }
|
84
86
|
}
|
87
|
+
description_cols.delete("Memory Snapshot") if !snapshot['memorySnapshot']
|
88
|
+
description_cols.delete("For Export") if !snapshot['forExport']
|
85
89
|
print_description_list(description_cols, snapshot)
|
86
90
|
|
87
91
|
print reset, "\n"
|
data/lib/morpheus/cli/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: morpheus-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 8.0.
|
4
|
+
version: 8.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Estes
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2025-
|
14
|
+
date: 2025-07-23 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: public_suffix
|