morpheus-cli 5.0.0 → 5.2.2
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/.gitignore +1 -0
- data/Dockerfile +1 -1
- data/lib/morpheus/api/api_client.rb +16 -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 +16 -2
- data/lib/morpheus/api/invoices_interface.rb +12 -3
- data/lib/morpheus/api/search_interface.rb +13 -0
- data/lib/morpheus/api/servers_interface.rb +14 -0
- data/lib/morpheus/api/service_catalog_interface.rb +89 -0
- data/lib/morpheus/api/usage_interface.rb +18 -0
- data/lib/morpheus/cli.rb +6 -2
- data/lib/morpheus/cli/apps.rb +3 -23
- data/lib/morpheus/cli/budgets_command.rb +389 -319
- data/lib/morpheus/cli/{catalog_command.rb → catalog_item_types_command.rb} +182 -67
- data/lib/morpheus/cli/cli_command.rb +51 -10
- data/lib/morpheus/cli/commands/standard/curl_command.rb +26 -13
- data/lib/morpheus/cli/commands/standard/history_command.rb +9 -3
- data/lib/morpheus/cli/commands/standard/man_command.rb +74 -40
- data/lib/morpheus/cli/containers_command.rb +0 -24
- data/lib/morpheus/cli/cypher_command.rb +6 -2
- data/lib/morpheus/cli/dashboard_command.rb +260 -20
- 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/groups.rb +1 -1
- data/lib/morpheus/cli/health_command.rb +59 -2
- data/lib/morpheus/cli/hosts.rb +271 -39
- data/lib/morpheus/cli/instances.rb +228 -129
- data/lib/morpheus/cli/invoices_command.rb +100 -20
- data/lib/morpheus/cli/jobs_command.rb +94 -92
- data/lib/morpheus/cli/library_option_lists_command.rb +1 -1
- data/lib/morpheus/cli/library_option_types_command.rb +10 -5
- data/lib/morpheus/cli/logs_command.rb +9 -6
- data/lib/morpheus/cli/mixins/accounts_helper.rb +5 -1
- data/lib/morpheus/cli/mixins/deployments_helper.rb +31 -2
- data/lib/morpheus/cli/mixins/print_helper.rb +13 -27
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +108 -5
- data/lib/morpheus/cli/option_types.rb +271 -22
- data/lib/morpheus/cli/remote.rb +35 -10
- data/lib/morpheus/cli/reports_command.rb +99 -30
- data/lib/morpheus/cli/roles.rb +193 -155
- data/lib/morpheus/cli/search_command.rb +182 -0
- data/lib/morpheus/cli/service_catalog_command.rb +1474 -0
- data/lib/morpheus/cli/setup.rb +1 -1
- data/lib/morpheus/cli/shell.rb +33 -11
- data/lib/morpheus/cli/tasks.rb +29 -32
- data/lib/morpheus/cli/usage_command.rb +64 -11
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/virtual_images.rb +429 -254
- data/lib/morpheus/cli/whoami.rb +6 -6
- data/lib/morpheus/cli/workflows.rb +33 -40
- data/lib/morpheus/formatters.rb +75 -18
- data/lib/morpheus/terminal.rb +6 -2
- metadata +10 -4
- data/lib/morpheus/cli/mixins/catalog_helper.rb +0 -66
data/lib/morpheus/cli/groups.rb
CHANGED
@@ -52,7 +52,7 @@ class Morpheus::Cli::Groups
|
|
52
52
|
end
|
53
53
|
json_response = @groups_interface.list(params)
|
54
54
|
exit_code, err = 0, nil
|
55
|
-
render_response(json_response, options) do
|
55
|
+
render_response(json_response, options, "groups") do
|
56
56
|
groups = json_response['groups']
|
57
57
|
subtitles = []
|
58
58
|
subtitles += parse_list_subtitles(options)
|
@@ -30,6 +30,7 @@ class Morpheus::Cli::HealthCommand
|
|
30
30
|
opts.on('-a', '--all', "Display all details: CPU, Memory, Database, etc." ) do
|
31
31
|
options[:details] = true
|
32
32
|
options[:show_cpu] = true
|
33
|
+
options[:show_threads] = true
|
33
34
|
options[:show_memory] = true
|
34
35
|
options[:show_database] = true
|
35
36
|
options[:show_elastic] = true
|
@@ -47,6 +48,9 @@ class Morpheus::Cli::HealthCommand
|
|
47
48
|
opts.on('--cpu', "Display CPU details" ) do
|
48
49
|
options[:show_cpu] = true
|
49
50
|
end
|
51
|
+
opts.on('--threads', "Display Thread details" ) do
|
52
|
+
options[:show_threads] = true
|
53
|
+
end
|
50
54
|
opts.on('--memory', "Display Memory details" ) do
|
51
55
|
options[:show_memory] = true
|
52
56
|
end
|
@@ -184,6 +188,59 @@ class Morpheus::Cli::HealthCommand
|
|
184
188
|
end
|
185
189
|
end
|
186
190
|
|
191
|
+
# Threads ()
|
192
|
+
if options[:show_threads]
|
193
|
+
print_h2 "Threads", options
|
194
|
+
if health['threads'].nil?
|
195
|
+
print yellow,"No thread information returned.",reset,"\n\n"
|
196
|
+
else
|
197
|
+
print cyan
|
198
|
+
|
199
|
+
thread_summary_columns = {
|
200
|
+
"Thread Count" => lambda {|it| it['totalThreads'].size rescue '' },
|
201
|
+
"Busy Threads" => lambda {|it| it['busyThreads'].size rescue '' },
|
202
|
+
"Running Threads" => lambda {|it| it['runningThreads'].size rescue '' },
|
203
|
+
"Blocked Threads" => lambda {|it| it['blockedThreads'].size rescue '' },
|
204
|
+
}
|
205
|
+
print_description_list(thread_summary_columns, health['threads'], options)
|
206
|
+
|
207
|
+
|
208
|
+
thread_columns = [
|
209
|
+
{"Name".upcase => lambda {|it| it['name']} },
|
210
|
+
{"Status".upcase => lambda {|it|
|
211
|
+
# hrmm
|
212
|
+
status_string = (it['status'] || it['state']).to_s.downcase
|
213
|
+
status_color = cyan
|
214
|
+
# if status_string.include?('waiting')
|
215
|
+
# status_color = yellow
|
216
|
+
# end
|
217
|
+
"#{status_color}#{status_string.upcase}#{cyan}"
|
218
|
+
} },
|
219
|
+
# {"CPU Time" => lambda {|it| it['cpuTime'].to_s } },
|
220
|
+
# {"CPU Time" => lambda {|it| format_human_duration(it['cpuTime'].to_f / 1000) rescue '' } },
|
221
|
+
{"CPU Percent" => lambda {|it| it['cpuPercent'].to_i.to_s + '%' } }
|
222
|
+
]
|
223
|
+
|
224
|
+
if health['threads']['busyThreads'] && health['threads']['busyThreads'].size > 0
|
225
|
+
print_h2 "Busy Threads"
|
226
|
+
print cyan
|
227
|
+
print as_pretty_table(health['threads']['busyThreads'], thread_columns, options)
|
228
|
+
end
|
229
|
+
|
230
|
+
if health['threads']['runningThreads'] && health['threads']['runningThreads'].size > 0
|
231
|
+
print_h2 "Running Threads"
|
232
|
+
print cyan
|
233
|
+
print as_pretty_table(health['threads']['runningThreads'], thread_columns, options)
|
234
|
+
end
|
235
|
+
|
236
|
+
if health['threads']['blockedThreads'] && health['threads']['blockedThreads'].size > 0
|
237
|
+
print_h2 "Blocked Threads"
|
238
|
+
print cyan
|
239
|
+
print as_pretty_table(health['threads']['blockedThreads'], thread_columns, options)
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
187
244
|
# Memory
|
188
245
|
if options[:show_memory]
|
189
246
|
if health['memory'].nil?
|
@@ -475,8 +532,8 @@ class Morpheus::Cli::HealthCommand
|
|
475
532
|
opts.footer = "List health logs. These are the logs of the morpheus appliance itself."
|
476
533
|
end
|
477
534
|
optparse.parse!(args)
|
478
|
-
if args.count
|
479
|
-
|
535
|
+
if args.count > 0
|
536
|
+
options[:phrase] = args.join(" ")
|
480
537
|
end
|
481
538
|
connect(options)
|
482
539
|
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, :software,
|
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,6 @@ 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( '-a', '--account ACCOUNT', "Account Name or ID" ) do |val|
|
57
|
-
options[:account] = val
|
58
|
-
end
|
59
57
|
opts.on( '-g', '--group GROUP', "Group Name or ID" ) do |val|
|
60
58
|
options[:group] = val
|
61
59
|
end
|
@@ -81,6 +79,17 @@ class Morpheus::Cli::Hosts
|
|
81
79
|
# params[:clusterId] = val
|
82
80
|
options[:cluster] = val
|
83
81
|
end
|
82
|
+
opts.on( '--plan NAME', String, "Filter by Plan name(s)" ) do |val|
|
83
|
+
# commas used in names a lot so use --plan one --plan two
|
84
|
+
params['plan'] ||= []
|
85
|
+
params['plan'] << val
|
86
|
+
end
|
87
|
+
opts.on( '--plan-id ID', String, "Filter by Plan id(s)" ) do |val|
|
88
|
+
params['planId'] = parse_id_list(val)
|
89
|
+
end
|
90
|
+
opts.on( '--plan-code CODE', String, "Filter by Plan code(s)" ) do |val|
|
91
|
+
params['planCode'] = parse_id_list(val)
|
92
|
+
end
|
84
93
|
opts.on( '', '--vm', "Show only virtual machines" ) do |val|
|
85
94
|
params[:vm] = true
|
86
95
|
end
|
@@ -105,8 +114,16 @@ class Morpheus::Cli::Hosts
|
|
105
114
|
opts.on( '--created-by USER', "Created By User Username or ID" ) do |val|
|
106
115
|
options[:created_by] = val
|
107
116
|
end
|
108
|
-
opts.on('--
|
109
|
-
options[:
|
117
|
+
opts.on( '--tenant TENANT', "Tenant Name or ID" ) do |val|
|
118
|
+
options[:account] = val
|
119
|
+
end
|
120
|
+
opts.on('--tags Name=Value',String, "Filter by tags.") do |val|
|
121
|
+
val.split(",").each do |value_pair|
|
122
|
+
k,v = value_pair.strip.split("=")
|
123
|
+
options[:tags] ||= {}
|
124
|
+
options[:tags][k] ||= []
|
125
|
+
options[:tags][k] << (v || '')
|
126
|
+
end
|
110
127
|
end
|
111
128
|
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
129
|
params[:tagCompliant] = true
|
@@ -114,7 +131,13 @@ class Morpheus::Cli::Hosts
|
|
114
131
|
opts.on('--non-tag-compliant', "Displays only servers with tag compliance warnings." ) do
|
115
132
|
params[:tagCompliant] = false
|
116
133
|
end
|
117
|
-
|
134
|
+
opts.on('--stats', "Display values for memory and storage usage used / max values." ) do
|
135
|
+
options[:stats] = true
|
136
|
+
end
|
137
|
+
opts.on('-a', '--details', "Display all details: hostname, private ip, plan, stats, etc." ) do
|
138
|
+
options[:details] = true
|
139
|
+
end
|
140
|
+
build_standard_list_options(opts, options)
|
118
141
|
opts.footer = "List hosts."
|
119
142
|
end
|
120
143
|
optparse.parse!(args)
|
@@ -163,6 +186,11 @@ class Morpheus::Cli::Hosts
|
|
163
186
|
params['clusterId'] = cluster['id']
|
164
187
|
end
|
165
188
|
end
|
189
|
+
if options[:tags] && !options[:tags].empty?
|
190
|
+
options[:tags].each do |k,v|
|
191
|
+
params['tags.' + k] = v
|
192
|
+
end
|
193
|
+
end
|
166
194
|
|
167
195
|
@servers_interface.setopts(options)
|
168
196
|
if options[:dry_run]
|
@@ -194,6 +222,9 @@ class Morpheus::Cli::Hosts
|
|
194
222
|
multi_tenant = json_response['multiTenant'] == true
|
195
223
|
title = "Morpheus Hosts"
|
196
224
|
subtitles = []
|
225
|
+
if account
|
226
|
+
subtitles << "Tenant: #{account['name']}".strip
|
227
|
+
end
|
197
228
|
if group
|
198
229
|
subtitles << "Group: #{group['name']}".strip
|
199
230
|
end
|
@@ -234,7 +265,7 @@ class Morpheus::Cli::Hosts
|
|
234
265
|
cpu_usage_str = !stats ? "" : generate_usage_bar((stats['usedCpu'] || stats['cpuUsage']).to_f, 100, {max_bars: 10})
|
235
266
|
memory_usage_str = !stats ? "" : generate_usage_bar(stats['usedMemory'], stats['maxMemory'], {max_bars: 10})
|
236
267
|
storage_usage_str = !stats ? "" : generate_usage_bar(stats['usedStorage'], stats['maxStorage'], {max_bars: 10})
|
237
|
-
if options[:details]
|
268
|
+
if options[:details] || options[:stats]
|
238
269
|
if stats['maxMemory'] && stats['maxMemory'].to_i != 0
|
239
270
|
memory_usage_str = memory_usage_str + cyan + format_bytes_short(stats['usedMemory']).strip.rjust(8, ' ') + " / " + format_bytes_short(stats['maxMemory']).strip
|
240
271
|
end
|
@@ -244,31 +275,76 @@ class Morpheus::Cli::Hosts
|
|
244
275
|
end
|
245
276
|
row = {
|
246
277
|
id: server['id'],
|
247
|
-
tenant: server['account'] ? server['account']['name'] : server['accountId'],
|
248
278
|
name: server['name'],
|
279
|
+
external_name: server['externalName'],
|
280
|
+
hostname: server['hostname'],
|
249
281
|
platform: server['serverOs'] ? server['serverOs']['name'].upcase : 'N/A',
|
250
|
-
cloud: server['zone'] ? server['zone']['name'] : '',
|
251
282
|
type: server['computeServerType'] ? server['computeServerType']['name'] : 'unmanaged',
|
283
|
+
tenant: server['account'] ? server['account']['name'] : server['accountId'],
|
284
|
+
owner: server['owner'] ? server['owner']['username'] : server['owner'],
|
285
|
+
cloud: server['zone'] ? server['zone']['name'] : '',
|
286
|
+
plan: server['plan'] ? server['plan']['name'] : '',
|
287
|
+
ip: server['externalIp'],
|
288
|
+
internal_ip: server['internalIp'],
|
252
289
|
nodes: server['containers'] ? server['containers'].size : '',
|
253
|
-
status: format_server_status(server, cyan),
|
290
|
+
# status: format_server_status(server, cyan),
|
291
|
+
status: (options[:details]||options[:all_fields]) ? format_server_status(server, cyan) : format_server_status_friendly(server, cyan),
|
254
292
|
power: format_server_power_state(server, cyan),
|
255
293
|
cpu: cpu_usage_str + cyan,
|
256
294
|
memory: memory_usage_str + cyan,
|
257
|
-
storage: storage_usage_str + cyan
|
295
|
+
storage: storage_usage_str + cyan,
|
296
|
+
created: format_local_dt(server['dateCreated']),
|
297
|
+
updated: format_local_dt(server['lastUpdated']),
|
258
298
|
}
|
259
299
|
row
|
260
300
|
}
|
261
|
-
columns = [:id, :name, :type, :cloud, :nodes, :status, :power]
|
262
|
-
|
263
|
-
|
301
|
+
# columns = [:id, :name, :type, :cloud, :ip, :internal_ip, :nodes, :status, :power]
|
302
|
+
columns = {
|
303
|
+
"ID" => :id,
|
304
|
+
"Name" => :name,
|
305
|
+
"External Name" => :external_name,
|
306
|
+
"Hostname" => :hostname,
|
307
|
+
"Type" => :type,
|
308
|
+
"Owner" => :owner,
|
309
|
+
"Tenant" => :tenant,
|
310
|
+
"Cloud" => :cloud,
|
311
|
+
"Plan" => :plan,
|
312
|
+
"IP" => :ip,
|
313
|
+
"Private IP" => :internal_ip,
|
314
|
+
"Nodes" => :nodes,
|
315
|
+
"Status" => :status,
|
316
|
+
"Power" => :power,
|
317
|
+
"CPU" => :cpu,
|
318
|
+
"Memory" => :memory,
|
319
|
+
"Storage" => :storage,
|
320
|
+
"Created" => :created,
|
321
|
+
"Updated" => :updated,
|
322
|
+
}
|
323
|
+
if options[:details] != true
|
324
|
+
columns.delete("External Name")
|
325
|
+
columns.delete("Hostname")
|
326
|
+
columns.delete("Plan")
|
327
|
+
columns.delete("Private IP")
|
328
|
+
columns.delete("Owner")
|
329
|
+
columns.delete("Tenant")
|
330
|
+
columns.delete("Power")
|
331
|
+
columns.delete("Created")
|
332
|
+
columns.delete("Updated")
|
264
333
|
end
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
columns = options[:include_fields]
|
334
|
+
# hide External Name if there are none
|
335
|
+
if !servers.find {|it| it['externalName'] && it['externalName'] != it['name']}
|
336
|
+
columns.delete("External Name")
|
269
337
|
end
|
338
|
+
if !multi_tenant
|
339
|
+
columns.delete("Tenant")
|
340
|
+
end
|
341
|
+
# columns += [:cpu, :memory, :storage]
|
342
|
+
# # custom pretty table columns ...
|
343
|
+
# if options[:include_fields]
|
344
|
+
# columns = options[:include_fields]
|
345
|
+
# end
|
270
346
|
print cyan
|
271
|
-
print as_pretty_table(rows, columns
|
347
|
+
print as_pretty_table(rows, columns.upcase_keys!, options)
|
272
348
|
print reset
|
273
349
|
print_results_pagination(json_response)
|
274
350
|
end
|
@@ -285,7 +361,7 @@ class Morpheus::Cli::Hosts
|
|
285
361
|
options = {}
|
286
362
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
287
363
|
opts.banner = subcommand_usage("[options]")
|
288
|
-
opts.on( '
|
364
|
+
opts.on( '--tenant TENANT', "Tenant Name or ID" ) do |val|
|
289
365
|
options[:account] = val
|
290
366
|
end
|
291
367
|
opts.on( '-g', '--group GROUP', "Group Name or ID" ) do |val|
|
@@ -454,36 +530,43 @@ class Morpheus::Cli::Hosts
|
|
454
530
|
puts records_as_csv([json_response['server']], options)
|
455
531
|
return 0
|
456
532
|
end
|
457
|
-
server = json_response['server']
|
533
|
+
server = json_response['server'] || json_response['host'] || {}
|
458
534
|
#stats = server['stats'] || json_response['stats'] || {}
|
459
535
|
stats = json_response['stats'] || {}
|
536
|
+
tags = server['tags'] || server['metadata']
|
460
537
|
title = "Host Details"
|
461
538
|
print_h1 title, [], options
|
462
539
|
print cyan
|
463
540
|
server_columns = {
|
464
541
|
"ID" => 'id',
|
465
542
|
"Name" => 'name',
|
543
|
+
"Hostname" => 'hostname',
|
466
544
|
"Description" => 'description',
|
467
|
-
"
|
545
|
+
"Tags" => lambda {|it| tags ? format_metadata(tags) : '' },
|
546
|
+
"Owner" => lambda {|it| it['owner'] ? it['owner']['username'] : '' },
|
547
|
+
"Tenant" => lambda {|it| it['account'] ? it['account']['name'] : '' },
|
468
548
|
#"Group" => lambda {|it| it['group'] ? it['group']['name'] : '' },
|
469
549
|
"Cloud" => lambda {|it| it['zone'] ? it['zone']['name'] : '' },
|
550
|
+
"IP" => lambda {|it| it['externalIp'] },
|
551
|
+
"Private IP" => lambda {|it| it['internalIp'] },
|
470
552
|
"Type" => lambda {|it| it['computeServerType'] ? it['computeServerType']['name'] : 'unmanaged' },
|
471
553
|
"Platform" => lambda {|it| it['serverOs'] ? it['serverOs']['name'].upcase : 'N/A' },
|
472
554
|
"Plan" => lambda {|it| it['plan'] ? it['plan']['name'] : '' },
|
473
555
|
"Cost" => lambda {|it| it['hourlyCost'] ? format_money(it['hourlyCost'], (it['currency'] || 'USD'), {sigdig:15}).to_s + ' per hour' : '' },
|
474
556
|
"Price" => lambda {|it| it['hourlyPrice'] ? format_money(it['hourlyPrice'], (it['currency'] || 'USD'), {sigdig:15}).to_s + ' per hour' : '' },
|
475
557
|
"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
558
|
"Nodes" => lambda {|it| it['containers'] ? it['containers'].size : 0 },
|
478
|
-
"
|
559
|
+
# "Status" => lambda {|it| format_server_status(it) },
|
560
|
+
# "Power" => lambda {|it| format_server_power_state(it) },
|
561
|
+
"Status" => lambda {|it| format_server_status_friendly(it) }, # combo
|
479
562
|
}
|
480
|
-
|
481
|
-
if server['
|
482
|
-
|
483
|
-
|
484
|
-
if server['
|
485
|
-
|
486
|
-
|
563
|
+
server_columns.delete("Hostname") if server['hostname'].to_s.empty? || server['hostname'] == server['name']
|
564
|
+
server_columns.delete("IP") if server['externalIp'].to_s.empty?
|
565
|
+
server_columns.delete("Private IP") if server['internalIp'].to_s.empty?
|
566
|
+
# server_columns.delete("Tenant") if multi_tenant != true
|
567
|
+
server_columns.delete("Cost") if server['hourlyCost'].to_f == 0
|
568
|
+
server_columns.delete("Price") if server['hourlyPrice'].to_f == 0 || server['hourlyPrice'] == server['hourlyCost']
|
569
|
+
server_columns.delete("Tags") if tags.nil? || tags.empty?
|
487
570
|
|
488
571
|
print_description_list(server_columns, server)
|
489
572
|
|
@@ -910,6 +993,19 @@ class Morpheus::Cli::Hosts
|
|
910
993
|
opts.on('--power-schedule-type ID', String, "Power Schedule Type ID") do |val|
|
911
994
|
params['powerScheduleType'] = val == "null" ? nil : val
|
912
995
|
end
|
996
|
+
opts.on('--tags LIST', String, "Tags in the format 'name:value, name:value'. This will add and remove tags.") do |val|
|
997
|
+
options[:tags] = val
|
998
|
+
end
|
999
|
+
opts.on('--metadata LIST', String, "Alias for --tags.") do |val|
|
1000
|
+
options[:tags] = val
|
1001
|
+
end
|
1002
|
+
opts.add_hidden_option('--metadata')
|
1003
|
+
opts.on('--add-tags TAGS', String, "Add Tags in the format 'name:value, name:value'. This will only add/update tags.") do |val|
|
1004
|
+
options[:add_tags] = val
|
1005
|
+
end
|
1006
|
+
opts.on('--remove-tags TAGS', String, "Remove Tags in the format 'name, name:value'. This removes tags, the :value component is optional and must match if passed.") do |val|
|
1007
|
+
options[:remove_tags] = val
|
1008
|
+
end
|
913
1009
|
# opts.on('--created-by ID', String, "Created By User ID") do |val|
|
914
1010
|
# params['createdById'] = val
|
915
1011
|
# end
|
@@ -928,6 +1024,18 @@ class Morpheus::Cli::Hosts
|
|
928
1024
|
new_group = nil
|
929
1025
|
passed_options = options[:options] ? options[:options].reject {|k,v| k.is_a?(Symbol) } : {}
|
930
1026
|
params.deep_merge!(passed_options) unless passed_options.empty?
|
1027
|
+
# metadata tags
|
1028
|
+
if options[:tags]
|
1029
|
+
params['tags'] = parse_metadata(options[:tags])
|
1030
|
+
else
|
1031
|
+
# params['tags'] = prompt_metadata(options)
|
1032
|
+
end
|
1033
|
+
if options[:add_tags]
|
1034
|
+
params['addTags'] = parse_metadata(options[:add_tags])
|
1035
|
+
end
|
1036
|
+
if options[:remove_tags]
|
1037
|
+
params['removeTags'] = parse_metadata(options[:remove_tags])
|
1038
|
+
end
|
931
1039
|
payload = nil
|
932
1040
|
if options[:payload]
|
933
1041
|
payload = options[:payload]
|
@@ -1809,6 +1917,103 @@ class Morpheus::Cli::Hosts
|
|
1809
1917
|
end
|
1810
1918
|
end
|
1811
1919
|
|
1920
|
+
def snapshots(args)
|
1921
|
+
options = {}
|
1922
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
1923
|
+
opts.banner = subcommand_usage("[host]")
|
1924
|
+
# no pagination yet
|
1925
|
+
# build_standard_list_options(opts, options)
|
1926
|
+
build_standard_get_options(opts, options)
|
1927
|
+
end
|
1928
|
+
optparse.parse!(args)
|
1929
|
+
verify_args!(args:args, optparse:optparse, count:1)
|
1930
|
+
connect(options)
|
1931
|
+
begin
|
1932
|
+
server = find_host_by_name_or_id(args[0])
|
1933
|
+
return 1 if server.nil?
|
1934
|
+
params = {}
|
1935
|
+
@servers_interface.setopts(options)
|
1936
|
+
if options[:dry_run]
|
1937
|
+
print_dry_run @servers_interface.dry.snapshots(server['id'], params)
|
1938
|
+
return
|
1939
|
+
end
|
1940
|
+
json_response = @servers_interface.snapshots(server['id'], params)
|
1941
|
+
snapshots = json_response['snapshots']
|
1942
|
+
render_response(json_response, options, 'snapshots') do
|
1943
|
+
print_h1 "Snapshots: #{server['name']}", [], options
|
1944
|
+
if snapshots.empty?
|
1945
|
+
print cyan,"No snapshots found",reset,"\n"
|
1946
|
+
else
|
1947
|
+
snapshot_column_definitions = {
|
1948
|
+
"ID" => lambda {|it| it['id'] },
|
1949
|
+
"Name" => lambda {|it| it['name'] },
|
1950
|
+
"Description" => lambda {|it| it['description'] },
|
1951
|
+
# "Type" => lambda {|it| it['snapshotType'] },
|
1952
|
+
"Date Created" => lambda {|it| format_local_dt(it['snapshotCreated']) },
|
1953
|
+
"Status" => lambda {|it| format_snapshot_status(it) }
|
1954
|
+
}
|
1955
|
+
print cyan
|
1956
|
+
print as_pretty_table(snapshots, snapshot_column_definitions.upcase_keys!, options)
|
1957
|
+
print_results_pagination({size: snapshots.size, total: snapshots.size})
|
1958
|
+
end
|
1959
|
+
print reset, "\n"
|
1960
|
+
end
|
1961
|
+
return 0
|
1962
|
+
rescue RestClient::Exception => e
|
1963
|
+
print_rest_exception(e, options)
|
1964
|
+
exit 1
|
1965
|
+
end
|
1966
|
+
end
|
1967
|
+
|
1968
|
+
def software(args)
|
1969
|
+
options = {}
|
1970
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
1971
|
+
opts.banner = subcommand_usage("[host]")
|
1972
|
+
build_standard_list_options(opts, options)
|
1973
|
+
end
|
1974
|
+
optparse.parse!(args)
|
1975
|
+
verify_args!(args:args, optparse:optparse, count:1)
|
1976
|
+
connect(options)
|
1977
|
+
begin
|
1978
|
+
server = find_host_by_name_or_id(args[0])
|
1979
|
+
return 1 if server.nil?
|
1980
|
+
params = {}
|
1981
|
+
params.merge!(parse_list_options(options))
|
1982
|
+
@servers_interface.setopts(options)
|
1983
|
+
if options[:dry_run]
|
1984
|
+
print_dry_run @servers_interface.dry.software(server['id'], params)
|
1985
|
+
return
|
1986
|
+
end
|
1987
|
+
json_response = @servers_interface.software(server['id'], params)
|
1988
|
+
software = json_response['software']
|
1989
|
+
render_response(json_response, options, 'software') do
|
1990
|
+
print_h1 "Software: #{server['name']}", [], options
|
1991
|
+
if software.empty?
|
1992
|
+
print cyan,"No software found",reset,"\n"
|
1993
|
+
else
|
1994
|
+
software_column_definitions = {
|
1995
|
+
# "ID" => lambda {|it| it['id'] },
|
1996
|
+
"Name" => lambda {|it| it['name'] },
|
1997
|
+
"Version" => lambda {|it| it['packageVersion'] },
|
1998
|
+
"Publisher" => lambda {|it| it['packagePublisher'] },
|
1999
|
+
# "Release" => lambda {|it| it['packageRelease'] },
|
2000
|
+
# "Type" => lambda {|it| it['packageType'] },
|
2001
|
+
# "Architecture" => lambda {|it| it['architecture'] },
|
2002
|
+
# "Install Date" => lambda {|it| format_local_dt(it['installDate']) },
|
2003
|
+
}
|
2004
|
+
print cyan
|
2005
|
+
print as_pretty_table(software, software_column_definitions.upcase_keys!, options)
|
2006
|
+
print_results_pagination({size: software.size, total: software.size})
|
2007
|
+
end
|
2008
|
+
print reset, "\n"
|
2009
|
+
end
|
2010
|
+
return 0
|
2011
|
+
rescue RestClient::Exception => e
|
2012
|
+
print_rest_exception(e, options)
|
2013
|
+
exit 1
|
2014
|
+
end
|
2015
|
+
end
|
2016
|
+
|
1812
2017
|
private
|
1813
2018
|
|
1814
2019
|
def find_host_by_id(id)
|
@@ -1925,16 +2130,43 @@ class Morpheus::Cli::Hosts
|
|
1925
2130
|
|
1926
2131
|
def format_server_status(server, return_color=cyan)
|
1927
2132
|
out = ""
|
1928
|
-
status_string = server['status']
|
1929
|
-
|
1930
|
-
|
2133
|
+
status_string = server['status'].to_s.downcase
|
2134
|
+
if status_string == 'provisioned'
|
2135
|
+
out = "#{cyan}#{status_string.upcase}#{return_color}"
|
2136
|
+
elsif status_string == 'provisioning'
|
2137
|
+
out = "#{cyan}#{status_string.upcase}#{cyan}"
|
2138
|
+
elsif status_string == 'failed' or status_string == 'error'
|
2139
|
+
out = "#{red}#{status_string.upcase}#{return_color}"
|
2140
|
+
else
|
2141
|
+
out = "#{yellow}#{status_string.upcase}#{return_color}"
|
2142
|
+
end
|
2143
|
+
out
|
2144
|
+
end
|
2145
|
+
|
2146
|
+
def format_server_status_friendly(server, return_color=cyan)
|
2147
|
+
out = ""
|
2148
|
+
status_string = server['status'].to_s.downcase
|
2149
|
+
if status_string == 'provisioned'
|
2150
|
+
# out = format_server_power_state(server, return_color)
|
2151
|
+
# make it looks like format_instance_status
|
2152
|
+
if server['powerState'] == 'on'
|
2153
|
+
out << "#{green}RUNNING#{return_color}"
|
2154
|
+
elsif server['powerState'] == 'off'
|
2155
|
+
out << "#{red}STOPPED#{return_color}"
|
2156
|
+
else
|
2157
|
+
out << "#{white}#{server['powerState'].to_s.upcase}#{return_color}"
|
2158
|
+
end
|
2159
|
+
else
|
2160
|
+
out = format_server_status(server, return_color)
|
2161
|
+
end
|
1931
2162
|
out
|
1932
2163
|
end
|
2164
|
+
|
1933
2165
|
|
1934
2166
|
def make_managed_option_types(connected=true)
|
1935
2167
|
[
|
1936
2168
|
#{'fieldName' => 'account', 'fieldLabel' => 'Account', 'type' => 'select', 'optionSource' => 'accounts', 'required' => true},
|
1937
|
-
{'fieldName' => 'sshUsername', 'fieldLabel' => 'SSH Username', 'type' => 'text'
|
2169
|
+
{'fieldName' => 'sshUsername', 'fieldLabel' => 'SSH Username', 'type' => 'text'},
|
1938
2170
|
{'fieldName' => 'sshPassword', 'fieldLabel' => 'SSH Password', 'type' => 'password', 'required' => false},
|
1939
2171
|
{'fieldName' => 'serverOs', 'fieldLabel' => 'OS Type', 'type' => 'select', 'optionSource' => 'osTypes', 'required' => false},
|
1940
2172
|
]
|