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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/Dockerfile +1 -1
  4. data/lib/morpheus/api/api_client.rb +16 -0
  5. data/lib/morpheus/api/billing_interface.rb +1 -0
  6. data/lib/morpheus/api/deploy_interface.rb +1 -1
  7. data/lib/morpheus/api/deployments_interface.rb +20 -1
  8. data/lib/morpheus/api/forgot_password_interface.rb +17 -0
  9. data/lib/morpheus/api/instances_interface.rb +16 -2
  10. data/lib/morpheus/api/invoices_interface.rb +12 -3
  11. data/lib/morpheus/api/search_interface.rb +13 -0
  12. data/lib/morpheus/api/servers_interface.rb +14 -0
  13. data/lib/morpheus/api/service_catalog_interface.rb +89 -0
  14. data/lib/morpheus/api/usage_interface.rb +18 -0
  15. data/lib/morpheus/cli.rb +6 -2
  16. data/lib/morpheus/cli/apps.rb +3 -23
  17. data/lib/morpheus/cli/budgets_command.rb +389 -319
  18. data/lib/morpheus/cli/{catalog_command.rb → catalog_item_types_command.rb} +182 -67
  19. data/lib/morpheus/cli/cli_command.rb +51 -10
  20. data/lib/morpheus/cli/commands/standard/curl_command.rb +26 -13
  21. data/lib/morpheus/cli/commands/standard/history_command.rb +9 -3
  22. data/lib/morpheus/cli/commands/standard/man_command.rb +74 -40
  23. data/lib/morpheus/cli/containers_command.rb +0 -24
  24. data/lib/morpheus/cli/cypher_command.rb +6 -2
  25. data/lib/morpheus/cli/dashboard_command.rb +260 -20
  26. data/lib/morpheus/cli/deploy.rb +199 -90
  27. data/lib/morpheus/cli/deployments.rb +341 -28
  28. data/lib/morpheus/cli/deploys.rb +206 -41
  29. data/lib/morpheus/cli/error_handler.rb +7 -0
  30. data/lib/morpheus/cli/forgot_password.rb +133 -0
  31. data/lib/morpheus/cli/groups.rb +1 -1
  32. data/lib/morpheus/cli/health_command.rb +59 -2
  33. data/lib/morpheus/cli/hosts.rb +271 -39
  34. data/lib/morpheus/cli/instances.rb +228 -129
  35. data/lib/morpheus/cli/invoices_command.rb +100 -20
  36. data/lib/morpheus/cli/jobs_command.rb +94 -92
  37. data/lib/morpheus/cli/library_option_lists_command.rb +1 -1
  38. data/lib/morpheus/cli/library_option_types_command.rb +10 -5
  39. data/lib/morpheus/cli/logs_command.rb +9 -6
  40. data/lib/morpheus/cli/mixins/accounts_helper.rb +5 -1
  41. data/lib/morpheus/cli/mixins/deployments_helper.rb +31 -2
  42. data/lib/morpheus/cli/mixins/print_helper.rb +13 -27
  43. data/lib/morpheus/cli/mixins/provisioning_helper.rb +108 -5
  44. data/lib/morpheus/cli/option_types.rb +271 -22
  45. data/lib/morpheus/cli/remote.rb +35 -10
  46. data/lib/morpheus/cli/reports_command.rb +99 -30
  47. data/lib/morpheus/cli/roles.rb +193 -155
  48. data/lib/morpheus/cli/search_command.rb +182 -0
  49. data/lib/morpheus/cli/service_catalog_command.rb +1474 -0
  50. data/lib/morpheus/cli/setup.rb +1 -1
  51. data/lib/morpheus/cli/shell.rb +33 -11
  52. data/lib/morpheus/cli/tasks.rb +29 -32
  53. data/lib/morpheus/cli/usage_command.rb +64 -11
  54. data/lib/morpheus/cli/version.rb +1 -1
  55. data/lib/morpheus/cli/virtual_images.rb +429 -254
  56. data/lib/morpheus/cli/whoami.rb +6 -6
  57. data/lib/morpheus/cli/workflows.rb +33 -40
  58. data/lib/morpheus/formatters.rb +75 -18
  59. data/lib/morpheus/terminal.rb +6 -2
  60. metadata +10 -4
  61. 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
- k,v = val.split("=")
111
- query_tags[k] ||= []
112
- query_tags[k] << v
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 query_tags && !query_tags.empty?
173
- query_tags.each do |k,v|
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
- if invoice['metadata'].nil? || invoice['metadata'].empty?
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
- # opts.on('--tags Name=Value',String, "Filter by tags.") do |val|
748
- # k,v = val.split("=")
749
- # query_tags[k] ||= []
750
- # query_tags[k] << v
751
- # end
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 query_tags && !query_tags.empty?
812
- query_tags.each do |k,v|
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
- build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run, :remote])
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
- if !options[:source].nil?
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
- @jobs_interface.setopts(options)
62
- if options[:dry_run]
63
- print_dry_run @jobs_interface.dry.list(params)
64
- return
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
- json_response = @jobs_interface.list(params)
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
- rows = jobs.collect do |job|
85
- {
86
- id: job['id'],
87
- type: job['type'] ? job['type']['name'] : '',
88
- name: job['name'],
89
- details: job['jobSummary'],
90
- enabled: "#{job['enabled'] ? '' : yellow}#{format_boolean(job['enabled'])}#{cyan}",
91
- lastRun: format_local_dt(job['lastRun']),
92
- nextRun: job['enabled'] && job['scheduleMode'] && job['scheduleMode'] != 'manual' ? format_local_dt(job['nextFire']) : '',
93
- lastResult: format_status(job['lastResult'])
94
- }
95
- end
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
- if stats = json_response['stats']
103
- label_width = 17
104
-
105
- print_h2 "Execution Stats - Last 7 Days"
106
- print cyan
107
-
108
- print "Jobs".rjust(label_width, ' ') + ": #{stats['jobCount']}\n"
109
- print "Executions Today".rjust(label_width, ' ') + ": #{stats['todayCount']}\n"
110
- print "Daily Executions".rjust(label_width, ' ') + ": " + stats['executionsPerDay'].join(' | ') + "\n"
111
- print "Total Executions".rjust(label_width, ' ') + ": #{stats['execCount']}\n"
112
- 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}"
113
- 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}"
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
- return 0
119
- rescue RestClient::Exception => e
120
- print_rest_exception(e, options)
121
- exit 1
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
- build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run, :remote])
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
- if args.count > 1
746
- raise_command_error "wrong number of arguments, expected 0..1 and got (#{args.count}) #{args}\n#{optparse}"
747
- return 1
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
- begin
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
- if job.nil?
757
- print_red_alert "Job #{args[0]} not found"
758
- exit 1
759
- end
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
- json_response = @jobs_interface.list_executions(params)
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
- print_h1 title, subtitles
777
-
778
- print_job_executions(json_response['jobExecutions'], options)
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
- return 0
782
- rescue RestClient::Exception => e
783
- print_rest_exception(e, options)
784
- exit 1
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, 'job')
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 Data" => lambda {|it| it[:start_date]},
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 Data" => lambda {|it| it[:start_date]},
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
- startDate: format_local_dt(ex['startDate']),
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, :startDate, {'ETA/TIME' => :duration}, :status, :error
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"