morpheus-cli 5.0.0 → 5.2.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -8,7 +8,7 @@ class Morpheus::Cli::InvoicesCommand
|
|
8
8
|
|
9
9
|
set_command_name :'invoices'
|
10
10
|
|
11
|
-
register_subcommands :list, :get, :refresh,
|
11
|
+
register_subcommands :list, :get, :update, :refresh,
|
12
12
|
:list_line_items, :get_line_item
|
13
13
|
|
14
14
|
def connect(opts)
|
@@ -25,16 +25,19 @@ class Morpheus::Cli::InvoicesCommand
|
|
25
25
|
options = {}
|
26
26
|
params = {}
|
27
27
|
ref_ids = []
|
28
|
-
query_tags = {}
|
29
28
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
30
29
|
opts.banner = subcommand_usage()
|
31
30
|
opts.on('-a', '--all', "Display all details, costs and prices." ) do
|
32
31
|
options[:show_all] = true
|
32
|
+
options[:show_dates] = true
|
33
33
|
options[:show_estimates] = true
|
34
34
|
# options[:show_costs] = true
|
35
35
|
options[:show_prices] = true
|
36
36
|
# options[:show_raw_data] = true
|
37
37
|
end
|
38
|
+
opts.on('--dates', "Display Ref Start, Ref End, etc.") do |val|
|
39
|
+
options[:show_dates] = true
|
40
|
+
end
|
38
41
|
opts.on('--estimates', '--estimates', "Display all estimated costs, from usage info: Compute, Storage, Network, Extra" ) do
|
39
42
|
options[:show_estimates] = true
|
40
43
|
end
|
@@ -107,9 +110,12 @@ class Morpheus::Cli::InvoicesCommand
|
|
107
110
|
params['accountId'] = val
|
108
111
|
end
|
109
112
|
opts.on('--tags Name=Value',String, "Filter by tags.") do |val|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
+
val.split(",").each do |value_pair|
|
114
|
+
k,v = value_pair.strip.split("=")
|
115
|
+
options[:tags] ||= {}
|
116
|
+
options[:tags][k] ||= []
|
117
|
+
options[:tags][k] << (v || '')
|
118
|
+
end
|
113
119
|
end
|
114
120
|
opts.on('--raw-data', '--raw-data', "Display Raw Data, the cost data from the cloud provider's API.") do |val|
|
115
121
|
options[:show_raw_data] = true
|
@@ -169,8 +175,8 @@ class Morpheus::Cli::InvoicesCommand
|
|
169
175
|
end
|
170
176
|
params['rawData'] = true if options[:show_raw_data]
|
171
177
|
params['refId'] = ref_ids unless ref_ids.empty?
|
172
|
-
if
|
173
|
-
|
178
|
+
if options[:tags] && !options[:tags].empty?
|
179
|
+
options[:tags].each do |k,v|
|
174
180
|
params['tags.' + k] = v
|
175
181
|
end
|
176
182
|
end
|
@@ -203,6 +209,7 @@ class Morpheus::Cli::InvoicesCommand
|
|
203
209
|
{"INVOICE ID" => lambda {|it| it['id'] } },
|
204
210
|
{"TYPE" => lambda {|it| format_invoice_ref_type(it) } },
|
205
211
|
{"REF ID" => lambda {|it| it['refId'] } },
|
212
|
+
{"REF UUID" => lambda {|it| it['refUuid'] } },
|
206
213
|
{"REF NAME" => lambda {|it|
|
207
214
|
if options[:show_all]
|
208
215
|
it['refName']
|
@@ -218,9 +225,11 @@ class Morpheus::Cli::InvoicesCommand
|
|
218
225
|
{"PERIOD" => lambda {|it| format_invoice_period(it) } },
|
219
226
|
{"START" => lambda {|it| format_date(it['startDate']) } },
|
220
227
|
{"END" => lambda {|it| format_date(it['endDate']) } },
|
221
|
-
] + (options[:show_all] ? [
|
228
|
+
] + ((options[:show_dates] || options[:show_all]) ? [
|
222
229
|
{"REF START" => lambda {|it| format_dt(it['refStart']) } },
|
223
230
|
{"REF END" => lambda {|it| format_dt(it['refEnd']) } },
|
231
|
+
# {"LAST COST DATE" => lambda {|it| format_local_dt(it['lastCostDate']) } },
|
232
|
+
# {"LAST ACTUAL DATE" => lambda {|it| format_local_dt(it['lastActualDate']) } },
|
224
233
|
] : []) + [
|
225
234
|
{"COMPUTE" => lambda {|it| format_money(it['computeCost'], 'usd', {sigdig:options[:sigdig]}) } },
|
226
235
|
# {"MEMORY" => lambda {|it| format_money(it['memoryCost']) } },
|
@@ -263,7 +272,7 @@ class Morpheus::Cli::InvoicesCommand
|
|
263
272
|
{"ESTIMATE" => lambda {|it| format_boolean(it['estimate']) } },
|
264
273
|
{"ACTIVE" => lambda {|it| format_boolean(it['active']) } },
|
265
274
|
{"ITEMS" => lambda {|it| it['lineItems'].size rescue '' } },
|
266
|
-
{"TAGS" => lambda {|it| it['metadata'] ? it['metadata'].collect {|m| "#{m['name']}: #{m['value']}" }.join(', ') : '' } },
|
275
|
+
{"TAGS" => lambda {|it| (it['metadata'] || it['tags']) ? (it['metadata'] || it['tags']).collect {|m| "#{m['name']}: #{m['value']}" }.join(', ') : '' } },
|
267
276
|
]
|
268
277
|
if show_projects
|
269
278
|
columns += [
|
@@ -272,9 +281,15 @@ class Morpheus::Cli::InvoicesCommand
|
|
272
281
|
{"PROJECT TAGS" => lambda {|it| it['project'] ? truncate_string(format_metadata(it['project']['tags']), 50) : '' } },
|
273
282
|
]
|
274
283
|
end
|
284
|
+
if options[:show_dates]
|
285
|
+
columns += [
|
286
|
+
{"LAST COST DATE" => lambda {|it| format_local_dt(it['lastCostDate']) } },
|
287
|
+
{"LAST ACTUAL DATE" => lambda {|it| format_local_dt(it['lastActualDate']) } },
|
288
|
+
]
|
289
|
+
end
|
275
290
|
columns += [
|
276
291
|
{"CREATED" => lambda {|it| format_local_dt(it['dateCreated']) } },
|
277
|
-
{"UPDATED" => lambda {|it| format_local_dt(it['lastUpdated']) } }
|
292
|
+
{"UPDATED" => lambda {|it| format_local_dt(it['lastUpdated']) } },
|
278
293
|
]
|
279
294
|
if options[:show_raw_data]
|
280
295
|
columns += [{"RAW DATA" => lambda {|it| truncate_string(it['rawData'].to_s, 10) } }]
|
@@ -423,7 +438,7 @@ EOT
|
|
423
438
|
"Ref Start" => lambda {|it| format_dt(it['refStart']) },
|
424
439
|
"Ref End" => lambda {|it| format_dt(it['refEnd']) },
|
425
440
|
"Items" => lambda {|it| it['lineItems'].size rescue '' },
|
426
|
-
"Tags" => lambda {|it| it['metadata'] ? it['metadata'].collect {|m| "#{m['name']}: #{m['value']}" }.join(', ') : '' },
|
441
|
+
"Tags" => lambda {|it| (it['metadata'] || it['tags']) ? (it['metadata'] || it['tags']).collect {|m| "#{m['name']}: #{m['value']}" }.join(', ') : '' },
|
427
442
|
"Project ID" => lambda {|it| it['project'] ? it['project']['id'] : '' },
|
428
443
|
"Project Name" => lambda {|it| it['project'] ? it['project']['name'] : '' },
|
429
444
|
"Project Tags" => lambda {|it| it['project'] ? format_metadata(it['project']['tags']) : '' },
|
@@ -439,7 +454,8 @@ EOT
|
|
439
454
|
description_cols.delete("Project Name")
|
440
455
|
description_cols.delete("Project Tags")
|
441
456
|
end
|
442
|
-
|
457
|
+
tags = (invoice['metadata'] || invoice['tags'])
|
458
|
+
if tags.nil? || tags.empty?
|
443
459
|
description_cols.delete("Tags")
|
444
460
|
end
|
445
461
|
if !['ComputeServer','Instance','Container'].include?(invoice['refType'])
|
@@ -575,6 +591,68 @@ EOT
|
|
575
591
|
end
|
576
592
|
end
|
577
593
|
|
594
|
+
def update(args)
|
595
|
+
options = {}
|
596
|
+
params = {}
|
597
|
+
payload = {}
|
598
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
599
|
+
opts.banner = subcommand_usage("[invoice] [options]")
|
600
|
+
opts.on('--tags LIST', String, "Tags in the format 'name:value, name:value'. This will add and remove tags.") do |val|
|
601
|
+
options[:tags] = val
|
602
|
+
end
|
603
|
+
opts.on('--add-tags TAGS', String, "Add Tags in the format 'name:value, name:value'. This will only add/update tags.") do |val|
|
604
|
+
options[:add_tags] = val
|
605
|
+
end
|
606
|
+
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|
|
607
|
+
options[:remove_tags] = val
|
608
|
+
end
|
609
|
+
build_standard_update_options(opts, options)
|
610
|
+
opts.footer = <<-EOT
|
611
|
+
Update an invoice.
|
612
|
+
[invoice] is required. This is the id of an invoice.
|
613
|
+
EOT
|
614
|
+
end
|
615
|
+
optparse.parse!(args)
|
616
|
+
verify_args!(args:args, optparse:optparse, count:1)
|
617
|
+
connect(options)
|
618
|
+
json_response = @invoices_interface.get(args[0])
|
619
|
+
invoice = json_response['invoice']
|
620
|
+
|
621
|
+
invoice_payload = parse_passed_options(options)
|
622
|
+
if options[:tags]
|
623
|
+
invoice_payload['tags'] = parse_metadata(options[:tags])
|
624
|
+
end
|
625
|
+
if options[:add_tags]
|
626
|
+
invoice_payload['addTags'] = parse_metadata(options[:add_tags])
|
627
|
+
end
|
628
|
+
if options[:remove_tags]
|
629
|
+
invoice_payload['removeTags'] = parse_metadata(options[:remove_tags])
|
630
|
+
end
|
631
|
+
|
632
|
+
payload = {}
|
633
|
+
if options[:payload]
|
634
|
+
payload = options[:payload]
|
635
|
+
payload.deep_merge!({'invoice' => invoice_payload})
|
636
|
+
else
|
637
|
+
payload.deep_merge!({'invoice' => invoice_payload})
|
638
|
+
if invoice_payload.empty?
|
639
|
+
raise_command_error "Specify at least one option to update.\n#{optparse}"
|
640
|
+
end
|
641
|
+
end
|
642
|
+
@invoices_interface.setopts(options)
|
643
|
+
if options[:dry_run]
|
644
|
+
print_dry_run @invoices_interface.dry.update(invoice['id'], payload)
|
645
|
+
return
|
646
|
+
end
|
647
|
+
json_response = @invoices_interface.update(invoice['id'], payload)
|
648
|
+
invoice = json_response['invoice']
|
649
|
+
render_response(json_response, options, 'invoice') do
|
650
|
+
print_green_success "Updated invoice #{invoice['id']}"
|
651
|
+
return _get(invoice["id"], options)
|
652
|
+
end
|
653
|
+
return 0, nil
|
654
|
+
end
|
655
|
+
|
578
656
|
def refresh(args)
|
579
657
|
options = {}
|
580
658
|
params = {}
|
@@ -656,7 +734,6 @@ EOT
|
|
656
734
|
options = {}
|
657
735
|
params = {}
|
658
736
|
ref_ids = []
|
659
|
-
query_tags = {}
|
660
737
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
661
738
|
opts.banner = subcommand_usage()
|
662
739
|
opts.on('-a', '--all', "Display all details, costs and prices." ) do
|
@@ -744,11 +821,14 @@ EOT
|
|
744
821
|
opts.on('--tenant ID', String, "View invoice line items for a tenant. Default is your own account.") do |val|
|
745
822
|
params['accountId'] = val
|
746
823
|
end
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
824
|
+
opts.on('--tags Name=Value',String, "Filter by tags.") do |val|
|
825
|
+
val.split(",").each do |value_pair|
|
826
|
+
k,v = value_pair.strip.split("=")
|
827
|
+
options[:tags] ||= {}
|
828
|
+
options[:tags][k] ||= []
|
829
|
+
options[:tags][k] << (v || '')
|
830
|
+
end
|
831
|
+
end
|
752
832
|
opts.on('--raw-data', '--raw-data', "Display Raw Data, the cost data from the cloud provider's API.") do |val|
|
753
833
|
options[:show_raw_data] = true
|
754
834
|
end
|
@@ -808,8 +888,8 @@ EOT
|
|
808
888
|
end
|
809
889
|
params['rawData'] = true if options[:show_raw_data]
|
810
890
|
params['refId'] = ref_ids unless ref_ids.empty?
|
811
|
-
if
|
812
|
-
|
891
|
+
if options[:tags] && !options[:tags].empty?
|
892
|
+
options[:tags].each do |k,v|
|
813
893
|
params['tags.' + k] = v
|
814
894
|
end
|
815
895
|
end
|
@@ -28,6 +28,7 @@ class Morpheus::Cli::JobsCommand
|
|
28
28
|
|
29
29
|
def list(args)
|
30
30
|
options = {}
|
31
|
+
options[:show_stats] = true
|
31
32
|
params = {}
|
32
33
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
33
34
|
opts.banner = subcommand_usage()
|
@@ -37,7 +38,10 @@ class Morpheus::Cli::JobsCommand
|
|
37
38
|
opts.on("--internal [true|false]", String, "Filters job based on internal flag. Internal jobs are excluded by default.") do |val|
|
38
39
|
params["internalOnly"] = (val.to_s != "false")
|
39
40
|
end
|
40
|
-
|
41
|
+
opts.on("--stats [true|false]", String, "Hide Execution Stats. Job statistics are displayed by default.") do |val|
|
42
|
+
options[:show_stats] = (val.to_s != "false")
|
43
|
+
end
|
44
|
+
build_standard_list_options(opts, options)
|
41
45
|
opts.footer = "List jobs."
|
42
46
|
end
|
43
47
|
optparse.parse!(args)
|
@@ -47,78 +51,72 @@ class Morpheus::Cli::JobsCommand
|
|
47
51
|
return 1
|
48
52
|
end
|
49
53
|
|
50
|
-
begin
|
51
|
-
params.merge!(parse_list_options(options))
|
52
54
|
|
53
|
-
|
54
|
-
if !['all', 'user', 'discovered', 'sync'].include?(options[:source])
|
55
|
-
print_red_alert "Invalid source filter #{options[:source]}"
|
56
|
-
exit 1
|
57
|
-
end
|
58
|
-
params['itemSource'] = options[:source] == 'discovered' ? 'sync' : options[:source]
|
59
|
-
end
|
55
|
+
params.merge!(parse_list_options(options))
|
60
56
|
|
61
|
-
|
62
|
-
if options[:
|
63
|
-
|
64
|
-
|
57
|
+
if !options[:source].nil?
|
58
|
+
if !['all', 'user', 'discovered', 'sync'].include?(options[:source])
|
59
|
+
print_red_alert "Invalid source filter #{options[:source]}"
|
60
|
+
exit 1
|
65
61
|
end
|
66
|
-
|
67
|
-
|
68
|
-
render_result = render_with_format(json_response, options, 'jobs')
|
69
|
-
return 0 if render_result
|
62
|
+
params['itemSource'] = options[:source] == 'discovered' ? 'sync' : options[:source]
|
63
|
+
end
|
70
64
|
|
65
|
+
@jobs_interface.setopts(options)
|
66
|
+
if options[:dry_run]
|
67
|
+
print_dry_run @jobs_interface.dry.list(params)
|
68
|
+
return
|
69
|
+
end
|
70
|
+
json_response = @jobs_interface.list(params)
|
71
|
+
jobs = json_response['jobs']
|
72
|
+
render_response(json_response, options, 'jobs') do
|
71
73
|
title = "Morpheus Jobs"
|
72
74
|
subtitles = []
|
73
75
|
subtitles += parse_list_subtitles(options)
|
74
76
|
if params["internalOnly"]
|
75
77
|
subtitles << "internalOnly: #{params['internalOnly']}"
|
76
78
|
end
|
77
|
-
print_h1 title, subtitles
|
78
|
-
|
79
|
-
jobs = json_response['jobs']
|
80
|
-
|
79
|
+
print_h1 title, subtitles, options
|
81
80
|
if jobs.empty?
|
82
81
|
print cyan,"No jobs found.",reset,"\n"
|
83
82
|
else
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
}
|
95
|
-
|
96
|
-
columns
|
97
|
-
:id, :type, :name, :details, :enabled, :lastRun, :nextRun, :lastResult
|
98
|
-
]
|
99
|
-
print as_pretty_table(rows, columns, options)
|
83
|
+
columns = {
|
84
|
+
"ID" => 'id',
|
85
|
+
"Type" => lambda {|job| job['type'] ? job['type']['name'] : '' },
|
86
|
+
"Name" => 'name',
|
87
|
+
"Details" => lambda {|job| job['jobSummary'] },
|
88
|
+
"Enabled" => lambda {|job| "#{job['enabled'] ? '' : yellow}#{format_boolean(job['enabled'])}#{cyan}" },
|
89
|
+
# "Date Created" => lambda {|job| format_local_dt(job['dateCreated']) },
|
90
|
+
# "Last Updated" => lambda {|job| format_local_dt(job['lastUpdated']) },
|
91
|
+
"Last Run" => lambda {|job| format_local_dt(job['lastRun']) },
|
92
|
+
"Next Run" => lambda {|job| job['enabled'] && job['scheduleMode'] && job['scheduleMode'] != 'manual' ? format_local_dt(job['nextFire']) : '' },
|
93
|
+
"Last Result" => lambda {|job| format_status(job['lastResult']) },
|
94
|
+
}
|
95
|
+
print as_pretty_table(jobs, columns.upcase_keys!, options)
|
100
96
|
print_results_pagination(json_response)
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
97
|
+
if options[:show_stats]
|
98
|
+
if stats = json_response['stats']
|
99
|
+
label_width = 17
|
100
|
+
|
101
|
+
print_h2 "Execution Stats - Last 7 Days"
|
102
|
+
print cyan
|
103
|
+
|
104
|
+
print "Jobs".rjust(label_width, ' ') + ": #{stats['jobCount']}\n"
|
105
|
+
print "Executions Today".rjust(label_width, ' ') + ": #{stats['todayCount']}\n"
|
106
|
+
print "Daily Executions".rjust(label_width, ' ') + ": " + stats['executionsPerDay'].join(' | ') + "\n"
|
107
|
+
print "Total Executions".rjust(label_width, ' ') + ": #{stats['execCount']}\n"
|
108
|
+
print "Completed".rjust(label_width, ' ') + ": " + generate_usage_bar(stats['execSuccessRate'].to_f, 100, {bar_color:green}) + "#{stats['execSuccess']}".rjust(15, ' ') + " of " + "#{stats['execCount']}".ljust(15, ' ') + "\n#{cyan}"
|
109
|
+
print "Failed".rjust(label_width, ' ') + ": " + generate_usage_bar(stats['execFailedRate'].to_f, 100, {bar_color:red}) + "#{stats['execFailed']}".rjust(15, ' ') + " of " + "#{stats['execCount']}".ljust(15, ' ') + "\n#{cyan}"
|
110
|
+
end
|
111
|
+
print reset,"\n"
|
114
112
|
end
|
115
|
-
print reset,"\n"
|
116
113
|
end
|
117
114
|
print reset,"\n"
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
115
|
+
end
|
116
|
+
if jobs.empty?
|
117
|
+
return 1, "no jobs found"
|
118
|
+
else
|
119
|
+
return 0, nil
|
122
120
|
end
|
123
121
|
end
|
124
122
|
|
@@ -735,53 +733,57 @@ class Morpheus::Cli::JobsCommand
|
|
735
733
|
params = {}
|
736
734
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
737
735
|
opts.banner = subcommand_usage("[job]")
|
738
|
-
|
736
|
+
opts.on('--job JOB', String, "Filter by Job ID or name.") do |val|
|
737
|
+
options[:job] = val
|
738
|
+
end
|
739
|
+
opts.on("--internal [true|false]", String, "Filters executions based on internal flag. Internal executions are excluded by default.") do |val|
|
740
|
+
params["internalOnly"] = (val.to_s != "false")
|
741
|
+
end
|
742
|
+
build_standard_list_options(opts, options)
|
739
743
|
opts.footer = "List job executions.\n" +
|
740
744
|
"[job] is optional. Job ID or name to filter executions."
|
741
745
|
|
742
746
|
end
|
743
747
|
optparse.parse!(args)
|
744
748
|
connect(options)
|
745
|
-
|
746
|
-
|
747
|
-
|
749
|
+
# verify_args!(args:args, optparse:optparse, max:1)
|
750
|
+
if args.count > 0
|
751
|
+
options[:job] = args.join(" ")
|
748
752
|
end
|
749
753
|
|
750
|
-
|
751
|
-
params.merge!(parse_list_options(options))
|
752
|
-
|
753
|
-
if args.count > 0
|
754
|
-
job = find_by_name_or_id('job', args[0])
|
754
|
+
params.merge!(parse_list_options(options))
|
755
755
|
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
params['jobId'] = job['id']
|
761
|
-
end
|
762
|
-
|
763
|
-
@jobs_interface.setopts(options)
|
764
|
-
if options[:dry_run]
|
765
|
-
print_dry_run @jobs_interface.dry.list_executions(params)
|
766
|
-
return
|
756
|
+
if options[:job]
|
757
|
+
job = find_by_name_or_id('job', options[:job])
|
758
|
+
if job.nil?
|
759
|
+
raise_command_error "Job #{options[:job]} not found"
|
767
760
|
end
|
768
|
-
|
769
|
-
|
770
|
-
render_result = render_with_format(json_response, options, 'jobExecutions')
|
771
|
-
return 0 if render_result
|
761
|
+
params['jobId'] = job['id']
|
762
|
+
end
|
772
763
|
|
764
|
+
@jobs_interface.setopts(options)
|
765
|
+
if options[:dry_run]
|
766
|
+
print_dry_run @jobs_interface.dry.list_executions(params)
|
767
|
+
return
|
768
|
+
end
|
769
|
+
json_response = @jobs_interface.list_executions(params)
|
770
|
+
job_executions = json_response['jobExecutions']
|
771
|
+
render_response(json_response, options, 'jobExecutions') do
|
773
772
|
title = "Morpheus Job Executions"
|
774
773
|
subtitles = job ? ["Job: #{job['name']}"] : []
|
775
774
|
subtitles += parse_list_subtitles(options)
|
776
|
-
|
777
|
-
|
778
|
-
|
775
|
+
if params["internalOnly"]
|
776
|
+
subtitles << "internalOnly: #{params['internalOnly']}"
|
777
|
+
end
|
778
|
+
print_h1 title, subtitles, options
|
779
|
+
print_job_executions(job_executions, options)
|
779
780
|
print_results_pagination(json_response)
|
780
781
|
print reset,"\n"
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
782
|
+
end
|
783
|
+
if job_executions.empty?
|
784
|
+
return 3, "no executions found"
|
785
|
+
else
|
786
|
+
return 0, nil
|
785
787
|
end
|
786
788
|
end
|
787
789
|
|
@@ -812,7 +814,7 @@ class Morpheus::Cli::JobsCommand
|
|
812
814
|
end
|
813
815
|
json_response = @jobs_interface.get_execution(args[0], params)
|
814
816
|
|
815
|
-
render_result = render_with_format(json_response, options, '
|
817
|
+
render_result = render_with_format(json_response, options, 'jobExecution')
|
816
818
|
return 0 if render_result
|
817
819
|
|
818
820
|
title = "Morpheus Job Execution"
|
@@ -845,7 +847,7 @@ class Morpheus::Cli::JobsCommand
|
|
845
847
|
description_cols = {
|
846
848
|
"Process ID" => lambda {|it| it[:id]},
|
847
849
|
"Description" => lambda {|it| it[:description]},
|
848
|
-
"Start
|
850
|
+
"Start Date" => lambda {|it| it[:start_date]},
|
849
851
|
"Created By" => lambda {|it| it[:created_by]},
|
850
852
|
"Duration" => lambda {|it| it[:duration]},
|
851
853
|
"Status" => lambda {|it| it[:status]}
|
@@ -919,7 +921,7 @@ class Morpheus::Cli::JobsCommand
|
|
919
921
|
description_cols = {
|
920
922
|
"ID" => lambda {|it| it[:id]},
|
921
923
|
"Description" => lambda {|it| it[:description]},
|
922
|
-
"Start
|
924
|
+
"Start Date" => lambda {|it| it[:start_date]},
|
923
925
|
"Created By" => lambda {|it| it[:created_by]},
|
924
926
|
"Duration" => lambda {|it| it[:duration]},
|
925
927
|
"Status" => lambda {|it| it[:status]}
|
@@ -974,7 +976,7 @@ class Morpheus::Cli::JobsCommand
|
|
974
976
|
job: ex['job'] ? ex['job']['name'] : '',
|
975
977
|
description: ex['description'] || ex['job'] ? ex['job']['description'] : '',
|
976
978
|
type: ex['job'] && ex['job']['type'] ? (ex['job']['type']['code'] == 'morpheus.workflow' ? 'Workflow' : 'Task') : '',
|
977
|
-
|
979
|
+
start: format_local_dt(ex['startDate']),
|
978
980
|
duration: ex['duration'] ? format_human_duration(ex['duration'] / 1000.0) : '',
|
979
981
|
status: format_status(ex['status']),
|
980
982
|
error: truncate_string(ex['process'] && (ex['process']['message'] || ex['process']['error']) ? ex['process']['message'] || ex['process']['error'] : '', 32)
|
@@ -982,7 +984,7 @@ class Morpheus::Cli::JobsCommand
|
|
982
984
|
end
|
983
985
|
|
984
986
|
columns = [
|
985
|
-
:id, :job, :type, :
|
987
|
+
:id, :job, :type, {'START DATE' => :start}, {'ETA/TIME' => :duration}, :status, :error
|
986
988
|
]
|
987
989
|
print as_pretty_table(rows, columns, options)
|
988
990
|
print reset,"\n"
|