morpheus-cli 5.0.2 → 5.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/Dockerfile +1 -1
  4. data/lib/morpheus/api/api_client.rb +4 -0
  5. data/lib/morpheus/api/instances_interface.rb +30 -2
  6. data/lib/morpheus/api/invoices_interface.rb +12 -3
  7. data/lib/morpheus/api/servers_interface.rb +7 -0
  8. data/lib/morpheus/api/service_catalog_interface.rb +89 -0
  9. data/lib/morpheus/cli.rb +2 -1
  10. data/lib/morpheus/cli/apps.rb +3 -23
  11. data/lib/morpheus/cli/budgets_command.rb +389 -319
  12. data/lib/morpheus/cli/{catalog_command.rb → catalog_item_types_command.rb} +182 -67
  13. data/lib/morpheus/cli/cli_command.rb +25 -1
  14. data/lib/morpheus/cli/commands/standard/curl_command.rb +25 -10
  15. data/lib/morpheus/cli/commands/standard/history_command.rb +6 -2
  16. data/lib/morpheus/cli/containers_command.rb +0 -24
  17. data/lib/morpheus/cli/cypher_command.rb +6 -2
  18. data/lib/morpheus/cli/dashboard_command.rb +260 -20
  19. data/lib/morpheus/cli/health_command.rb +57 -0
  20. data/lib/morpheus/cli/hosts.rb +128 -11
  21. data/lib/morpheus/cli/instances.rb +270 -108
  22. data/lib/morpheus/cli/invoices_command.rb +67 -4
  23. data/lib/morpheus/cli/jobs_command.rb +94 -92
  24. data/lib/morpheus/cli/library_option_lists_command.rb +1 -1
  25. data/lib/morpheus/cli/library_option_types_command.rb +10 -5
  26. data/lib/morpheus/cli/mixins/accounts_helper.rb +5 -1
  27. data/lib/morpheus/cli/mixins/print_helper.rb +13 -6
  28. data/lib/morpheus/cli/mixins/provisioning_helper.rb +88 -5
  29. data/lib/morpheus/cli/option_types.rb +10 -10
  30. data/lib/morpheus/cli/projects_command.rb +1 -1
  31. data/lib/morpheus/cli/roles.rb +193 -155
  32. data/lib/morpheus/cli/service_catalog_command.rb +1474 -0
  33. data/lib/morpheus/cli/tasks.rb +9 -11
  34. data/lib/morpheus/cli/version.rb +1 -1
  35. data/lib/morpheus/cli/virtual_images.rb +162 -68
  36. data/lib/morpheus/formatters.rb +55 -20
  37. metadata +5 -4
  38. data/lib/morpheus/cli/mixins/catalog_helper.rb +0 -66
@@ -8,7 +8,7 @@ class Morpheus::Cli::InvoicesCommand
8
8
 
9
9
  set_command_name :'invoices'
10
10
 
11
- register_subcommands :list, :get, :refresh,
11
+ register_subcommands :list, :get, :update, :refresh,
12
12
  :list_line_items, :get_line_item
13
13
 
14
14
  def connect(opts)
@@ -272,7 +272,7 @@ class Morpheus::Cli::InvoicesCommand
272
272
  {"ESTIMATE" => lambda {|it| format_boolean(it['estimate']) } },
273
273
  {"ACTIVE" => lambda {|it| format_boolean(it['active']) } },
274
274
  {"ITEMS" => lambda {|it| it['lineItems'].size rescue '' } },
275
- {"TAGS" => lambda {|it| it['metadata'] ? it['metadata'].collect {|m| "#{m['name']}: #{m['value']}" }.join(', ') : '' } },
275
+ {"TAGS" => lambda {|it| (it['metadata'] || it['tags']) ? (it['metadata'] || it['tags']).collect {|m| "#{m['name']}: #{m['value']}" }.join(', ') : '' } },
276
276
  ]
277
277
  if show_projects
278
278
  columns += [
@@ -438,7 +438,7 @@ EOT
438
438
  "Ref Start" => lambda {|it| format_dt(it['refStart']) },
439
439
  "Ref End" => lambda {|it| format_dt(it['refEnd']) },
440
440
  "Items" => lambda {|it| it['lineItems'].size rescue '' },
441
- "Tags" => lambda {|it| it['metadata'] ? it['metadata'].collect {|m| "#{m['name']}: #{m['value']}" }.join(', ') : '' },
441
+ "Tags" => lambda {|it| (it['metadata'] || it['tags']) ? (it['metadata'] || it['tags']).collect {|m| "#{m['name']}: #{m['value']}" }.join(', ') : '' },
442
442
  "Project ID" => lambda {|it| it['project'] ? it['project']['id'] : '' },
443
443
  "Project Name" => lambda {|it| it['project'] ? it['project']['name'] : '' },
444
444
  "Project Tags" => lambda {|it| it['project'] ? format_metadata(it['project']['tags']) : '' },
@@ -454,7 +454,8 @@ EOT
454
454
  description_cols.delete("Project Name")
455
455
  description_cols.delete("Project Tags")
456
456
  end
457
- if invoice['metadata'].nil? || invoice['metadata'].empty?
457
+ tags = (invoice['metadata'] || invoice['tags'])
458
+ if tags.nil? || tags.empty?
458
459
  description_cols.delete("Tags")
459
460
  end
460
461
  if !['ComputeServer','Instance','Container'].include?(invoice['refType'])
@@ -590,6 +591,68 @@ EOT
590
591
  end
591
592
  end
592
593
 
594
+ def update(args)
595
+ options = {}
596
+ params = {}
597
+ payload = {}
598
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
599
+ opts.banner = subcommand_usage("[invoice] [options]")
600
+ opts.on('--tags LIST', String, "Tags in the format 'name:value, name:value'. This will add and remove tags.") do |val|
601
+ options[:tags] = val
602
+ end
603
+ opts.on('--add-tags TAGS', String, "Add Tags in the format 'name:value, name:value'. This will only add/update tags.") do |val|
604
+ options[:add_tags] = val
605
+ end
606
+ opts.on('--remove-tags TAGS', String, "Remove Tags in the format 'name, name:value'. This removes tags, the :value component is optional and must match if passed.") do |val|
607
+ options[:remove_tags] = val
608
+ end
609
+ build_standard_update_options(opts, options)
610
+ opts.footer = <<-EOT
611
+ Update an invoice.
612
+ [invoice] is required. This is the id of an invoice.
613
+ EOT
614
+ end
615
+ optparse.parse!(args)
616
+ verify_args!(args:args, optparse:optparse, count:1)
617
+ connect(options)
618
+ json_response = @invoices_interface.get(args[0])
619
+ invoice = json_response['invoice']
620
+
621
+ invoice_payload = parse_passed_options(options)
622
+ if options[:tags]
623
+ invoice_payload['tags'] = parse_metadata(options[:tags])
624
+ end
625
+ if options[:add_tags]
626
+ invoice_payload['addTags'] = parse_metadata(options[:add_tags])
627
+ end
628
+ if options[:remove_tags]
629
+ invoice_payload['removeTags'] = parse_metadata(options[:remove_tags])
630
+ end
631
+
632
+ payload = {}
633
+ if options[:payload]
634
+ payload = options[:payload]
635
+ payload.deep_merge!({'invoice' => invoice_payload})
636
+ else
637
+ payload.deep_merge!({'invoice' => invoice_payload})
638
+ if invoice_payload.empty?
639
+ raise_command_error "Specify at least one option to update.\n#{optparse}"
640
+ end
641
+ end
642
+ @invoices_interface.setopts(options)
643
+ if options[:dry_run]
644
+ print_dry_run @invoices_interface.dry.update(invoice['id'], payload)
645
+ return
646
+ end
647
+ json_response = @invoices_interface.update(invoice['id'], payload)
648
+ invoice = json_response['invoice']
649
+ render_response(json_response, options, 'invoice') do
650
+ print_green_success "Updated invoice #{invoice['id']}"
651
+ return _get(invoice["id"], options)
652
+ end
653
+ return 0, nil
654
+ end
655
+
593
656
  def refresh(args)
594
657
  options = {}
595
658
  params = {}
@@ -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"
@@ -270,7 +270,7 @@ class Morpheus::Cli::LibraryOptionListsCommand
270
270
  else
271
271
  payload = {}
272
272
  payload.deep_merge!({'optionTypeList' => parse_passed_options(options)})
273
- list_payload = Morpheus::Cli::OptionTypes.no_prompt(update_option_type_option_types(), options[:options], @api_client)
273
+ list_payload = Morpheus::Cli::OptionTypes.no_prompt(update_option_type_list_option_types(), options[:options], @api_client)
274
274
  if list_payload['type'] == 'rest'
275
275
  # parse Source Headers
276
276
  if !(payload['optionTypeList']['config'] && payload['optionTypeList']['config']['sourceHeaders'])
@@ -129,7 +129,7 @@ class Morpheus::Cli::LibraryOptionTypesCommand
129
129
 
130
130
  print_h1 "Option Type Details"
131
131
  print cyan
132
- print_description_list({
132
+ columns = {
133
133
  "ID" => 'id',
134
134
  "Name" => 'name',
135
135
  "Description" => 'description',
@@ -138,11 +138,15 @@ class Morpheus::Cli::LibraryOptionTypesCommand
138
138
  # "Field Name" => 'fieldName',
139
139
  "Full Field Name" => lambda {|it| [it['fieldContext'], it['fieldName']].select {|it| !it.to_s.empty? }.join('.') },
140
140
  "Type" => lambda {|it| it['type'].to_s.capitalize },
141
+ "Option List" => lambda {|it| it['optionList'] ? it['optionList']['name'] : nil },
141
142
  "Placeholder" => 'placeHolder',
143
+ "Help Block" => 'helpBlock',
142
144
  "Default Value" => 'defaultValue',
143
145
  "Required" => lambda {|it| format_boolean(it['required']) },
144
146
  "Export As Tag" => lambda {|it| it['exportMeta'].nil? ? '' : format_boolean(it['exportMeta']) },
145
- }, option_type)
147
+ }
148
+ columns.delete("Option List") if option_type['optionList'].nil?
149
+ print as_description_list(option_type, columns, options)
146
150
  print reset,"\n"
147
151
  return 0
148
152
  rescue RestClient::Exception => e
@@ -294,9 +298,10 @@ class Morpheus::Cli::LibraryOptionTypesCommand
294
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},
295
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},
296
300
  {'fieldName' => 'placeHolder', 'fieldLabel' => 'Placeholder', 'type' => 'text', 'displayOrder' => 7},
297
- {'fieldName' => 'defaultValue', 'fieldLabel' => 'Default Value', 'type' => 'text', 'displayOrder' => 8},
298
- {'fieldName' => 'required', 'fieldLabel' => 'Required', 'type' => 'checkbox', 'defaultValue' => false, 'displayOrder' => 9},
299
- {'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},
300
305
  ]
301
306
  end
302
307
 
@@ -401,7 +401,7 @@ module Morpheus::Cli::AccountsHelper
401
401
  end
402
402
 
403
403
  def get_access_string(access, return_color=cyan)
404
- get_access_color(access) + access + return_color
404
+ get_access_color(access) + access.to_s + return_color.to_s
405
405
  # access ||= 'none'
406
406
  # if access == 'none'
407
407
  # "#{white}#{access.to_s}#{return_color}"
@@ -426,10 +426,14 @@ module Morpheus::Cli::AccountsHelper
426
426
  # Examples: format_permission_access("read")
427
427
  # format_permission_access("custom", "full,custom,none")
428
428
  def format_access_string(access, access_levels=nil, return_color=cyan)
429
+ # nevermind all this, just colorized access level
430
+ return get_access_string(access, return_color)
431
+
429
432
  access = access.to_s.downcase.strip
430
433
  if access.empty?
431
434
  access = "none"
432
435
  end
436
+
433
437
  if access_levels.nil?
434
438
  access_levels = ["none","read","user","full"]
435
439
  elsif access_levels.is_a?(Array)