morpheus-cli 5.2.1 → 5.3.0

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)
@@ -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