morpheus-cli 5.2.1 → 5.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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"
@@ -140,6 +140,7 @@ class Morpheus::Cli::LibraryOptionTypesCommand
140
140
  "Type" => lambda {|it| it['type'].to_s.capitalize },
141
141
  "Option List" => lambda {|it| it['optionList'] ? it['optionList']['name'] : nil },
142
142
  "Placeholder" => 'placeHolder',
143
+ "Help Block" => 'helpBlock',
143
144
  "Default Value" => 'defaultValue',
144
145
  "Required" => lambda {|it| format_boolean(it['required']) },
145
146
  "Export As Tag" => lambda {|it| it['exportMeta'].nil? ? '' : format_boolean(it['exportMeta']) },
@@ -297,9 +298,10 @@ class Morpheus::Cli::LibraryOptionTypesCommand
297
298
  {'fieldName' => 'optionList', 'fieldLabel' => 'Option List', 'type' => 'select', 'optionSource' => 'optionTypeLists', 'required' => true, 'dependsOnCode' => 'optionType.type:select', 'description' => "The Option List to be the source of options when type is 'select'.", 'displayOrder' => 5},
298
299
  {'fieldName' => 'fieldLabel', 'fieldLabel' => 'Field Label', 'type' => 'text', 'required' => true, 'description' => 'This is the input label that shows typically to the left of a custom option.', 'displayOrder' => 6},
299
300
  {'fieldName' => 'placeHolder', 'fieldLabel' => 'Placeholder', 'type' => 'text', 'displayOrder' => 7},
300
- {'fieldName' => 'defaultValue', 'fieldLabel' => 'Default Value', 'type' => 'text', 'displayOrder' => 8},
301
- {'fieldName' => 'required', 'fieldLabel' => 'Required', 'type' => 'checkbox', 'defaultValue' => false, 'displayOrder' => 9},
302
- {'fieldName' => 'exportMeta', 'fieldLabel' => 'Export As Tag', 'type' => 'checkbox', 'defaultValue' => false, 'description' => 'Export as Tag.', 'displayOrder' => 10},
301
+ {'fieldName' => 'helpBlock', 'fieldLabel' => 'Help Block', 'type' => 'text', 'description' => 'This is the explaination of the input that shows typically underneath the option.', 'displayOrder' => 8},
302
+ {'fieldName' => 'defaultValue', 'fieldLabel' => 'Default Value', 'type' => 'text', 'displayOrder' => 9},
303
+ {'fieldName' => 'required', 'fieldLabel' => 'Required', 'type' => 'checkbox', 'defaultValue' => false, 'displayOrder' => 10},
304
+ {'fieldName' => 'exportMeta', 'fieldLabel' => 'Export As Tag', 'type' => 'checkbox', 'defaultValue' => false, 'description' => 'Export as Tag.', 'displayOrder' => 11},
303
305
  ]
304
306
  end
305
307
 
@@ -448,7 +448,8 @@ module Morpheus::Cli::PrintHelper
448
448
 
449
449
  if opts[:bar_color] == :rainbow
450
450
  rainbow_bar = ""
451
- cur_rainbow_color = white
451
+ cur_rainbow_color = reset # default terminal color
452
+ rainbow_bar << cur_rainbow_color
452
453
  bars.each_with_index {|bar, i|
453
454
  reached_percent = (i / max_bars.to_f) * 100
454
455
  new_bar_color = cur_rainbow_color
@@ -458,6 +459,8 @@ module Morpheus::Cli::PrintHelper
458
459
  new_bar_color = yellow
459
460
  elsif reached_percent > 10
460
461
  new_bar_color = cyan
462
+ else
463
+ new_bar_color = reset
461
464
  end
462
465
  if cur_rainbow_color != new_bar_color
463
466
  cur_rainbow_color = new_bar_color
@@ -471,7 +474,7 @@ module Morpheus::Cli::PrintHelper
471
474
  #rainbow_bar << " " * padding
472
475
  end
473
476
  rainbow_bar << reset
474
- bar_display = white + "[" + rainbow_bar + white + "]" + " #{cur_rainbow_color}#{percent_label}#{reset}"
477
+ bar_display = cyan + "[" + rainbow_bar + cyan + "]" + " #{cur_rainbow_color}#{percent_label}#{reset}"
475
478
  out << bar_display
476
479
  elsif opts[:bar_color] == :solid
477
480
  bar_color = cyan
@@ -479,12 +482,16 @@ module Morpheus::Cli::PrintHelper
479
482
  bar_color = red
480
483
  elsif percent > 50
481
484
  bar_color = yellow
485
+ elsif percent > 10
486
+ bar_color = cyan
487
+ else
488
+ bar_color = reset
482
489
  end
483
- bar_display = white + "[" + bar_color + bars.join.ljust(max_bars, ' ') + white + "]" + " #{percent_label}" + reset
490
+ bar_display = cyan + "[" + bar_color + bars.join.ljust(max_bars, ' ') + cyan + "]" + " #{percent_label}" + reset
484
491
  out << bar_display
485
492
  else
486
- bar_color = opts[:bar_color] || cyan
487
- bar_display = white + "[" + bar_color + bars.join.ljust(max_bars, ' ') + white + "]" + " #{percent_label}" + reset
493
+ bar_color = opts[:bar_color] || reset
494
+ bar_display = cyan + "[" + bar_color + bars.join.ljust(max_bars, ' ') + cyan + "]" + " #{percent_label}" + reset
488
495
  out << bar_display
489
496
  end
490
497
  return out
@@ -504,7 +511,7 @@ module Morpheus::Cli::PrintHelper
504
511
  out << cyan + "Max CPU".rjust(label_width, ' ') + ": " + generate_usage_bar(cpu_usage.to_f, 100) + "\n"
505
512
  end
506
513
  if opts[:include].include?(:avg_cpu)
507
- cpu_usage = stats['cpuUsageAvg']
514
+ cpu_usage = stats['cpuUsageAvg'] || stats['cpuUsageAverage']
508
515
  out << cyan + "Avg. CPU".rjust(label_width, ' ') + ": " + generate_usage_bar(cpu_usage.to_f, 100) + "\n"
509
516
  end
510
517
  if opts[:include].include?(:cpu)
@@ -1,6 +1,6 @@
1
1
 
2
2
  module Morpheus
3
3
  module Cli
4
- VERSION = "5.2.1"
4
+ VERSION = "5.2.2"
5
5
  end
6
6
  end
@@ -15,11 +15,7 @@ def parse_time(dt, format=nil)
15
15
  elsif dt.is_a?(String)
16
16
  result = nil
17
17
  err = nil
18
- begin
19
- result = Time.parse(dt)
20
- rescue => e
21
- err = e
22
- end
18
+
23
19
  if !result
24
20
  format ||= DEFAULT_TIME_FORMAT
25
21
  if format
@@ -29,12 +25,26 @@ def parse_time(dt, format=nil)
29
25
  err = e
30
26
  end
31
27
  end
32
- if !result
33
- begin
34
- result = Time.strptime(dt, ALTERNATE_TIME_FORMAT)
35
- rescue => e
36
- err = e
37
- end
28
+ end
29
+ if !result
30
+ begin
31
+ result = Time.strptime(dt, ALTERNATE_TIME_FORMAT)
32
+ rescue => e
33
+ # err = e
34
+ end
35
+ end
36
+ if !result
37
+ begin
38
+ result = Time.strptime(dt, DEFAULT_DATE_FORMAT)
39
+ rescue => e
40
+ # err = e
41
+ end
42
+ end
43
+ if !result
44
+ begin
45
+ result = Time.parse(dt)
46
+ rescue => e
47
+ err = e
38
48
  end
39
49
  end
40
50
  if result
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: morpheus-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.2.1
4
+ version: 5.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Estes
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2020-11-18 00:00:00.000000000 Z
14
+ date: 2020-12-15 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler