morpheus-cli 5.2.1 → 5.3.0

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.
@@ -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)
@@ -713,6 +720,7 @@ module Morpheus::Cli::PrintHelper
713
720
  columns.each do |column_def|
714
721
  # r << column_def.display_method.respond_to?(:call) ? column_def.display_method.call(row_data) : get_object_value(row_data, column_def.display_method)
715
722
  value = column_def.display_method.call(row_data)
723
+ value = JSON.fast_generate(value) if value.is_a?(Hash) || value.is_a?(Array)
716
724
  row << value
717
725
  end
718
726
  rows << row
@@ -795,6 +803,7 @@ module Morpheus::Cli::PrintHelper
795
803
  columns.each do |column_def|
796
804
  # r << column_def.display_method.respond_to?(:call) ? column_def.display_method.call(row_data) : get_object_value(row_data, column_def.display_method)
797
805
  value = column_def.display_method.call(row_data)
806
+ value = JSON.fast_generate(value) if value.is_a?(Hash) || value.is_a?(Array)
798
807
  row << value
799
808
  end
800
809
  rows << row
@@ -872,6 +881,7 @@ module Morpheus::Cli::PrintHelper
872
881
  label = label.upcase if ALL_LABELS_UPCASE
873
882
  # value = get_object_value(obj, column_def.display_method)
874
883
  value = column_def.display_method.call(obj)
884
+ value = JSON.fast_generate(value) if value.is_a?(Hash) || value.is_a?(Array)
875
885
  if label.size > max_label_width
876
886
  max_label_width = label.size
877
887
  end
@@ -42,7 +42,7 @@ class Morpheus::Cli::Projects
42
42
  opts.on('--owners [LIST]', Array, "Owner, comma separated list of usernames or IDs.") do |list|
43
43
  owner_ids = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
44
44
  end
45
- build_standard_get_options(opts, options)
45
+ build_standard_list_options(opts, options)
46
46
  opts.footer = <<-EOT
47
47
  List projects.
48
48
  EOT
@@ -1276,7 +1276,8 @@ EOT
1276
1276
 
1277
1277
  def format_remote_details(appliance, options={})
1278
1278
  columns = {
1279
- "Name" => :name,
1279
+ #"Name" => :name,
1280
+ "Name" => lambda {|it| it[:name].to_s },
1280
1281
  #"Name" => lambda {|it| it[:active] ? "#{it[:name]} #{bold}(current)#{reset}#{cyan}" : it[:name] },
1281
1282
  "URL" => lambda {|it| it[:url] || it[:host] },
1282
1283
  #"Status" => lambda {|it| format_appliance_status(it, cyan) },
@@ -6,6 +6,7 @@ class Morpheus::Cli::UserSourcesCommand
6
6
  include Morpheus::Cli::AccountsHelper
7
7
 
8
8
  set_command_name :'user-sources'
9
+ set_command_description "View and manage user identity sources"
9
10
 
10
11
  register_subcommands :list, :get, :add, :update, :remove
11
12
  register_subcommands :activate, :deactivate
@@ -43,49 +44,32 @@ class Morpheus::Cli::UserSourcesCommand
43
44
  account_id = val
44
45
  end
45
46
  opts.add_hidden_option('-a, --account') if opts.is_a?(Morpheus::Cli::OptionParser)
46
- # opts.on('--technology VALUE', String, "Filter by technology") do |val|
47
- # params['provisionType'] = val
48
- # end
49
- build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run, :remote])
50
- opts.footer = "List user sources."
47
+ build_standard_list_options(opts, options)
48
+ opts.footer = "List identity sources."
51
49
  end
52
50
  optparse.parse!(args)
53
51
  connect(options)
54
- # instance is required right now.
55
- # account_id = args[0] if !account_id
52
+ # verify_args!(args:args, optparse:optparse, count:0)
56
53
  if args.count > 0
57
- print_error Morpheus::Terminal.angry_prompt
58
- puts_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args.inspect}\n#{optparse}"
59
- return 1
54
+ options[:phrase] = args.join(" ")
60
55
  end
61
- begin
62
- # construct payload
63
- if account_id
64
- account = find_account_by_name_or_id(account_id)
65
- return 1 if account.nil?
66
- account_id = account['id']
67
- end
68
-
69
- params.merge!(parse_list_options(options))
70
- @user_sources_interface.setopts(options)
71
- if options[:dry_run]
72
- print_dry_run @user_sources_interface.dry.list(account_id, params)
73
- return
74
- end
75
-
76
- json_response = @user_sources_interface.list(account_id, params)
77
- if options[:json]
78
- puts as_json(json_response, options, "userSources")
79
- return 0
80
- elsif options[:csv]
81
- puts records_as_csv(json_response['userSources'], options)
82
- return 0
83
- elsif options[:yaml]
84
- puts as_yaml(json_response, options, "userSources")
85
- return 0
56
+ if account_id
57
+ account = find_account_by_name_or_id(account_id)
58
+ if account.nil?
59
+ return 1, "Tenant not found for '#{account_id}'"
86
60
  end
87
- user_sources = json_response['userSources']
88
- title = "Morpheus User Sources"
61
+ account_id = account['id']
62
+ end
63
+ params.merge!(parse_list_options(options))
64
+ @user_sources_interface.setopts(options)
65
+ if options[:dry_run]
66
+ print_dry_run @user_sources_interface.dry.list(account_id, params)
67
+ return 0, nil
68
+ end
69
+ json_response = @user_sources_interface.list(account_id, params)
70
+ render_response(json_response, options, "userSources") do
71
+ user_sources = json_response["userSources"]
72
+ title = "Morpheus Identity Sources"
89
73
  subtitles = []
90
74
  if account
91
75
  subtitles << "Tenant: #{account['name']}".strip
@@ -93,82 +77,77 @@ class Morpheus::Cli::UserSourcesCommand
93
77
  subtitles += parse_list_subtitles(options)
94
78
  print_h1 title, subtitles
95
79
  if user_sources.empty?
96
- if account
97
- print cyan,"No user sources found for account #{account['name']}.",reset,"\n"
98
- else
99
- print cyan,"No user sources found.",reset,"\n"
100
- end
80
+ print cyan,"No identity sources found.",reset,"\n"
101
81
  else
102
82
  print_user_sources_table(user_sources, options)
103
- print_results_pagination(json_response, {:label => "user source", :n_label => "user sources"})
83
+ print_results_pagination(json_response)
104
84
  end
105
85
  print reset,"\n"
106
- rescue RestClient::Exception => e
107
- print_rest_exception(e, options)
108
- return 1
109
86
  end
87
+ return 0, nil
88
+
110
89
  end
111
90
 
112
91
  def get(args)
113
- options = {}
114
92
  params = {}
93
+ options = {}
115
94
  optparse = Morpheus::Cli::OptionParser.new do |opts|
116
95
  opts.banner = subcommand_usage("[name]")
117
- build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
118
- opts.footer = "Get details about an user source." + "\n" +
119
- "[name] is required. This is the name or id of an user source."
96
+ # opts.on( '-c', '--config', "Display raw config only. Default is YAML. Combine with -j for JSON instead." ) do
97
+ # options[:show_config] = true
98
+ # end
99
+ # opts.on('--no-config', "Do not display Config YAML." ) do
100
+ # options[:no_config] = true
101
+ # end
102
+ build_standard_get_options(opts, options)
103
+ opts.footer = <<-EOT
104
+ Get details about an identity source.
105
+ [name] is required. This is the name or id of an identity source.
106
+ EOT
120
107
  end
121
108
  optparse.parse!(args)
109
+ verify_args!(args:args, optparse:optparse, min:1)
122
110
  connect(options)
123
- if args.count != 1
124
- print_error Morpheus::Terminal.angry_prompt
125
- puts_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args.inspect}\n#{optparse}"
126
- return 1
111
+ id_list = parse_id_list(args)
112
+ return run_command_for_each_arg(id_list) do |arg|
113
+ _get(arg, params, options)
127
114
  end
115
+ end
116
+
117
+ def _get(user_source_id, params, options)
128
118
  account_id = nil
129
119
  account = nil
130
- user_source_id = args[0]
131
120
  # account_id = args[0]
132
121
  # account = find_account_by_name_or_id(account_id)
133
122
  # exit 1 if account.nil?
134
123
  # account_id = account['id']
135
124
  # user_source_id = args[1]
136
- begin
137
- @user_sources_interface.setopts(options)
138
- if options[:dry_run]
139
- if user_source_id.to_s =~ /\A\d{1,}\Z/
140
- print_dry_run @user_sources_interface.dry.get(account_id, user_source_id.to_i)
141
- else
142
- print_dry_run @user_sources_interface.dry.list(account_id, {name:user_source_id})
143
- end
144
- return
145
- end
146
- user_source = find_user_source_by_name_or_id(account_id, user_source_id)
147
- if user_source.nil?
148
- return 1
149
- end
150
- # fetch by id to get config too
151
- json_response = nil
125
+
126
+ @user_sources_interface.setopts(options)
127
+ if options[:dry_run]
152
128
  if user_source_id.to_s =~ /\A\d{1,}\Z/
153
- json_response = {'userSource' => user_source}
129
+ print_dry_run @user_sources_interface.dry.get(account_id, user_source_id.to_i)
154
130
  else
155
- json_response = @user_sources_interface.get(account_id, user_source['id'])
156
- user_source = json_response['userSource']
131
+ print_dry_run @user_sources_interface.dry.list(account_id, {name:user_source_id})
157
132
  end
133
+ return
134
+ end
135
+ user_source = find_user_source_by_name_or_id(account_id, user_source_id)
136
+ if user_source.nil?
137
+ return 1
138
+ end
139
+ # fetch by id to get config too
140
+ json_response = nil
141
+ if user_source_id.to_s =~ /\A\d{1,}\Z/
142
+ json_response = {'userSource' => user_source}
143
+ else
144
+ json_response = @user_sources_interface.get(account_id, user_source['id'])
145
+ user_source = json_response['userSource']
146
+ end
158
147
 
159
- #user_source = json_response['userSource']
160
- if options[:json]
161
- puts as_json(json_response, options, "userSource")
162
- return 0
163
- elsif options[:yaml]
164
- puts as_yaml(json_response, options, "userSource")
165
- return 0
166
- elsif options[:csv]
167
- puts records_as_csv([json_response['userSource']], options)
168
- return 0
169
- end
170
-
171
- print_h1 "User Source Details"
148
+ #user_source = json_response['userSource']
149
+ render_response(json_response, options, "userSource") do
150
+ print_h1 "Identity Source Details"
172
151
  print cyan
173
152
  description_cols = {
174
153
  "ID" => lambda {|it| it['id'] },
@@ -187,7 +166,7 @@ class Morpheus::Cli::UserSourcesCommand
187
166
 
188
167
  # show config settings...
189
168
  user_source_config = user_source['config']
190
- print_h2 "User Source Config (#{user_source['type']})"
169
+ print_h2 "Configuration"
191
170
  if user_source_config
192
171
  columns = user_source_config.keys #.sort
193
172
  print_description_list(columns, user_source_config)
@@ -208,15 +187,27 @@ class Morpheus::Cli::UserSourcesCommand
208
187
  {"SOURCE ROLE FQN" => lambda {|it| it['sourceRoleFqn'] } },
209
188
  ]
210
189
  print as_pretty_table(role_mappings, role_mapping_columns)
190
+ else
191
+ print cyan,"No role mappings found for this identity source.","\n",reset
192
+ end
193
+
194
+ provider_settings = user_source['providerSettings']
195
+ if provider_settings && !provider_settings.empty?
196
+ print_h2 "Provider Settings"
197
+ print_description_list({
198
+ "Entity ID" => lambda {|it| it['entityId'] },
199
+ "ACS URL" => lambda {|it| it['acsUrl'] }
200
+ }, provider_settings)
201
+ print_h2 "SP Metadata"
202
+ print cyan
203
+ print provider_settings['spMetadata']
211
204
  print "\n",reset
212
205
  else
213
- print cyan,"No role mappings found for this user source.","\n",reset
206
+ # print cyan,"No provider settings found.","\n",reset
214
207
  end
215
- return 0
216
- rescue RestClient::Exception => e
217
- print_rest_exception(e, options)
218
- return 1
208
+ print "\n",reset
219
209
  end
210
+ return 0, nil
220
211
  end
221
212
 
222
213
  def add(args)
@@ -229,17 +220,17 @@ class Morpheus::Cli::UserSourcesCommand
229
220
  default_role_id = nil
230
221
  optparse = Morpheus::Cli::OptionParser.new do|opts|
231
222
  opts.banner = subcommand_usage("[account] [name]")
232
- opts.on( '--tenant TENANT', String, "Tenant Name or ID the user source will belong to, default is your own." ) do |val|
223
+ opts.on( '--tenant TENANT', String, "Tenant Name or ID the identity source will belong to, default is your own." ) do |val|
233
224
  account_id = val
234
225
  end
235
- opts.on( '-a', '--account ACCOUNT', "Tenant Name or ID the user source will belong to, default is your own." ) do |val|
226
+ opts.on( '-a', '--account ACCOUNT', "Tenant Name or ID the identity source will belong to, default is your own." ) do |val|
236
227
  account_id = val
237
228
  end
238
229
  opts.add_hidden_option('-a, --account') if opts.is_a?(Morpheus::Cli::OptionParser)
239
- opts.on('--type CODE', String, "User Source Type") do |val|
230
+ opts.on('--type CODE', String, "Identity Source Type") do |val|
240
231
  type_code = val
241
232
  end
242
- opts.on('--name VALUE', String, "Name for this user source") do |val|
233
+ opts.on('--name VALUE', String, "Name for this identity source") do |val|
243
234
  params['name'] = val
244
235
  end
245
236
  opts.on('--description VALUE', String, "Description") do |val|
@@ -276,7 +267,7 @@ class Morpheus::Cli::UserSourcesCommand
276
267
  end
277
268
  #build_option_type_options(opts, options, add_user_source_option_types())
278
269
  build_standard_add_options(opts, options)
279
- opts.footer = "Create a new user source." + "\n" +
270
+ opts.footer = "Create a new identity source." + "\n" +
280
271
  "[account] is required. This is the name or id of an account."
281
272
  end
282
273
  optparse.parse!(args)
@@ -313,10 +304,10 @@ class Morpheus::Cli::UserSourcesCommand
313
304
  else
314
305
  payload.deep_merge!({'userSource' => parse_passed_options(options)})
315
306
 
316
- # User Source Type
307
+ # Identity Source Type
317
308
  user_source_types = @user_sources_interface.list_types({userSelectable: true})['userSourceTypes']
318
309
  if user_source_types.empty?
319
- print_red_alert "No available User Source Types found"
310
+ print_red_alert "No available Identity Source Types found"
320
311
  return 1
321
312
  end
322
313
  user_source_type = nil
@@ -328,7 +319,7 @@ class Morpheus::Cli::UserSourcesCommand
328
319
  user_source_type = user_source_types.find { |it| it['type'] == type_code }
329
320
 
330
321
  if user_source_type.nil?
331
- print_red_alert "User Source Type not found for '#{type_code}'"
322
+ print_red_alert "Identity Source Type not found for '#{type_code}'"
332
323
  return 1
333
324
  end
334
325
 
@@ -393,7 +384,7 @@ class Morpheus::Cli::UserSourcesCommand
393
384
  return 0
394
385
  end
395
386
  user_source = json_response['userSource']
396
- print_green_success "Added User Source #{user_source['name']}"
387
+ print_green_success "Added Identity Source #{user_source['name']}"
397
388
  get([user_source['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
398
389
  return 0
399
390
  end
@@ -406,7 +397,7 @@ class Morpheus::Cli::UserSourcesCommand
406
397
  role_mapping_names = nil
407
398
  optparse = Morpheus::Cli::OptionParser.new do|opts|
408
399
  opts.banner = subcommand_usage("[name] [options]")
409
- opts.on('--name VALUE', String, "Name for this user source") do |val|
400
+ opts.on('--name VALUE', String, "Name for this identity source") do |val|
410
401
  params['name'] = val
411
402
  end
412
403
  opts.on('--description VALUE', String, "Description") do |val|
@@ -438,8 +429,8 @@ class Morpheus::Cli::UserSourcesCommand
438
429
  end
439
430
  end
440
431
  build_standard_update_options(opts, options)
441
- opts.footer = "Update a user source." + "\n" +
442
- "[name] is required. This is the name or id of a user source."
432
+ opts.footer = "Update an identity source." + "\n" +
433
+ "[name] is required. This is the name or id of an identity source."
443
434
  end
444
435
  optparse.parse!(args)
445
436
  if args.count < 1
@@ -494,7 +485,7 @@ class Morpheus::Cli::UserSourcesCommand
494
485
  return
495
486
  end
496
487
 
497
- print_green_success "Updated User Source #{params['name'] || user_source['name']}"
488
+ print_green_success "Updated Identity Source #{params['name'] || user_source['name']}"
498
489
  get([user_source['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
499
490
  rescue RestClient::Exception => e
500
491
  print_rest_exception(e, options)
@@ -511,8 +502,8 @@ class Morpheus::Cli::UserSourcesCommand
511
502
  optparse = Morpheus::Cli::OptionParser.new do|opts|
512
503
  opts.banner = subcommand_usage("[name]")
513
504
  build_common_options(opts, options, [:options, :json, :dry_run, :remote])
514
- opts.footer = "Activate a user source." + "\n" +
515
- "[name] is required. This is the name or id of a user source."
505
+ opts.footer = "Activate an identity source." + "\n" +
506
+ "[name] is required. This is the name or id of an identity source."
516
507
  end
517
508
  optparse.parse!(args)
518
509
  if args.count < 1
@@ -544,7 +535,7 @@ class Morpheus::Cli::UserSourcesCommand
544
535
  return
545
536
  end
546
537
 
547
- print_green_success "Activated User Source #{user_source['name']}"
538
+ print_green_success "Activated Identity Source #{user_source['name']}"
548
539
  get([user_source['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
549
540
  rescue RestClient::Exception => e
550
541
  print_rest_exception(e, options)
@@ -561,8 +552,8 @@ class Morpheus::Cli::UserSourcesCommand
561
552
  optparse = Morpheus::Cli::OptionParser.new do|opts|
562
553
  opts.banner = subcommand_usage("[name]")
563
554
  build_common_options(opts, options, [:options, :json, :dry_run, :remote])
564
- opts.footer = "Deactivate a user source." + "\n" +
565
- "[name] is required. This is the name or id of a user source."
555
+ opts.footer = "Deactivate an identity source." + "\n" +
556
+ "[name] is required. This is the name or id of an identity source."
566
557
  end
567
558
  optparse.parse!(args)
568
559
  if args.count < 1
@@ -594,7 +585,7 @@ class Morpheus::Cli::UserSourcesCommand
594
585
  return
595
586
  end
596
587
 
597
- print_green_success "Activated User Source #{user_source['name']}"
588
+ print_green_success "Activated Identity Source #{user_source['name']}"
598
589
  get([user_source['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
599
590
  rescue RestClient::Exception => e
600
591
  print_rest_exception(e, options)
@@ -608,12 +599,12 @@ class Morpheus::Cli::UserSourcesCommand
608
599
  account_id = nil
609
600
  optparse = Morpheus::Cli::OptionParser.new do|opts|
610
601
  opts.banner = subcommand_usage("[name]")
611
- opts.on('--subdomain VALUE', String, "New subdomain for this user source") do |val|
602
+ opts.on('--subdomain VALUE', String, "New subdomain for this identity source") do |val|
612
603
  params['subdomain'] = (val == 'null') ? nil : val
613
604
  end
614
605
  build_common_options(opts, options, [:options, :json, :dry_run, :remote])
615
- opts.footer = "Update subdomain for a user source." + "\n" +
616
- "[name] is required. This is the name or id of a user source."
606
+ opts.footer = "Update subdomain for an identity source." + "\n" +
607
+ "[name] is required. This is the name or id of an identity source."
617
608
  end
618
609
  optparse.parse!(args)
619
610
  if args.count < 1
@@ -645,8 +636,8 @@ class Morpheus::Cli::UserSourcesCommand
645
636
  puts JSON.pretty_generate(json_response)
646
637
  return
647
638
  end
648
- # JD: uhh this updates the account too, it cannot be set per user source ...yet
649
- print_green_success "Updated User Source #{user_source['name']} subdomain to '#{payload['subdomain']}'"
639
+ # JD: uhh this updates the account too, it cannot be set per identity source ...yet
640
+ print_green_success "Updated Identity Source #{user_source['name']} subdomain to '#{payload['subdomain']}'"
650
641
  get([user_source['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
651
642
  rescue RestClient::Exception => e
652
643
  print_rest_exception(e, options)
@@ -672,7 +663,7 @@ class Morpheus::Cli::UserSourcesCommand
672
663
  user_source = find_user_source_by_name_or_id(nil, args[0])
673
664
  exit 1 if user_source.nil?
674
665
 
675
- unless Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the user source #{user_source['name']}?", options)
666
+ unless Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the identity source #{user_source['name']}?", options)
676
667
  exit
677
668
  end
678
669
  @user_sources_interface.setopts(options)
@@ -687,7 +678,7 @@ class Morpheus::Cli::UserSourcesCommand
687
678
  return
688
679
  end
689
680
 
690
- print_green_success "Removed User Source #{user_source['name']}"
681
+ print_green_success "Removed Identity Source #{user_source['name']}"
691
682
  #list([])
692
683
  rescue RestClient::Exception => e
693
684
  print_rest_exception(e, options)
@@ -703,7 +694,7 @@ class Morpheus::Cli::UserSourcesCommand
703
694
  optparse = Morpheus::Cli::OptionParser.new do |opts|
704
695
  opts.banner = subcommand_usage()
705
696
  build_common_options(opts, options, [:list, :json, :yaml, :csv, :fields, :dry_run, :remote])
706
- opts.footer = "List user source types."
697
+ opts.footer = "List identity source types."
707
698
  end
708
699
  optparse.parse!(args)
709
700
  connect(options)
@@ -735,7 +726,7 @@ class Morpheus::Cli::UserSourcesCommand
735
726
  return 0
736
727
  end
737
728
  user_source_types = json_response['userSourceTypes']
738
- title = "Morpheus User Source Types"
729
+ title = "Morpheus Identity Source Types"
739
730
  subtitles = []
740
731
  subtitles += parse_list_subtitles(options)
741
732
  print_h1 title, subtitles
@@ -760,7 +751,7 @@ class Morpheus::Cli::UserSourcesCommand
760
751
  optparse = Morpheus::Cli::OptionParser.new do |opts|
761
752
  opts.banner = subcommand_usage("[type]")
762
753
  build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
763
- opts.footer = "Get details about a user source type." + "\n" +
754
+ opts.footer = "Get details about an identity source type." + "\n" +
764
755
  "[type] is required. This is the type identifier."
765
756
  end
766
757
  optparse.parse!(args)
@@ -776,13 +767,6 @@ class Morpheus::Cli::UserSourcesCommand
776
767
  begin
777
768
  user_source_type_id = args[0]
778
769
 
779
- # all_user_source_types = @user_sources_interface.dry.list_types({})['userSourceTypes']
780
- # user_source_type = all_user_source_types.find {|it| it['type'] == user_source_type_id }
781
- # if !user_source_type
782
- # print_red_alert "User Source Type not found by id '#{user_source_type_id}'"
783
- # return 1
784
- # end
785
-
786
770
  # construct payload
787
771
  @user_sources_interface.setopts(options)
788
772
  if options[:dry_run]
@@ -801,7 +785,7 @@ class Morpheus::Cli::UserSourcesCommand
801
785
  puts records_as_csv([user_source_type], options)
802
786
  return 0
803
787
  end
804
- title = "User Source Type"
788
+ title = "Identity Source Type"
805
789
  subtitles = []
806
790
  print_h1 title, subtitles
807
791
  print cyan
@@ -860,7 +844,7 @@ class Morpheus::Cli::UserSourcesCommand
860
844
  return json_response['userSource']
861
845
  rescue RestClient::Exception => e
862
846
  if e.response && e.response.code == 404
863
- print_red_alert "User Source not found by id #{id}"
847
+ print_red_alert "Identity Source not found by id #{id}"
864
848
  else
865
849
  raise e
866
850
  end
@@ -870,10 +854,10 @@ class Morpheus::Cli::UserSourcesCommand
870
854
  def find_user_source_by_name(account_id, name)
871
855
  user_sources = @user_sources_interface.list(account_id, {name: name.to_s})['userSources']
872
856
  if user_sources.empty?
873
- print_red_alert "User Source not found by name #{name}"
857
+ print_red_alert "Identity Source not found by name #{name}"
874
858
  return nil
875
859
  elsif user_sources.size > 1
876
- print_red_alert "#{user_sources.size} user sources found by name #{name}"
860
+ print_red_alert "#{user_sources.size} identity sources found by name #{name}"
877
861
  print_user_sources_table(user_sources, {color: red})
878
862
  print_red_alert "Try using ID instead"
879
863
  print reset,"\n"
@@ -979,7 +963,7 @@ class Morpheus::Cli::UserSourcesCommand
979
963
  {'fieldContext' => 'config', 'fieldName' => 'encryptionKey', 'type' => 'text', 'fieldLabel' => 'Encryption Key', 'required' => true, 'description' => ''},
980
964
  ]
981
965
  else
982
- print "unknown user source type: #{type_code}"
966
+ print "unknown identity source type: #{type_code}"
983
967
  []
984
968
  end
985
969
  end