morpheus-cli 5.0.0 → 5.0.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 +12 -0
- data/lib/morpheus/api/billing_interface.rb +1 -0
- data/lib/morpheus/api/deploy_interface.rb +1 -1
- data/lib/morpheus/api/deployments_interface.rb +20 -1
- data/lib/morpheus/api/forgot_password_interface.rb +17 -0
- data/lib/morpheus/api/instances_interface.rb +7 -0
- data/lib/morpheus/api/search_interface.rb +13 -0
- data/lib/morpheus/api/servers_interface.rb +7 -0
- data/lib/morpheus/api/usage_interface.rb +18 -0
- data/lib/morpheus/cli.rb +4 -1
- data/lib/morpheus/cli/cli_command.rb +26 -9
- data/lib/morpheus/cli/commands/standard/curl_command.rb +3 -5
- data/lib/morpheus/cli/commands/standard/history_command.rb +3 -1
- data/lib/morpheus/cli/commands/standard/man_command.rb +74 -40
- data/lib/morpheus/cli/deploy.rb +199 -90
- data/lib/morpheus/cli/deployments.rb +341 -28
- data/lib/morpheus/cli/deploys.rb +206 -41
- data/lib/morpheus/cli/error_handler.rb +7 -0
- data/lib/morpheus/cli/forgot_password.rb +133 -0
- data/lib/morpheus/cli/health_command.rb +2 -2
- data/lib/morpheus/cli/hosts.rb +169 -32
- data/lib/morpheus/cli/instances.rb +83 -32
- data/lib/morpheus/cli/invoices_command.rb +33 -16
- data/lib/morpheus/cli/logs_command.rb +9 -6
- data/lib/morpheus/cli/mixins/deployments_helper.rb +31 -2
- data/lib/morpheus/cli/mixins/print_helper.rb +0 -21
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +24 -4
- data/lib/morpheus/cli/option_types.rb +266 -17
- data/lib/morpheus/cli/remote.rb +35 -10
- data/lib/morpheus/cli/reports_command.rb +99 -30
- data/lib/morpheus/cli/search_command.rb +182 -0
- data/lib/morpheus/cli/setup.rb +1 -1
- data/lib/morpheus/cli/shell.rb +33 -11
- data/lib/morpheus/cli/tasks.rb +20 -21
- data/lib/morpheus/cli/usage_command.rb +64 -11
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/virtual_images.rb +280 -199
- data/lib/morpheus/cli/whoami.rb +6 -6
- data/lib/morpheus/cli/workflows.rb +33 -40
- data/lib/morpheus/formatters.rb +22 -0
- data/lib/morpheus/terminal.rb +6 -2
- metadata +7 -2
@@ -475,8 +475,8 @@ class Morpheus::Cli::HealthCommand
|
|
475
475
|
opts.footer = "List health logs. These are the logs of the morpheus appliance itself."
|
476
476
|
end
|
477
477
|
optparse.parse!(args)
|
478
|
-
if args.count
|
479
|
-
|
478
|
+
if args.count > 0
|
479
|
+
options[:phrase] = args.join(" ")
|
480
480
|
end
|
481
481
|
connect(options)
|
482
482
|
begin
|
data/lib/morpheus/cli/hosts.rb
CHANGED
@@ -16,10 +16,11 @@ class Morpheus::Cli::Hosts
|
|
16
16
|
include Morpheus::Cli::LogsHelper
|
17
17
|
set_command_name :hosts
|
18
18
|
set_command_description "View and manage hosts (servers)."
|
19
|
-
register_subcommands :list, :count, :get, :view, :stats, :add, :update, :remove, :logs, :start, :stop, :resize,
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
register_subcommands :list, :count, :get, :view, :stats, :add, :update, :remove, :logs, :start, :stop, :resize,
|
20
|
+
:run_workflow, :make_managed, :upgrade_agent, :snapshots,
|
21
|
+
{:'types' => :list_types},
|
22
|
+
{:exec => :execution_request},
|
23
|
+
:wiki, :update_wiki
|
23
24
|
alias_subcommand :details, :get
|
24
25
|
set_default_subcommand :list
|
25
26
|
|
@@ -53,9 +54,13 @@ class Morpheus::Cli::Hosts
|
|
53
54
|
params = {}
|
54
55
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
55
56
|
opts.banner = subcommand_usage()
|
56
|
-
opts.on(
|
57
|
-
options[:
|
57
|
+
opts.on('-a', '--all', "Display all details: memory and storage usage used / max values." ) do
|
58
|
+
options[:details] = true
|
59
|
+
end
|
60
|
+
opts.on('--details', "Display all details: alias for --all" ) do
|
61
|
+
options[:details] = true
|
58
62
|
end
|
63
|
+
opts.add_hidden_option('--details')
|
59
64
|
opts.on( '-g', '--group GROUP', "Group Name or ID" ) do |val|
|
60
65
|
options[:group] = val
|
61
66
|
end
|
@@ -105,16 +110,27 @@ class Morpheus::Cli::Hosts
|
|
105
110
|
opts.on( '--created-by USER', "Created By User Username or ID" ) do |val|
|
106
111
|
options[:created_by] = val
|
107
112
|
end
|
113
|
+
opts.on( '--tenant TENANT', "Tenant Name or ID" ) do |val|
|
114
|
+
options[:account] = val
|
115
|
+
end
|
108
116
|
opts.on('--details', "Display more details: memory and storage usage used / max values." ) do
|
109
117
|
options[:details] = true
|
110
118
|
end
|
119
|
+
opts.on('--tags Name=Value',String, "Filter by tags.") do |val|
|
120
|
+
val.split(",").each do |value_pair|
|
121
|
+
k,v = value_pair.strip.split("=")
|
122
|
+
options[:tags] ||= {}
|
123
|
+
options[:tags][k] ||= []
|
124
|
+
options[:tags][k] << (v || '')
|
125
|
+
end
|
126
|
+
end
|
111
127
|
opts.on('--tag-compliant', "Displays only servers that are valid according to applied tag policies. Does not show servers that do not have tag policies." ) do
|
112
128
|
params[:tagCompliant] = true
|
113
129
|
end
|
114
130
|
opts.on('--non-tag-compliant', "Displays only servers with tag compliance warnings." ) do
|
115
131
|
params[:tagCompliant] = false
|
116
132
|
end
|
117
|
-
|
133
|
+
build_standard_list_options(opts, options)
|
118
134
|
opts.footer = "List hosts."
|
119
135
|
end
|
120
136
|
optparse.parse!(args)
|
@@ -163,6 +179,11 @@ class Morpheus::Cli::Hosts
|
|
163
179
|
params['clusterId'] = cluster['id']
|
164
180
|
end
|
165
181
|
end
|
182
|
+
if options[:tags] && !options[:tags].empty?
|
183
|
+
options[:tags].each do |k,v|
|
184
|
+
params['tags.' + k] = v
|
185
|
+
end
|
186
|
+
end
|
166
187
|
|
167
188
|
@servers_interface.setopts(options)
|
168
189
|
if options[:dry_run]
|
@@ -194,6 +215,9 @@ class Morpheus::Cli::Hosts
|
|
194
215
|
multi_tenant = json_response['multiTenant'] == true
|
195
216
|
title = "Morpheus Hosts"
|
196
217
|
subtitles = []
|
218
|
+
if account
|
219
|
+
subtitles << "Tenant: #{account['name']}".strip
|
220
|
+
end
|
197
221
|
if group
|
198
222
|
subtitles << "Group: #{group['name']}".strip
|
199
223
|
end
|
@@ -244,31 +268,66 @@ class Morpheus::Cli::Hosts
|
|
244
268
|
end
|
245
269
|
row = {
|
246
270
|
id: server['id'],
|
247
|
-
tenant: server['account'] ? server['account']['name'] : server['accountId'],
|
248
271
|
name: server['name'],
|
272
|
+
hostname: server['hostname'],
|
249
273
|
platform: server['serverOs'] ? server['serverOs']['name'].upcase : 'N/A',
|
250
|
-
cloud: server['zone'] ? server['zone']['name'] : '',
|
251
274
|
type: server['computeServerType'] ? server['computeServerType']['name'] : 'unmanaged',
|
275
|
+
tenant: server['account'] ? server['account']['name'] : server['accountId'],
|
276
|
+
owner: server['owner'] ? server['owner']['username'] : server['owner'],
|
277
|
+
cloud: server['zone'] ? server['zone']['name'] : '',
|
278
|
+
ip: server['externalIp'],
|
279
|
+
internal_ip: server['internalIp'],
|
252
280
|
nodes: server['containers'] ? server['containers'].size : '',
|
253
|
-
status: format_server_status(server, cyan),
|
281
|
+
# status: format_server_status(server, cyan),
|
282
|
+
status: (options[:details]||options[:all_fields]) ? format_server_status(server, cyan) : format_server_status_friendly(server, cyan),
|
254
283
|
power: format_server_power_state(server, cyan),
|
255
284
|
cpu: cpu_usage_str + cyan,
|
256
285
|
memory: memory_usage_str + cyan,
|
257
|
-
storage: storage_usage_str + cyan
|
286
|
+
storage: storage_usage_str + cyan,
|
287
|
+
created: format_local_dt(server['dateCreated']),
|
288
|
+
updated: format_local_dt(server['lastUpdated']),
|
258
289
|
}
|
259
290
|
row
|
260
291
|
}
|
261
|
-
columns = [:id, :name, :type, :cloud, :nodes, :status, :power]
|
262
|
-
|
263
|
-
|
292
|
+
# columns = [:id, :name, :type, :cloud, :ip, :internal_ip, :nodes, :status, :power]
|
293
|
+
columns = {
|
294
|
+
"ID" => :id,
|
295
|
+
"Name" => :name,
|
296
|
+
"Hostname" => :hostname,
|
297
|
+
"Type" => :type,
|
298
|
+
"Owner" => :owner,
|
299
|
+
"Tenant" => :tenant,
|
300
|
+
"Cloud" => :cloud,
|
301
|
+
"IP" => :ip,
|
302
|
+
"Private IP" => :internal_ip,
|
303
|
+
"Nodes" => :nodes,
|
304
|
+
"Status" => :status,
|
305
|
+
"Power" => :power,
|
306
|
+
"CPU" => :cpu,
|
307
|
+
"Memory" => :memory,
|
308
|
+
"Storage" => :storage,
|
309
|
+
"Created" => :created,
|
310
|
+
"Updated" => :updated,
|
311
|
+
}
|
312
|
+
if options[:details] != true
|
313
|
+
columns.delete("Hostname")
|
314
|
+
columns.delete("Private IP")
|
315
|
+
columns.delete("Owner")
|
316
|
+
columns.delete("Tenant")
|
317
|
+
columns.delete("Power")
|
318
|
+
columns.delete("Created")
|
319
|
+
columns.delete("Updated")
|
264
320
|
end
|
265
|
-
|
266
|
-
|
267
|
-
if options[:include_fields]
|
268
|
-
columns = options[:include_fields]
|
321
|
+
if !multi_tenant
|
322
|
+
columns.delete("Tenant")
|
269
323
|
end
|
324
|
+
# columns += [:cpu, :memory, :storage]
|
325
|
+
# # custom pretty table columns ...
|
326
|
+
# if options[:include_fields]
|
327
|
+
# columns = options[:include_fields]
|
328
|
+
# end
|
270
329
|
print cyan
|
271
|
-
print as_pretty_table(rows, columns
|
330
|
+
print as_pretty_table(rows, columns.upcase_keys!, options)
|
272
331
|
print reset
|
273
332
|
print_results_pagination(json_response)
|
274
333
|
end
|
@@ -463,27 +522,31 @@ class Morpheus::Cli::Hosts
|
|
463
522
|
server_columns = {
|
464
523
|
"ID" => 'id',
|
465
524
|
"Name" => 'name',
|
525
|
+
"Hostname" => 'hostname',
|
466
526
|
"Description" => 'description',
|
467
|
-
"
|
527
|
+
"Owner" => lambda {|it| it['owner'] ? it['owner']['username'] : '' },
|
528
|
+
"Tenant" => lambda {|it| it['account'] ? it['account']['name'] : '' },
|
468
529
|
#"Group" => lambda {|it| it['group'] ? it['group']['name'] : '' },
|
469
530
|
"Cloud" => lambda {|it| it['zone'] ? it['zone']['name'] : '' },
|
531
|
+
"IP" => lambda {|it| it['externalIp'] },
|
532
|
+
"Private IP" => lambda {|it| it['internalIp'] },
|
470
533
|
"Type" => lambda {|it| it['computeServerType'] ? it['computeServerType']['name'] : 'unmanaged' },
|
471
534
|
"Platform" => lambda {|it| it['serverOs'] ? it['serverOs']['name'].upcase : 'N/A' },
|
472
535
|
"Plan" => lambda {|it| it['plan'] ? it['plan']['name'] : '' },
|
473
536
|
"Cost" => lambda {|it| it['hourlyCost'] ? format_money(it['hourlyCost'], (it['currency'] || 'USD'), {sigdig:15}).to_s + ' per hour' : '' },
|
474
537
|
"Price" => lambda {|it| it['hourlyPrice'] ? format_money(it['hourlyPrice'], (it['currency'] || 'USD'), {sigdig:15}).to_s + ' per hour' : '' },
|
475
538
|
"Agent" => lambda {|it| it['agentInstalled'] ? "#{server['agentVersion'] || ''} updated at #{format_local_dt(server['lastAgentUpdate'])}" : '(not installed)' },
|
476
|
-
"Status" => lambda {|it| format_server_status(it) },
|
477
539
|
"Nodes" => lambda {|it| it['containers'] ? it['containers'].size : 0 },
|
478
|
-
"
|
540
|
+
# "Status" => lambda {|it| format_server_status(it) },
|
541
|
+
# "Power" => lambda {|it| format_server_power_state(it) },
|
542
|
+
"Status" => lambda {|it| format_server_status_friendly(it) }, # combo
|
479
543
|
}
|
480
|
-
|
481
|
-
if server['
|
482
|
-
|
483
|
-
|
484
|
-
if server['
|
485
|
-
|
486
|
-
end
|
544
|
+
server_columns.delete("Hostname") if server['hostname'].to_s.empty? || server['hostname'] == server['name']
|
545
|
+
server_columns.delete("IP") if server['externalIp'].to_s.empty?
|
546
|
+
server_columns.delete("Private IP") if server['internalIp'].to_s.empty?
|
547
|
+
# server_columns.delete("Tenant") if multi_tenant != true
|
548
|
+
server_columns.delete("Cost") if server['hourlyCost'].to_f == 0
|
549
|
+
server_columns.delete("Price") if server['hourlyPrice'].to_f == 0 || server['hourlyPrice'] == server['hourlyCost']
|
487
550
|
|
488
551
|
print_description_list(server_columns, server)
|
489
552
|
|
@@ -1809,6 +1872,53 @@ class Morpheus::Cli::Hosts
|
|
1809
1872
|
end
|
1810
1873
|
end
|
1811
1874
|
|
1875
|
+
def snapshots(args)
|
1876
|
+
options = {}
|
1877
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
1878
|
+
opts.banner = subcommand_usage("[host]")
|
1879
|
+
# no pagination yet
|
1880
|
+
# build_standard_list_options(opts, options)
|
1881
|
+
build_standard_get_options(opts, options)
|
1882
|
+
end
|
1883
|
+
optparse.parse!(args)
|
1884
|
+
verify_args!(args:args, optparse:optparse, count:1)
|
1885
|
+
connect(options)
|
1886
|
+
begin
|
1887
|
+
server = find_host_by_name_or_id(args[0])
|
1888
|
+
return 1 if server.nil?
|
1889
|
+
params = {}
|
1890
|
+
@servers_interface.setopts(options)
|
1891
|
+
if options[:dry_run]
|
1892
|
+
print_dry_run @servers_interface.dry.snapshots(server['id'], params)
|
1893
|
+
return
|
1894
|
+
end
|
1895
|
+
json_response = @servers_interface.snapshots(server['id'], params)
|
1896
|
+
snapshots = json_response['snapshots']
|
1897
|
+
render_response(json_response, options, 'snapshots') do
|
1898
|
+
print_h1 "Snapshots: #{server['name']}", [], options
|
1899
|
+
if snapshots.empty?
|
1900
|
+
print cyan,"No snapshots found",reset,"\n"
|
1901
|
+
else
|
1902
|
+
snapshot_column_definitions = {
|
1903
|
+
"ID" => lambda {|it| it['id'] },
|
1904
|
+
"Name" => lambda {|it| it['name'] },
|
1905
|
+
"Description" => lambda {|it| it['snapshotType'] ? (it['snapshotType']['name'] || it['snapshotType']['code']) : '' },
|
1906
|
+
"Date Created" => lambda {|it| format_local_dt(it['snapshotCreated']) },
|
1907
|
+
"Status" => lambda {|it| format_snapshot_status(it) }
|
1908
|
+
}
|
1909
|
+
print cyan
|
1910
|
+
print as_pretty_table(snapshots, snapshot_column_definitions.upcase_keys!, options)
|
1911
|
+
print_results_pagination({size: snapshots.size, total: snapshots.size})
|
1912
|
+
end
|
1913
|
+
print reset, "\n"
|
1914
|
+
end
|
1915
|
+
return 0
|
1916
|
+
rescue RestClient::Exception => e
|
1917
|
+
print_rest_exception(e, options)
|
1918
|
+
exit 1
|
1919
|
+
end
|
1920
|
+
end
|
1921
|
+
|
1812
1922
|
private
|
1813
1923
|
|
1814
1924
|
def find_host_by_id(id)
|
@@ -1925,11 +2035,38 @@ class Morpheus::Cli::Hosts
|
|
1925
2035
|
|
1926
2036
|
def format_server_status(server, return_color=cyan)
|
1927
2037
|
out = ""
|
1928
|
-
status_string = server['status']
|
1929
|
-
|
1930
|
-
|
2038
|
+
status_string = server['status'].to_s.downcase
|
2039
|
+
if status_string == 'provisioned'
|
2040
|
+
out = "#{cyan}#{status_string.upcase}#{return_color}"
|
2041
|
+
elsif status_string == 'provisioning'
|
2042
|
+
out = "#{cyan}#{status_string.upcase}#{cyan}"
|
2043
|
+
elsif status_string == 'failed' or status_string == 'error'
|
2044
|
+
out = "#{red}#{status_string.upcase}#{return_color}"
|
2045
|
+
else
|
2046
|
+
out = "#{yellow}#{status_string.upcase}#{return_color}"
|
2047
|
+
end
|
2048
|
+
out
|
2049
|
+
end
|
2050
|
+
|
2051
|
+
def format_server_status_friendly(server, return_color=cyan)
|
2052
|
+
out = ""
|
2053
|
+
status_string = server['status'].to_s.downcase
|
2054
|
+
if status_string == 'provisioned'
|
2055
|
+
# out = format_server_power_state(server, return_color)
|
2056
|
+
# make it looks like format_instance_status
|
2057
|
+
if server['powerState'] == 'on'
|
2058
|
+
out << "#{green}RUNNING#{return_color}"
|
2059
|
+
elsif server['powerState'] == 'off'
|
2060
|
+
out << "#{red}STOPPED#{return_color}"
|
2061
|
+
else
|
2062
|
+
out << "#{white}#{server['powerState'].to_s.upcase}#{return_color}"
|
2063
|
+
end
|
2064
|
+
else
|
2065
|
+
out = format_server_status(server, return_color)
|
2066
|
+
end
|
1931
2067
|
out
|
1932
2068
|
end
|
2069
|
+
|
1933
2070
|
|
1934
2071
|
def make_managed_option_types(connected=true)
|
1935
2072
|
[
|
@@ -19,7 +19,7 @@ class Morpheus::Cli::Instances
|
|
19
19
|
:history, {:'history-details' => :history_details}, {:'history-event' => :history_event_details},
|
20
20
|
:stats, :stop, :start, :restart, :actions, :action, :suspend, :eject, :stop_service, :start_service, :restart_service,
|
21
21
|
:backup, :backups, :resize, :clone, :envs, :setenv, :delenv,
|
22
|
-
:security_groups, :apply_security_groups, :run_workflow, :import_snapshot,
|
22
|
+
:security_groups, :apply_security_groups, :run_workflow, :import_snapshot, :snapshots,
|
23
23
|
:console, :status_check, {:containers => :list_containers},
|
24
24
|
:scaling, {:'scaling-update' => :scaling_update},
|
25
25
|
:wiki, :update_wiki,
|
@@ -92,6 +92,20 @@ class Morpheus::Cli::Instances
|
|
92
92
|
opts.on('--pending-removal-only', "Only instances pending removal.") do
|
93
93
|
options[:deleted] = true
|
94
94
|
end
|
95
|
+
opts.on('--labels label',String, "Filter by labels (keywords).") do |val|
|
96
|
+
val.split(",").each do |k|
|
97
|
+
options[:labels] ||= []
|
98
|
+
options[:labels] << k.strip
|
99
|
+
end
|
100
|
+
end
|
101
|
+
opts.on('--tags Name=Value',String, "Filter by tags (metadata name value pairs).") do |val|
|
102
|
+
val.split(",").each do |value_pair|
|
103
|
+
k,v = value_pair.strip.split("=")
|
104
|
+
options[:tags] ||= {}
|
105
|
+
options[:tags][k] ||= []
|
106
|
+
options[:tags][k] << (v || '')
|
107
|
+
end
|
108
|
+
end
|
95
109
|
build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run, :remote])
|
96
110
|
opts.footer = "List instances."
|
97
111
|
end
|
@@ -132,7 +146,13 @@ class Morpheus::Cli::Instances
|
|
132
146
|
|
133
147
|
params['showDeleted'] = true if options[:showDeleted]
|
134
148
|
params['deleted'] = true if options[:deleted]
|
135
|
-
|
149
|
+
params['labels'] = options[:labels] if options[:labels]
|
150
|
+
if options[:tags]
|
151
|
+
options[:tags].each do |k,v|
|
152
|
+
params['tags.' + k] = v
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
136
156
|
@instances_interface.setopts(options)
|
137
157
|
if options[:dry_run]
|
138
158
|
print_dry_run @instances_interface.dry.list(params)
|
@@ -347,18 +367,16 @@ class Morpheus::Cli::Instances
|
|
347
367
|
opts.on("--environment ENV", String, "Environment code") do |val|
|
348
368
|
options[:environment] = val.to_s
|
349
369
|
end
|
350
|
-
opts.on('--
|
370
|
+
opts.on('--tags LIST', String, "Metadata tags in the format 'ping=pong,flash=bang'") do |val|
|
351
371
|
options[:metadata] = val
|
352
372
|
end
|
353
|
-
opts.on('--
|
354
|
-
|
355
|
-
options[:tags] = val.split(',').collect {|it| it.to_s.strip }.compact.uniq.join(',')
|
373
|
+
opts.on('--metadata LIST', String, "Metadata tags in the format 'ping=pong,flash=bang'") do |val|
|
374
|
+
options[:metadata] = val
|
356
375
|
end
|
357
|
-
opts.
|
358
|
-
|
359
|
-
options[:
|
376
|
+
opts.add_hidden_option('--metadata')
|
377
|
+
opts.on('--labels LIST', String, "Labels (keywords) in the format 'foo, bar'") do |val|
|
378
|
+
options[:labels] = val.split(',').collect {|it| it.to_s.strip }.compact.uniq.join(',')
|
360
379
|
end
|
361
|
-
opts.add_hidden_option('--tags')
|
362
380
|
opts.on("--copies NUMBER", Integer, "Number of copies to provision") do |val|
|
363
381
|
options[:copies] = val.to_i
|
364
382
|
end
|
@@ -528,18 +546,17 @@ class Morpheus::Cli::Instances
|
|
528
546
|
opts.on('--group GROUP', String, "Group Name or ID") do |val|
|
529
547
|
options[:group] = val
|
530
548
|
end
|
531
|
-
opts.on('--
|
549
|
+
opts.on('--tags LIST', String, "Metadata tags in the format 'ping=pong,flash=bang'") do |val|
|
532
550
|
options[:metadata] = val
|
533
551
|
end
|
534
|
-
opts.on('--
|
535
|
-
|
536
|
-
params['tags'] = val.split(',').collect {|it| it.to_s.strip }.compact.uniq.join(',')
|
552
|
+
opts.on('--metadata LIST', String, "Metadata tags in the format 'ping=pong,flash=bang'") do |val|
|
553
|
+
options[:metadata] = val
|
537
554
|
end
|
538
|
-
opts.
|
539
|
-
|
555
|
+
opts.add_hidden_option('--metadata')
|
556
|
+
opts.on('--labels LIST', String, "Labels (keywords) in the format 'foo, bar'") do |val|
|
557
|
+
# todo switch this from 'tags' to 'labels'
|
540
558
|
params['tags'] = val.split(',').collect {|it| it.to_s.strip }.compact.uniq.join(',')
|
541
559
|
end
|
542
|
-
opts.add_hidden_option('--tags')
|
543
560
|
opts.on('--power-schedule-type ID', String, "Power Schedule Type ID") do |val|
|
544
561
|
params['powerScheduleType'] = val == "null" ? nil : val
|
545
562
|
end
|
@@ -610,6 +627,9 @@ class Morpheus::Cli::Instances
|
|
610
627
|
metadata_list = options[:metadata].split(",").select {|it| !it.to_s.empty? }
|
611
628
|
metadata_list = metadata_list.collect do |it|
|
612
629
|
metadata_pair = it.split(":")
|
630
|
+
if metadata_pair.size == 1 && it.include?("=")
|
631
|
+
metadata_pair = it.split("=")
|
632
|
+
end
|
613
633
|
row = {}
|
614
634
|
row['name'] = metadata_pair[0].to_s.strip
|
615
635
|
row['value'] = metadata_pair[1].to_s.strip
|
@@ -2898,6 +2918,52 @@ class Morpheus::Cli::Instances
|
|
2898
2918
|
end
|
2899
2919
|
end
|
2900
2920
|
|
2921
|
+
def snapshots(args)
|
2922
|
+
options = {}
|
2923
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
2924
|
+
opts.banner = subcommand_usage("[instance]")
|
2925
|
+
# no pagination yet
|
2926
|
+
# build_standard_list_options(opts, options)
|
2927
|
+
build_standard_get_options(opts, options)
|
2928
|
+
end
|
2929
|
+
optparse.parse!(args)
|
2930
|
+
verify_args!(args:args, optparse:optparse, count:1)
|
2931
|
+
connect(options)
|
2932
|
+
begin
|
2933
|
+
instance = find_instance_by_name_or_id(args[0])
|
2934
|
+
params = {}
|
2935
|
+
@instances_interface.setopts(options)
|
2936
|
+
if options[:dry_run]
|
2937
|
+
print_dry_run @instances_interface.dry.snapshots(instance['id'], params)
|
2938
|
+
return
|
2939
|
+
end
|
2940
|
+
json_response = @instances_interface.snapshots(instance['id'], params)
|
2941
|
+
snapshots = json_response['snapshots']
|
2942
|
+
render_response(json_response, options, 'snapshots') do
|
2943
|
+
print_h1 "Snapshots: #{instance['name']} (#{instance['instanceType']['name']})", [], options
|
2944
|
+
if snapshots.empty?
|
2945
|
+
print cyan,"No snapshots found",reset,"\n"
|
2946
|
+
else
|
2947
|
+
snapshot_column_definitions = {
|
2948
|
+
"ID" => lambda {|it| it['id'] },
|
2949
|
+
"Name" => lambda {|it| it['name'] },
|
2950
|
+
"Description" => lambda {|it| it['snapshotType'] ? (it['snapshotType']['name'] || it['snapshotType']['code']) : '' },
|
2951
|
+
"Date Created" => lambda {|it| format_local_dt(it['snapshotCreated']) },
|
2952
|
+
"Status" => lambda {|it| format_snapshot_status(it) }
|
2953
|
+
}
|
2954
|
+
print cyan
|
2955
|
+
print as_pretty_table(snapshots, snapshot_column_definitions.upcase_keys!, options)
|
2956
|
+
print_results_pagination({size: snapshots.size, total: snapshots.size})
|
2957
|
+
end
|
2958
|
+
print reset, "\n"
|
2959
|
+
end
|
2960
|
+
return 0
|
2961
|
+
rescue RestClient::Exception => e
|
2962
|
+
print_rest_exception(e, options)
|
2963
|
+
exit 1
|
2964
|
+
end
|
2965
|
+
end
|
2966
|
+
|
2901
2967
|
def import_snapshot(args)
|
2902
2968
|
options = {}
|
2903
2969
|
query_params = {}
|
@@ -4024,19 +4090,4 @@ private
|
|
4024
4090
|
}
|
4025
4091
|
end
|
4026
4092
|
|
4027
|
-
def format_app_deploy_status(status, return_color=cyan)
|
4028
|
-
out = ""
|
4029
|
-
s = status.to_s.downcase
|
4030
|
-
if s == 'deployed'
|
4031
|
-
out << "#{green}#{s.upcase}#{return_color}"
|
4032
|
-
elsif s == 'open' || s == 'archived' || s == 'committed'
|
4033
|
-
out << "#{cyan}#{s.upcase}#{return_color}"
|
4034
|
-
elsif s == 'failed'
|
4035
|
-
out << "#{red}#{s.upcase}#{return_color}"
|
4036
|
-
else
|
4037
|
-
out << "#{yellow}#{s.upcase}#{return_color}"
|
4038
|
-
end
|
4039
|
-
out
|
4040
|
-
end
|
4041
|
-
|
4042
4093
|
end
|