morpheus-cli 5.5.0 → 5.5.1
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.
- checksums.yaml +4 -4
 - data/Dockerfile +1 -1
 - data/lib/morpheus/api/api_client.rb +4 -0
 - data/lib/morpheus/api/clusters_interface.rb +12 -0
 - data/lib/morpheus/api/network_pool_servers_interface.rb +7 -0
 - data/lib/morpheus/api/scale_thresholds_interface.rb +9 -0
 - data/lib/morpheus/cli/cli_command.rb +39 -20
 - data/lib/morpheus/cli/commands/apps.rb +1 -1
 - data/lib/morpheus/cli/commands/cloud_resource_pools_command.rb +33 -2
 - data/lib/morpheus/cli/commands/clouds.rb +12 -6
 - data/lib/morpheus/cli/commands/clusters.rb +66 -5
 - data/lib/morpheus/cli/commands/hosts.rb +5 -1
 - data/lib/morpheus/cli/commands/instances.rb +1 -1
 - data/lib/morpheus/cli/commands/integrations_command.rb +1 -1
 - data/lib/morpheus/cli/commands/invoices_command.rb +8 -1
 - data/lib/morpheus/cli/commands/jobs_command.rb +45 -225
 - data/lib/morpheus/cli/commands/library_container_types_command.rb +52 -3
 - data/lib/morpheus/cli/commands/library_option_types_command.rb +56 -62
 - data/lib/morpheus/cli/commands/load_balancers.rb +11 -19
 - data/lib/morpheus/cli/commands/network_pool_servers_command.rb +5 -2
 - data/lib/morpheus/cli/commands/roles.rb +475 -70
 - data/lib/morpheus/cli/commands/scale_thresholds.rb +103 -0
 - data/lib/morpheus/cli/commands/tasks.rb +19 -12
 - data/lib/morpheus/cli/commands/user_sources_command.rb +107 -39
 - data/lib/morpheus/cli/commands/users.rb +10 -10
 - data/lib/morpheus/cli/commands/view.rb +1 -0
 - data/lib/morpheus/cli/commands/workflows.rb +21 -14
 - data/lib/morpheus/cli/error_handler.rb +13 -4
 - data/lib/morpheus/cli/mixins/accounts_helper.rb +1 -1
 - data/lib/morpheus/cli/mixins/execution_request_helper.rb +1 -1
 - data/lib/morpheus/cli/mixins/infrastructure_helper.rb +3 -3
 - data/lib/morpheus/cli/mixins/jobs_helper.rb +173 -0
 - data/lib/morpheus/cli/mixins/print_helper.rb +120 -38
 - data/lib/morpheus/cli/mixins/provisioning_helper.rb +1 -3
 - data/lib/morpheus/cli/mixins/rest_command.rb +41 -14
 - data/lib/morpheus/cli/option_types.rb +68 -37
 - data/lib/morpheus/cli/version.rb +1 -1
 - data/lib/morpheus/logging.rb +6 -8
 - metadata +6 -4
 
| 
         @@ -0,0 +1,173 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'morpheus/cli/mixins/print_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
            # Mixin for Morpheus::Cli command classes
         
     | 
| 
      
 3 
     | 
    
         
            +
            # Provides refreshing job execution records by id
         
     | 
| 
      
 4 
     | 
    
         
            +
            module Morpheus::Cli::JobsHelper
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              def self.included(klass)
         
     | 
| 
      
 7 
     | 
    
         
            +
                klass.send :include, Morpheus::Cli::PrintHelper
         
     | 
| 
      
 8 
     | 
    
         
            +
                # klass.send :include, Morpheus::Cli::ProcessesHelper
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              def api_client
         
     | 
| 
      
 12 
     | 
    
         
            +
                raise "#{self.class} has not defined @api_client" if @api_client.nil?
         
     | 
| 
      
 13 
     | 
    
         
            +
                @api_client
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              def jobs_interface
         
     | 
| 
      
 17 
     | 
    
         
            +
                # get_interface('jobs')
         
     | 
| 
      
 18 
     | 
    
         
            +
                api_client.jobs
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
              def get_process_event_data(process_or_event)
         
     | 
| 
      
 22 
     | 
    
         
            +
                {
         
     | 
| 
      
 23 
     | 
    
         
            +
                    id: process_or_event['id'],
         
     | 
| 
      
 24 
     | 
    
         
            +
                    description: process_or_event['description'] || (process_or_event['refType'] == 'instance' ? process_or_event['displayName'] : (process_or_event['processTypeName'] || '').capitalize),
         
     | 
| 
      
 25 
     | 
    
         
            +
                    start_date: format_local_dt(process_or_event['startDate']),
         
     | 
| 
      
 26 
     | 
    
         
            +
                    created_by: process_or_event['createdBy'] ? process_or_event['createdBy']['displayName'] : '',
         
     | 
| 
      
 27 
     | 
    
         
            +
                    duration: format_human_duration((process_or_event['duration'] || process_or_event['statusEta'] || 0) / 1000.0),
         
     | 
| 
      
 28 
     | 
    
         
            +
                    status: format_job_status(process_or_event['status']),
         
     | 
| 
      
 29 
     | 
    
         
            +
                    error: process_or_event['message'] || process_or_event['error'],
         
     | 
| 
      
 30 
     | 
    
         
            +
                    output: process_or_event['output'],
         
     | 
| 
      
 31 
     | 
    
         
            +
                }
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
              # both process and process events
         
     | 
| 
      
 35 
     | 
    
         
            +
              def print_process_events(events, options={})
         
     | 
| 
      
 36 
     | 
    
         
            +
                # event_columns = [:id, :description, :start_date, :created_by, :duration, :status, :error, :output]
         
     | 
| 
      
 37 
     | 
    
         
            +
                event_columns = {
         
     | 
| 
      
 38 
     | 
    
         
            +
                      "ID" => lambda {|it| it[:id]},
         
     | 
| 
      
 39 
     | 
    
         
            +
                      "Description" => lambda {|it| it[:description]},
         
     | 
| 
      
 40 
     | 
    
         
            +
                      "Start Date" => lambda {|it| it[:start_date]},
         
     | 
| 
      
 41 
     | 
    
         
            +
                      "Created By" => lambda {|it| it[:created_by]},
         
     | 
| 
      
 42 
     | 
    
         
            +
                      "Duration" => lambda {|it| it[:duration]},
         
     | 
| 
      
 43 
     | 
    
         
            +
                      "Status" => lambda {|it| it[:status]},
         
     | 
| 
      
 44 
     | 
    
         
            +
                      "Error" => lambda {|it| options[:details] ? it[:error] : truncate_string(it[:error], 32) },
         
     | 
| 
      
 45 
     | 
    
         
            +
                      "Output" => lambda {|it| options[:details] ? it[:output] : truncate_string(it[:output], 32) }
         
     | 
| 
      
 46 
     | 
    
         
            +
                  }
         
     | 
| 
      
 47 
     | 
    
         
            +
                print as_pretty_table(events.collect {|it| get_process_event_data(it)}, event_columns.upcase_keys!, options)
         
     | 
| 
      
 48 
     | 
    
         
            +
              end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
              def print_job_execution(job_execution, options)
         
     | 
| 
      
 51 
     | 
    
         
            +
                process = job_execution['process']
         
     | 
| 
      
 52 
     | 
    
         
            +
                print cyan
         
     | 
| 
      
 53 
     | 
    
         
            +
                description_cols = {
         
     | 
| 
      
 54 
     | 
    
         
            +
                    "ID" => lambda {|it| it['id'] },
         
     | 
| 
      
 55 
     | 
    
         
            +
                    "Job" => lambda {|it| it['job'] ? it['job']['name'] : ''},
         
     | 
| 
      
 56 
     | 
    
         
            +
                    "Job Type" => lambda {|it| it['job'] && it['job']['type'] ? (it['job']['type']['code'] == 'morpheus.workflow' ? 'Workflow' : 'Task') : ''},
         
     | 
| 
      
 57 
     | 
    
         
            +
                    # "Description" => lambda {|it| it['description'] || (it['job'] ? it['job']['description'] : '') },
         
     | 
| 
      
 58 
     | 
    
         
            +
                    "Start Date" => lambda {|it| format_local_dt(it['startDate'])},
         
     | 
| 
      
 59 
     | 
    
         
            +
                    "ETA/Time" => lambda {|it| it['duration'] ? format_human_duration(it['duration'] / 1000.0) : ''},
         
     | 
| 
      
 60 
     | 
    
         
            +
                    "Status" => lambda {|it| format_job_status(it['status'])},
         
     | 
| 
      
 61 
     | 
    
         
            +
                    #"Output" => lambda {|it| it['process'] && (it['process']['output']) ?(it['process']['output']).to_s.strip : ''},
         
     | 
| 
      
 62 
     | 
    
         
            +
                    #"Error" => lambda {|it| it['process'] && (it['process']['message'] || it['process']['error']) ? red + (it['process']['message'] || it['process']['error']).to_s.strip + cyan : ''},
         
     | 
| 
      
 63 
     | 
    
         
            +
                    "Created By" => lambda {|it| it['createdBy'].nil? ? '' : it['createdBy']['displayName'] || it['createdBy']['username']}
         
     | 
| 
      
 64 
     | 
    
         
            +
                }
         
     | 
| 
      
 65 
     | 
    
         
            +
                print_description_list(description_cols, job_execution, options)
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                if process
         
     | 
| 
      
 68 
     | 
    
         
            +
                  process_data = get_process_event_data(process)
         
     | 
| 
      
 69 
     | 
    
         
            +
                  print_h2 "Process Details"
         
     | 
| 
      
 70 
     | 
    
         
            +
                  process_description_cols = {
         
     | 
| 
      
 71 
     | 
    
         
            +
                      "Process ID" => lambda {|it| it[:id]},
         
     | 
| 
      
 72 
     | 
    
         
            +
                      "Description" => lambda {|it| it[:description]},
         
     | 
| 
      
 73 
     | 
    
         
            +
                      "Start Date" => lambda {|it| it[:start_date]},
         
     | 
| 
      
 74 
     | 
    
         
            +
                      "Created By" => lambda {|it| it[:created_by]},
         
     | 
| 
      
 75 
     | 
    
         
            +
                      "Duration" => lambda {|it| it[:duration]},
         
     | 
| 
      
 76 
     | 
    
         
            +
                      "Status" => lambda {|it| it[:status]}
         
     | 
| 
      
 77 
     | 
    
         
            +
                  }
         
     | 
| 
      
 78 
     | 
    
         
            +
                  print_description_list(process_description_cols, process_data, options)
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                  if process_data[:output] && process_data[:output].strip.length > 0
         
     | 
| 
      
 81 
     | 
    
         
            +
                    print_h2 "Output"
         
     | 
| 
      
 82 
     | 
    
         
            +
                    print process['output']
         
     | 
| 
      
 83 
     | 
    
         
            +
                  end
         
     | 
| 
      
 84 
     | 
    
         
            +
                  if process_data[:error] && process_data[:error].strip.length > 0
         
     | 
| 
      
 85 
     | 
    
         
            +
                    print_h2 "Error"
         
     | 
| 
      
 86 
     | 
    
         
            +
                    print process['message'] || process['error']
         
     | 
| 
      
 87 
     | 
    
         
            +
                    print reset,"\n"
         
     | 
| 
      
 88 
     | 
    
         
            +
                  end
         
     | 
| 
      
 89 
     | 
    
         
            +
                  
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
                  if process['events'] && !process['events'].empty?
         
     | 
| 
      
 92 
     | 
    
         
            +
                    print_h2 "Process Events", options
         
     | 
| 
      
 93 
     | 
    
         
            +
                    print_process_events(process['events'], options)
         
     | 
| 
      
 94 
     | 
    
         
            +
                  end
         
     | 
| 
      
 95 
     | 
    
         
            +
                else
         
     | 
| 
      
 96 
     | 
    
         
            +
                  print reset,"\n"
         
     | 
| 
      
 97 
     | 
    
         
            +
                end
         
     | 
| 
      
 98 
     | 
    
         
            +
                return 0, nil
         
     | 
| 
      
 99 
     | 
    
         
            +
              end
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
              def print_job_executions(execs, options={})
         
     | 
| 
      
 102 
     | 
    
         
            +
                if execs.empty?
         
     | 
| 
      
 103 
     | 
    
         
            +
                  print cyan,"No job executions found.",reset,"\n"
         
     | 
| 
      
 104 
     | 
    
         
            +
                else
         
     | 
| 
      
 105 
     | 
    
         
            +
                  rows = execs.collect do |ex|
         
     | 
| 
      
 106 
     | 
    
         
            +
                    {
         
     | 
| 
      
 107 
     | 
    
         
            +
                        id: ex['id'],
         
     | 
| 
      
 108 
     | 
    
         
            +
                        job: ex['job'] ? ex['job']['name'] : '',
         
     | 
| 
      
 109 
     | 
    
         
            +
                        description: ex['description'] || ex['job'] ? ex['job']['description'] : '',
         
     | 
| 
      
 110 
     | 
    
         
            +
                        type: ex['job'] && ex['job']['type'] ? (ex['job']['type']['code'] == 'morpheus.workflow' ? 'Workflow' : 'Task') : '',
         
     | 
| 
      
 111 
     | 
    
         
            +
                        start: format_local_dt(ex['startDate']),
         
     | 
| 
      
 112 
     | 
    
         
            +
                        duration: ex['duration'] ? format_human_duration(ex['duration'] / 1000.0) : '',
         
     | 
| 
      
 113 
     | 
    
         
            +
                        status: format_job_status(ex['status']),
         
     | 
| 
      
 114 
     | 
    
         
            +
                        error: truncate_string(ex['process'] && (ex['process']['message'] || ex['process']['error']) ? ex['process']['message'] || ex['process']['error'] : '', options[:details] ? nil : 32),
         
     | 
| 
      
 115 
     | 
    
         
            +
                        output: truncate_string(ex['process'] && ex['process']['output'] ? ex['process']['output'] : '', options[:details] ? nil : 32),
         
     | 
| 
      
 116 
     | 
    
         
            +
                    }
         
     | 
| 
      
 117 
     | 
    
         
            +
                  end
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
                  columns = [
         
     | 
| 
      
 120 
     | 
    
         
            +
                      :id, :job, :type, {'START DATE' => :start}, {'ETA/TIME' => :duration}, :status, :error, :output
         
     | 
| 
      
 121 
     | 
    
         
            +
                  ]
         
     | 
| 
      
 122 
     | 
    
         
            +
                  print as_pretty_table(rows, columns, options)
         
     | 
| 
      
 123 
     | 
    
         
            +
                end
         
     | 
| 
      
 124 
     | 
    
         
            +
              end
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
              def format_job_status(status_string, return_color=cyan)
         
     | 
| 
      
 127 
     | 
    
         
            +
                out = ""
         
     | 
| 
      
 128 
     | 
    
         
            +
                if status_string
         
     | 
| 
      
 129 
     | 
    
         
            +
                  if ['complete','success', 'successful', 'ok'].include?(status_string)
         
     | 
| 
      
 130 
     | 
    
         
            +
                    out << "#{green}#{status_string.upcase}"
         
     | 
| 
      
 131 
     | 
    
         
            +
                  elsif ['error', 'offline', 'failed', 'failure'].include?(status_string)
         
     | 
| 
      
 132 
     | 
    
         
            +
                    out << "#{red}#{status_string.upcase}"
         
     | 
| 
      
 133 
     | 
    
         
            +
                  else
         
     | 
| 
      
 134 
     | 
    
         
            +
                    out << "#{yellow}#{status_string.upcase}"
         
     | 
| 
      
 135 
     | 
    
         
            +
                  end
         
     | 
| 
      
 136 
     | 
    
         
            +
                end
         
     | 
| 
      
 137 
     | 
    
         
            +
                out + return_color
         
     | 
| 
      
 138 
     | 
    
         
            +
              end
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
      
 140 
     | 
    
         
            +
              # this is built into CliCommand now...
         
     | 
| 
      
 141 
     | 
    
         
            +
              # def find_by_name_or_id(type, val)
         
     | 
| 
      
 142 
     | 
    
         
            +
              #   interface = instance_variable_get "@#{type}s_interface"
         
     | 
| 
      
 143 
     | 
    
         
            +
              #   typeCamelCase = type.gsub(/(?:^|_)([a-z])/) do $1.upcase end
         
     | 
| 
      
 144 
     | 
    
         
            +
              #   typeCamelCase = typeCamelCase[0, 1].downcase + typeCamelCase[1..-1]
         
     | 
| 
      
 145 
     | 
    
         
            +
              #   (val.to_s =~ /\A\d{1,}\Z/) ? interface.get(val.to_i)[typeCamelCase] : interface.list({'name' => val})["#{typeCamelCase}s"].first
         
     | 
| 
      
 146 
     | 
    
         
            +
              # end
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
              # refresh execution request until it is finished
         
     | 
| 
      
 149 
     | 
    
         
            +
              # returns json response data of the last execution request when status reached 'completed' or 'failed'
         
     | 
| 
      
 150 
     | 
    
         
            +
              def wait_for_job_execution(job_execution_id, options={}, print_output = true)
         
     | 
| 
      
 151 
     | 
    
         
            +
                refresh_interval = 10
         
     | 
| 
      
 152 
     | 
    
         
            +
                if options[:refresh_interval].to_i > 0
         
     | 
| 
      
 153 
     | 
    
         
            +
                  refresh_interval = options[:refresh_interval]
         
     | 
| 
      
 154 
     | 
    
         
            +
                end
         
     | 
| 
      
 155 
     | 
    
         
            +
                refresh_display_seconds = refresh_interval % 1.0 == 0 ? refresh_interval.to_i : refresh_interval
         
     | 
| 
      
 156 
     | 
    
         
            +
                unless options[:quiet]
         
     | 
| 
      
 157 
     | 
    
         
            +
                  print cyan, "Refreshing every #{refresh_display_seconds} seconds until execution is complete...", "\n", reset
         
     | 
| 
      
 158 
     | 
    
         
            +
                end
         
     | 
| 
      
 159 
     | 
    
         
            +
                job_execution = jobs_interface.get_execution(job_execution_id)['jobExecution']
         
     | 
| 
      
 160 
     | 
    
         
            +
                while ['new','queued','pending','running'].include?(job_execution['status']) do
         
     | 
| 
      
 161 
     | 
    
         
            +
                  sleep(refresh_interval)
         
     | 
| 
      
 162 
     | 
    
         
            +
                  job_execution = jobs_interface.get_execution(job_execution_id)['jobExecution']
         
     | 
| 
      
 163 
     | 
    
         
            +
                end
         
     | 
| 
      
 164 
     | 
    
         
            +
                if print_output && options[:quiet] != true
         
     | 
| 
      
 165 
     | 
    
         
            +
                  print_h1 "Morpheus Job Execution", [], options
         
     | 
| 
      
 166 
     | 
    
         
            +
                  print_job_execution(job_execution, options)
         
     | 
| 
      
 167 
     | 
    
         
            +
                end
         
     | 
| 
      
 168 
     | 
    
         
            +
                return job_execution
         
     | 
| 
      
 169 
     | 
    
         
            +
              end
         
     | 
| 
      
 170 
     | 
    
         
            +
             
     | 
| 
      
 171 
     | 
    
         
            +
             
     | 
| 
      
 172 
     | 
    
         
            +
             
     | 
| 
      
 173 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -608,6 +608,9 @@ module Morpheus::Cli::PrintHelper 
     | 
|
| 
       608 
608 
     | 
    
         
             
              # @param suffix [String] the character to pad right side with. Default is '...'
         
     | 
| 
       609 
609 
     | 
    
         
             
              def truncate_string(value, width, suffix="...")
         
     | 
| 
       610 
610 
     | 
    
         
             
                value = value.to_s
         
     | 
| 
      
 611 
     | 
    
         
            +
                if !width
         
     | 
| 
      
 612 
     | 
    
         
            +
                  return value
         
     | 
| 
      
 613 
     | 
    
         
            +
                end
         
     | 
| 
       611 
614 
     | 
    
         
             
                # JD: hack alerty.. this sux, but it's a best effort to preserve values containing ascii coloring codes
         
     | 
| 
       612 
615 
     | 
    
         
             
                #     it stops working when there are words separated by ascii codes, eg. two diff colors
         
     | 
| 
       613 
616 
     | 
    
         
             
                #     plus this is probably pretty slow...
         
     | 
| 
         @@ -714,7 +717,11 @@ module Morpheus::Cli::PrintHelper 
     | 
|
| 
       714 
717 
     | 
    
         | 
| 
       715 
718 
     | 
    
         
             
                # support --fields x,y,z and --all-fields or --fields all
         
     | 
| 
       716 
719 
     | 
    
         
             
                all_fields = data.first ? data.first.keys : []
         
     | 
| 
       717 
     | 
    
         
            -
                
         
     | 
| 
      
 720 
     | 
    
         
            +
                #todo: support --raw-fields   meh, not really needed..
         
     | 
| 
      
 721 
     | 
    
         
            +
                # if options[:include_fields] && options[:raw_fields]
         
     | 
| 
      
 722 
     | 
    
         
            +
                #   data = transform_data_for_field_options(data, options)
         
     | 
| 
      
 723 
     | 
    
         
            +
                #   data = data[options[:include_fields_context]] if options[:include_fields_context]
         
     | 
| 
      
 724 
     | 
    
         
            +
                # elsif options[:include_fields]
         
     | 
| 
       718 
725 
     | 
    
         
             
                if options[:include_fields]
         
     | 
| 
       719 
726 
     | 
    
         
             
                  if (options[:include_fields].is_a?(Array) && options[:include_fields].size == 1 && options[:include_fields][0] == 'all') || options[:include_fields] == 'all'
         
     | 
| 
       720 
727 
     | 
    
         
             
                    columns = all_fields
         
     | 
| 
         @@ -1093,16 +1100,78 @@ module Morpheus::Cli::PrintHelper 
     | 
|
| 
       1093 
1100 
     | 
    
         
             
                '"' + v.to_s.gsub('"', '""') + '"'
         
     | 
| 
       1094 
1101 
     | 
    
         
             
              end
         
     | 
| 
       1095 
1102 
     | 
    
         | 
| 
       1096 
     | 
    
         
            -
              def as_csv(data,  
     | 
| 
      
 1103 
     | 
    
         
            +
              def as_csv(data, default_columns=nil, options={}, object_key=nil)
         
     | 
| 
       1097 
1104 
     | 
    
         
             
                out = ""
         
     | 
| 
       1098 
1105 
     | 
    
         
             
                delim = options[:csv_delim] || options[:delim] || ","
         
     | 
| 
       1099 
1106 
     | 
    
         
             
                newline = options[:csv_newline] || options[:newline] || "\n"
         
     | 
| 
       1100 
1107 
     | 
    
         
             
                include_header = options[:csv_no_header] ? false : true
         
     | 
| 
       1101 
1108 
     | 
    
         
             
                do_quotes = options[:csv_quotes] || options[:quotes]
         
     | 
| 
       1102 
1109 
     | 
    
         | 
| 
      
 1110 
     | 
    
         
            +
                if options[:include_fields]
         
     | 
| 
      
 1111 
     | 
    
         
            +
                  data = transform_data_for_field_options(data, options, object_key)
         
     | 
| 
      
 1112 
     | 
    
         
            +
                  if data.is_a?(Hash)
         
     | 
| 
      
 1113 
     | 
    
         
            +
                    if options[:raw_fields]
         
     | 
| 
      
 1114 
     | 
    
         
            +
                      if options[:include_fields_context]
         
     | 
| 
      
 1115 
     | 
    
         
            +
                        data = data[options[:include_fields_context]]
         
     | 
| 
      
 1116 
     | 
    
         
            +
                      else
         
     | 
| 
      
 1117 
     | 
    
         
            +
                        # todo: could use a dynamic object_key, first Array or Hash in the data, can probably always do this...
         
     | 
| 
      
 1118 
     | 
    
         
            +
                        # if object_key.nil?
         
     | 
| 
      
 1119 
     | 
    
         
            +
                        #   object_key = data.keys.find {|k| data[k].is_a?(Array) || data[k].is_a?(Hash) }
         
     | 
| 
      
 1120 
     | 
    
         
            +
                        # end
         
     | 
| 
      
 1121 
     | 
    
         
            +
                        # if object_key && data[object_key]
         
     | 
| 
      
 1122 
     | 
    
         
            +
                        #   data = data[object_key]
         
     | 
| 
      
 1123 
     | 
    
         
            +
                        # end
         
     | 
| 
      
 1124 
     | 
    
         
            +
                      end
         
     | 
| 
      
 1125 
     | 
    
         
            +
                    else
         
     | 
| 
      
 1126 
     | 
    
         
            +
                      if object_key
         
     | 
| 
      
 1127 
     | 
    
         
            +
                        data = data[object_key]
         
     | 
| 
      
 1128 
     | 
    
         
            +
                      end
         
     | 
| 
      
 1129 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1130 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1131 
     | 
    
         
            +
                else
         
     | 
| 
      
 1132 
     | 
    
         
            +
                  # need array of records, so always select the object/array here
         
     | 
| 
      
 1133 
     | 
    
         
            +
                  if object_key
         
     | 
| 
      
 1134 
     | 
    
         
            +
                    if data.is_a?(Hash)
         
     | 
| 
      
 1135 
     | 
    
         
            +
                      data = data[object_key]
         
     | 
| 
      
 1136 
     | 
    
         
            +
                    else
         
     | 
| 
      
 1137 
     | 
    
         
            +
                      Morpheus::Logging::DarkPrinter.puts "as_csv() expects data as an to fetch object key '#{object_key}' from, #{records.class}." if Morpheus::Logging.debug?
         
     | 
| 
      
 1138 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1139 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1140 
     | 
    
         
            +
                end
         
     | 
| 
      
 1141 
     | 
    
         
            +
                
         
     | 
| 
      
 1142 
     | 
    
         
            +
                
         
     | 
| 
      
 1143 
     | 
    
         
            +
                records = data
         
     | 
| 
      
 1144 
     | 
    
         
            +
             
     | 
| 
      
 1145 
     | 
    
         
            +
                # allow records as Array and Hash only..
         
     | 
| 
      
 1146 
     | 
    
         
            +
                if records.is_a?(Array)
         
     | 
| 
      
 1147 
     | 
    
         
            +
                  # records = records
         
     | 
| 
      
 1148 
     | 
    
         
            +
                elsif records.is_a?(Hash)
         
     | 
| 
      
 1149 
     | 
    
         
            +
                  records = [records]
         
     | 
| 
      
 1150 
     | 
    
         
            +
                else
         
     | 
| 
      
 1151 
     | 
    
         
            +
                  #raise "records_as_csv expects records as an Array of objects to render"
         
     | 
| 
      
 1152 
     | 
    
         
            +
                  Morpheus::Logging::DarkPrinter.puts "as_csv() expects data as an Array of objects to render, got a #{records.class} instead" if Morpheus::Logging.debug?
         
     | 
| 
      
 1153 
     | 
    
         
            +
                  # return ""
         
     | 
| 
      
 1154 
     | 
    
         
            +
                  return out
         
     | 
| 
      
 1155 
     | 
    
         
            +
                end
         
     | 
| 
      
 1156 
     | 
    
         
            +
             
     | 
| 
      
 1157 
     | 
    
         
            +
                # build column definitions, by default use all properties for the first record (Hash) in the array
         
     | 
| 
      
 1158 
     | 
    
         
            +
                columns = []
         
     | 
| 
      
 1159 
     | 
    
         
            +
                all_fields = records.first.is_a?(Hash) ? records.first.keys : []
         
     | 
| 
      
 1160 
     | 
    
         
            +
                if options[:include_fields]
         
     | 
| 
      
 1161 
     | 
    
         
            +
                  if (options[:include_fields].is_a?(Array) && options[:include_fields].size == 1 && options[:include_fields][0] == 'all') || options[:include_fields] == 'all'
         
     | 
| 
      
 1162 
     | 
    
         
            +
                    columns = all_fields
         
     | 
| 
      
 1163 
     | 
    
         
            +
                  else
         
     | 
| 
      
 1164 
     | 
    
         
            +
                    columns = options[:include_fields]
         
     | 
| 
      
 1165 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1166 
     | 
    
         
            +
                elsif options[:all_fields]
         
     | 
| 
      
 1167 
     | 
    
         
            +
                  columns = all_fields
         
     | 
| 
      
 1168 
     | 
    
         
            +
                elsif default_columns
         
     | 
| 
      
 1169 
     | 
    
         
            +
                  columns = default_columns
         
     | 
| 
      
 1170 
     | 
    
         
            +
                else
         
     | 
| 
      
 1171 
     | 
    
         
            +
                  columns = all_fields
         
     | 
| 
      
 1172 
     | 
    
         
            +
                end
         
     | 
| 
      
 1173 
     | 
    
         
            +
             
     | 
| 
       1103 
1174 
     | 
    
         
             
                column_defs = build_column_definitions(columns)
         
     | 
| 
       1104 
     | 
    
         
            -
                #columns = columns.flatten.compact
         
     | 
| 
       1105 
     | 
    
         
            -
                data_array = [data].flatten.compact
         
     | 
| 
       1106 
1175 
     | 
    
         | 
| 
       1107 
1176 
     | 
    
         
             
                if include_header
         
     | 
| 
       1108 
1177 
     | 
    
         
             
                  headers = column_defs.collect {|column_def| column_def.label }
         
     | 
| 
         @@ -1113,7 +1182,7 @@ module Morpheus::Cli::PrintHelper 
     | 
|
| 
       1113 
1182 
     | 
    
         
             
                  out << newline
         
     | 
| 
       1114 
1183 
     | 
    
         
             
                end
         
     | 
| 
       1115 
1184 
     | 
    
         
             
                lines = []
         
     | 
| 
       1116 
     | 
    
         
            -
                 
     | 
| 
      
 1185 
     | 
    
         
            +
                records.each do |obj|
         
     | 
| 
       1117 
1186 
     | 
    
         
             
                  if obj
         
     | 
| 
       1118 
1187 
     | 
    
         
             
                    cells = []
         
     | 
| 
       1119 
1188 
     | 
    
         
             
                    column_defs.each do |column_def|
         
     | 
| 
         @@ -1137,29 +1206,9 @@ module Morpheus::Cli::PrintHelper 
     | 
|
| 
       1137 
1206 
     | 
    
         | 
| 
       1138 
1207 
     | 
    
         
             
              end
         
     | 
| 
       1139 
1208 
     | 
    
         | 
| 
      
 1209 
     | 
    
         
            +
              # deprecated, replaced by as_csv(records, columns, options, object_key)
         
     | 
| 
       1140 
1210 
     | 
    
         
             
              def records_as_csv(records, options={}, default_columns=nil)
         
     | 
| 
       1141 
     | 
    
         
            -
                 
     | 
| 
       1142 
     | 
    
         
            -
                if !records
         
     | 
| 
       1143 
     | 
    
         
            -
                  #raise "records_as_csv expects records as an Array of objects to render"
         
     | 
| 
       1144 
     | 
    
         
            -
                  return out
         
     | 
| 
       1145 
     | 
    
         
            -
                end
         
     | 
| 
       1146 
     | 
    
         
            -
                cols = []
         
     | 
| 
       1147 
     | 
    
         
            -
                all_fields = records.first ? records.first.keys : []
         
     | 
| 
       1148 
     | 
    
         
            -
                if options[:include_fields]
         
     | 
| 
       1149 
     | 
    
         
            -
                  if (options[:include_fields].is_a?(Array) && options[:include_fields].size == 1 && options[:include_fields][0] == 'all') || options[:include_fields] == 'all'
         
     | 
| 
       1150 
     | 
    
         
            -
                    cols = all_fields
         
     | 
| 
       1151 
     | 
    
         
            -
                  else
         
     | 
| 
       1152 
     | 
    
         
            -
                    cols = options[:include_fields]
         
     | 
| 
       1153 
     | 
    
         
            -
                  end
         
     | 
| 
       1154 
     | 
    
         
            -
                elsif options[:all_fields]
         
     | 
| 
       1155 
     | 
    
         
            -
                  cols = all_fields
         
     | 
| 
       1156 
     | 
    
         
            -
                elsif default_columns
         
     | 
| 
       1157 
     | 
    
         
            -
                  cols = default_columns
         
     | 
| 
       1158 
     | 
    
         
            -
                else
         
     | 
| 
       1159 
     | 
    
         
            -
                  cols = all_fields
         
     | 
| 
       1160 
     | 
    
         
            -
                end
         
     | 
| 
       1161 
     | 
    
         
            -
                out << as_csv(records, cols, options)
         
     | 
| 
       1162 
     | 
    
         
            -
                out
         
     | 
| 
      
 1211 
     | 
    
         
            +
                as_csv(records, default_columns, options)
         
     | 
| 
       1163 
1212 
     | 
    
         
             
              end
         
     | 
| 
       1164 
1213 
     | 
    
         | 
| 
       1165 
1214 
     | 
    
         
             
              def as_json(data, options={}, object_key=nil)
         
     | 
| 
         @@ -1169,12 +1218,7 @@ module Morpheus::Cli::PrintHelper 
     | 
|
| 
       1169 
1218 
     | 
    
         
             
                end
         
     | 
| 
       1170 
1219 
     | 
    
         | 
| 
       1171 
1220 
     | 
    
         
             
                if options[:include_fields]
         
     | 
| 
       1172 
     | 
    
         
            -
                   
     | 
| 
       1173 
     | 
    
         
            -
                    # data[object_key] = filter_data(data[object_key], options[:include_fields])
         
     | 
| 
       1174 
     | 
    
         
            -
                    data = {(object_key) => filter_data(data[object_key], options[:include_fields]) }
         
     | 
| 
       1175 
     | 
    
         
            -
                  else
         
     | 
| 
       1176 
     | 
    
         
            -
                    data = filter_data(data, options[:include_fields])
         
     | 
| 
       1177 
     | 
    
         
            -
                  end
         
     | 
| 
      
 1221 
     | 
    
         
            +
                  data = transform_data_for_field_options(data, options, object_key)
         
     | 
| 
       1178 
1222 
     | 
    
         
             
                end
         
     | 
| 
       1179 
1223 
     | 
    
         | 
| 
       1180 
1224 
     | 
    
         
             
                do_pretty = options.key?(:pretty_json) ? options[:pretty_json] : true
         
     | 
| 
         @@ -1193,11 +1237,7 @@ module Morpheus::Cli::PrintHelper 
     | 
|
| 
       1193 
1237 
     | 
    
         
             
                  return "null" # "No data"
         
     | 
| 
       1194 
1238 
     | 
    
         
             
                end
         
     | 
| 
       1195 
1239 
     | 
    
         
             
                if options[:include_fields]
         
     | 
| 
       1196 
     | 
    
         
            -
                   
     | 
| 
       1197 
     | 
    
         
            -
                    data[object_key] = filter_data(data[object_key], options[:include_fields])
         
     | 
| 
       1198 
     | 
    
         
            -
                  else
         
     | 
| 
       1199 
     | 
    
         
            -
                    data = filter_data(data, options[:include_fields])
         
     | 
| 
       1200 
     | 
    
         
            -
                  end
         
     | 
| 
      
 1240 
     | 
    
         
            +
                  data = transform_data_for_field_options(data, options, object_key)
         
     | 
| 
       1201 
1241 
     | 
    
         
             
                end
         
     | 
| 
       1202 
1242 
     | 
    
         
             
                begin
         
     | 
| 
       1203 
1243 
     | 
    
         
             
                  out << data.to_yaml
         
     | 
| 
         @@ -1209,6 +1249,48 @@ module Morpheus::Cli::PrintHelper 
     | 
|
| 
       1209 
1249 
     | 
    
         
             
                out
         
     | 
| 
       1210 
1250 
     | 
    
         
             
              end
         
     | 
| 
       1211 
1251 
     | 
    
         | 
| 
      
 1252 
     | 
    
         
            +
             
     | 
| 
      
 1253 
     | 
    
         
            +
              # transform data for options --fields id,authority and --select id,authority
         
     | 
| 
      
 1254 
     | 
    
         
            +
              # support traversing records with --raw-fields and the list command. Example: roles list --raw-fields roles.id,roles.authority
         
     | 
| 
      
 1255 
     | 
    
         
            +
              def transform_data_for_field_options(data, options, object_key=nil)
         
     | 
| 
      
 1256 
     | 
    
         
            +
                if options[:include_fields] && data.is_a?(Hash)
         
     | 
| 
      
 1257 
     | 
    
         
            +
                  if options[:raw_fields]
         
     | 
| 
      
 1258 
     | 
    
         
            +
                    row = (object_key && !options[:raw_fields]) ? data[object_key] : data
         
     | 
| 
      
 1259 
     | 
    
         
            +
                    records = [row].flatten()
         
     | 
| 
      
 1260 
     | 
    
         
            +
                    # look for an array in the first field only now...
         
     | 
| 
      
 1261 
     | 
    
         
            +
                    field_parts = options[:include_fields][0].to_s.split(".")
         
     | 
| 
      
 1262 
     | 
    
         
            +
                    field_context = field_parts[0]
         
     | 
| 
      
 1263 
     | 
    
         
            +
                    context_data = data[field_context]
         
     | 
| 
      
 1264 
     | 
    
         
            +
                    if field_parts.size > 1 && context_data.is_a?(Array)
         
     | 
| 
      
 1265 
     | 
    
         
            +
                      # inject all the root level properties to be selectable too..
         
     | 
| 
      
 1266 
     | 
    
         
            +
                      context_data = data.delete(field_context)
         
     | 
| 
      
 1267 
     | 
    
         
            +
                      # records = context_data
         
     | 
| 
      
 1268 
     | 
    
         
            +
                      records = context_data.collect {|it| it.is_a?(Hash) ? data.merge(it) : data }
         
     | 
| 
      
 1269 
     | 
    
         
            +
                      # hacky modifying options in place
         
     | 
| 
      
 1270 
     | 
    
         
            +
                      options[:include_fields_context] = field_context
         
     | 
| 
      
 1271 
     | 
    
         
            +
                      options[:include_fields] = options[:include_fields].collect {|it| it.sub(field_context+'.', '')}
         
     | 
| 
      
 1272 
     | 
    
         
            +
                      # data = filter_data(records, options[:include_fields])
         
     | 
| 
      
 1273 
     | 
    
         
            +
                      # data[field_context] = filter_data(records, options[:include_fields])
         
     | 
| 
      
 1274 
     | 
    
         
            +
                      data = {(field_context) => filter_data(records, options[:include_fields])}
         
     | 
| 
      
 1275 
     | 
    
         
            +
                    else
         
     | 
| 
      
 1276 
     | 
    
         
            +
                      data = filter_data(data, options[:include_fields])
         
     | 
| 
      
 1277 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1278 
     | 
    
         
            +
                  else
         
     | 
| 
      
 1279 
     | 
    
         
            +
                    # By default, fields are relative to the object_key, so you can use -F id instead of requiring -F instance.id
         
     | 
| 
      
 1280 
     | 
    
         
            +
                    # So ironically it is the 'raw' options (:raw_fields == true) that has to do all this funny stuff to filter intuitively.
         
     | 
| 
      
 1281 
     | 
    
         
            +
                    if object_key
         
     | 
| 
      
 1282 
     | 
    
         
            +
                      # this removes everything but the object, makes sense when using --fields
         
     | 
| 
      
 1283 
     | 
    
         
            +
                      data = {(object_key) => filter_data(data[object_key], options[:include_fields])}
         
     | 
| 
      
 1284 
     | 
    
         
            +
                      # this preserves other fields eg. meta...
         
     | 
| 
      
 1285 
     | 
    
         
            +
                      # data[object_key] = filter_data(data[object_key], options[:include_fields])
         
     | 
| 
      
 1286 
     | 
    
         
            +
                    else
         
     | 
| 
      
 1287 
     | 
    
         
            +
                      data = filter_data(data, options[:include_fields])
         
     | 
| 
      
 1288 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1289 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1290 
     | 
    
         
            +
                end
         
     | 
| 
      
 1291 
     | 
    
         
            +
                return data
         
     | 
| 
      
 1292 
     | 
    
         
            +
              end
         
     | 
| 
      
 1293 
     | 
    
         
            +
             
     | 
| 
       1212 
1294 
     | 
    
         
             
              def sleep_with_dots(sleep_seconds, dots=3, dot_chr=".")
         
     | 
| 
       1213 
1295 
     | 
    
         
             
                dot_interval = (sleep_seconds.to_f / dots.to_i)
         
     | 
| 
       1214 
1296 
     | 
    
         
             
                dots.to_i.times do |dot_index|
         
     | 
| 
         @@ -2082,7 +2082,6 @@ module Morpheus::Cli::ProvisioningHelper 
     | 
|
| 
       2082 
2082 
     | 
    
         
             
                    if !visibility && !options[:no_prompt]
         
     | 
| 
       2083 
2083 
     | 
    
         
             
                      visibility = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'visibility', 'fieldLabel' => 'Tenant Permissions Visibility', 'type' => 'select', 'defaultValue' => 'private', 'required' => true, 'selectOptions' => [{'name' => 'Private', 'value' => 'private'},{'name' => 'Public', 'value' => 'public'}]}], options[:options], @api_client, {})['visibility']
         
     | 
| 
       2084 
2084 
     | 
    
         
             
                    end
         
     | 
| 
       2085 
     | 
    
         
            -
             
     | 
| 
       2086 
2085 
     | 
    
         
             
                    permissions['resourcePool'] = {'visibility' => visibility} if visibility
         
     | 
| 
       2087 
2086 
     | 
    
         
             
                  end
         
     | 
| 
       2088 
2087 
     | 
    
         | 
| 
         @@ -2114,8 +2113,7 @@ module Morpheus::Cli::ProvisioningHelper 
     | 
|
| 
       2114 
2113 
     | 
    
         
             
              def prompt_permissions_v2(options, excludes = [])
         
     | 
| 
       2115 
2114 
     | 
    
         
             
                perms = prompt_permissions(options, excludes)
         
     | 
| 
       2116 
2115 
     | 
    
         
             
                rtn = {}
         
     | 
| 
       2117 
     | 
    
         
            -
             
     | 
| 
       2118 
     | 
    
         
            -
                rtn['visibility'] = perms['resourcePool']['visibility'] if !perms['resourcePool'].nil?
         
     | 
| 
      
 2116 
     | 
    
         
            +
                rtn['visibility'] = perms['resourcePool']['visibility'] if !perms['resourcePool'].nil? && !excludes.include?('visibility')
         
     | 
| 
       2119 
2117 
     | 
    
         
             
                rtn['tenants'] = ((perms['tenantPermissions'] || {})['accounts'] || []).collect {|it| {'id' => it}}
         
     | 
| 
       2120 
2118 
     | 
    
         
             
                rtn
         
     | 
| 
       2121 
2119 
     | 
    
         
             
              end
         
     | 
| 
         @@ -148,6 +148,17 @@ module Morpheus::Cli::RestCommand 
     | 
|
| 
       148 
148 
     | 
    
         | 
| 
       149 
149 
     | 
    
         
             
                alias :set_rest_interface_name :rest_interface_name=
         
     | 
| 
       150 
150 
     | 
    
         | 
| 
      
 151 
     | 
    
         
            +
                # rest_perms_config enables and configures permissions prompt
         
     | 
| 
      
 152 
     | 
    
         
            +
                def rest_perms_config
         
     | 
| 
      
 153 
     | 
    
         
            +
                  @rest_perms_config || {}
         
     | 
| 
      
 154 
     | 
    
         
            +
                end
         
     | 
| 
      
 155 
     | 
    
         
            +
             
     | 
| 
      
 156 
     | 
    
         
            +
                def rest_perms_config=(v)
         
     | 
| 
      
 157 
     | 
    
         
            +
                  @rest_perms_config = v
         
     | 
| 
      
 158 
     | 
    
         
            +
                end
         
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
      
 160 
     | 
    
         
            +
                alias :set_rest_perms_config :rest_perms_config=
         
     | 
| 
      
 161 
     | 
    
         
            +
             
     | 
| 
       151 
162 
     | 
    
         
             
                # rest_has_type indicates a resource has a type. default is false
         
     | 
| 
       152 
163 
     | 
    
         
             
                def rest_has_type
         
     | 
| 
       153 
164 
     | 
    
         
             
                  @rest_has_type == true
         
     | 
| 
         @@ -329,6 +340,10 @@ module Morpheus::Cli::RestCommand 
     | 
|
| 
       329 
340 
     | 
    
         
             
                self.class.rest_interface_name
         
     | 
| 
       330 
341 
     | 
    
         
             
              end
         
     | 
| 
       331 
342 
     | 
    
         | 
| 
      
 343 
     | 
    
         
            +
              def rest_perms_config
         
     | 
| 
      
 344 
     | 
    
         
            +
                self.class.rest_perms_config
         
     | 
| 
      
 345 
     | 
    
         
            +
              end
         
     | 
| 
      
 346 
     | 
    
         
            +
             
     | 
| 
       332 
347 
     | 
    
         
             
              # returns the default rest interface, allows using rest_interface_name = "your"
         
     | 
| 
       333 
348 
     | 
    
         
             
              # or override this method to return @your_interface if needed
         
     | 
| 
       334 
349 
     | 
    
         
             
              def rest_interface
         
     | 
| 
         @@ -600,25 +615,25 @@ EOT 
     | 
|
| 
       600 
615 
     | 
    
         
             
                  verify_args!(args:args, optparse:optparse, count: 0)
         
     | 
| 
       601 
616 
     | 
    
         
             
                end
         
     | 
| 
       602 
617 
     | 
    
         
             
                connect(options)
         
     | 
| 
       603 
     | 
    
         
            -
                # load or prompt for type
         
     | 
| 
       604 
     | 
    
         
            -
                if rest_has_type && type_option_type.nil?
         
     | 
| 
       605 
     | 
    
         
            -
                  if record_type_id.nil?
         
     | 
| 
       606 
     | 
    
         
            -
                    #raise_command_error "#{rest_type_label} is required.\n#{optparse}"
         
     | 
| 
       607 
     | 
    
         
            -
                    type_list = rest_type_interface.list({max:10000, creatable:true})[rest_type_list_key]
         
     | 
| 
       608 
     | 
    
         
            -
                    type_dropdown_options = respond_to?("#{rest_key}_type_list_to_options", true) ? send("#{rest_key}_type_list_to_options", type_list) : type_list.collect {|it| {'name' => it['name'], 'value' => it['code']} }
         
     | 
| 
       609 
     | 
    
         
            -
                    record_type_id = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'type', 'fieldLabel' => rest_type_label, 'type' => 'select', 'selectOptions' => type_dropdown_options, 'required' => true}], options[:options], @api_client)['type']
         
     | 
| 
       610 
     | 
    
         
            -
                  end
         
     | 
| 
       611 
     | 
    
         
            -
                  record_type = rest_type_find_by_name_or_id(record_type_id)
         
     | 
| 
       612 
     | 
    
         
            -
                  if record_type.nil?
         
     | 
| 
       613 
     | 
    
         
            -
                    return 1, "#{rest_type_label} not found for '#{record_type_id}"
         
     | 
| 
       614 
     | 
    
         
            -
                  end
         
     | 
| 
       615 
     | 
    
         
            -
                end
         
     | 
| 
       616 
618 
     | 
    
         
             
                passed_options = parse_passed_options(options)
         
     | 
| 
       617 
619 
     | 
    
         
             
                payload = {}
         
     | 
| 
       618 
620 
     | 
    
         
             
                if options[:payload]
         
     | 
| 
       619 
621 
     | 
    
         
             
                  payload = options[:payload]
         
     | 
| 
       620 
622 
     | 
    
         
             
                  payload.deep_merge!({rest_object_key => passed_options})
         
     | 
| 
       621 
623 
     | 
    
         
             
                else
         
     | 
| 
      
 624 
     | 
    
         
            +
                  # load or prompt for type
         
     | 
| 
      
 625 
     | 
    
         
            +
                  if rest_has_type && type_option_type.nil?
         
     | 
| 
      
 626 
     | 
    
         
            +
                    if record_type_id.nil?
         
     | 
| 
      
 627 
     | 
    
         
            +
                      #raise_command_error "#{rest_type_label} is required.\n#{optparse}"
         
     | 
| 
      
 628 
     | 
    
         
            +
                      type_list = rest_type_interface.list({max:10000, creatable:true})[rest_type_list_key]
         
     | 
| 
      
 629 
     | 
    
         
            +
                      type_dropdown_options = respond_to?("#{rest_key}_type_list_to_options", true) ? send("#{rest_key}_type_list_to_options", type_list) : type_list.collect {|it| {'name' => it['name'], 'value' => it['code']} }
         
     | 
| 
      
 630 
     | 
    
         
            +
                      record_type_id = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'type', 'fieldLabel' => rest_type_label, 'type' => 'select', 'selectOptions' => type_dropdown_options, 'required' => true}], options[:options], @api_client)['type']
         
     | 
| 
      
 631 
     | 
    
         
            +
                    end
         
     | 
| 
      
 632 
     | 
    
         
            +
                    record_type = rest_type_find_by_name_or_id(record_type_id)
         
     | 
| 
      
 633 
     | 
    
         
            +
                    if record_type.nil?
         
     | 
| 
      
 634 
     | 
    
         
            +
                      return 1, "#{rest_type_label} not found for '#{record_type_id}"
         
     | 
| 
      
 635 
     | 
    
         
            +
                    end
         
     | 
| 
      
 636 
     | 
    
         
            +
                  end
         
     | 
| 
       622 
637 
     | 
    
         
             
                  record_payload = {}
         
     | 
| 
       623 
638 
     | 
    
         
             
                  if record_name
         
     | 
| 
       624 
639 
     | 
    
         
             
                    record_payload['name'] = record_name
         
     | 
| 
         @@ -667,7 +682,7 @@ EOT 
     | 
|
| 
       667 
682 
     | 
    
         
             
                      end
         
     | 
| 
       668 
683 
     | 
    
         
             
                    end
         
     | 
| 
       669 
684 
     | 
    
         
             
                    api_params = (options[:params] || {}).merge(record_payload)
         
     | 
| 
       670 
     | 
    
         
            -
                    v_prompt = Morpheus::Cli::OptionTypes.prompt(my_option_types, options[:options], @api_client, api_params)
         
     | 
| 
      
 685 
     | 
    
         
            +
                    v_prompt = Morpheus::Cli::OptionTypes.prompt(my_option_types, options[:options], @api_client, api_params, false, true)
         
     | 
| 
       671 
686 
     | 
    
         
             
                    v_prompt.deep_compact!
         
     | 
| 
       672 
687 
     | 
    
         
             
                    v_prompt.booleanize! # 'on' => true
         
     | 
| 
       673 
688 
     | 
    
         
             
                    record_payload.deep_merge!(v_prompt)
         
     | 
| 
         @@ -679,6 +694,18 @@ EOT 
     | 
|
| 
       679 
694 
     | 
    
         
             
                    v_prompt.booleanize! # 'on' => true
         
     | 
| 
       680 
695 
     | 
    
         
             
                    record_payload.deep_merge!(v_prompt)
         
     | 
| 
       681 
696 
     | 
    
         
             
                  end
         
     | 
| 
      
 697 
     | 
    
         
            +
                  # permissions
         
     | 
| 
      
 698 
     | 
    
         
            +
                  if rest_perms_config[:enabled]
         
     | 
| 
      
 699 
     | 
    
         
            +
                    if rest_perms_config[:version] == 2
         
     | 
| 
      
 700 
     | 
    
         
            +
                      perms = prompt_permissions_v2(options.deep_merge(rest_perms_config[:options] || {}), rest_perms_config[:excludes] || [])
         
     | 
| 
      
 701 
     | 
    
         
            +
                    else
         
     | 
| 
      
 702 
     | 
    
         
            +
                      perms = prompt_permissions(options.deep_merge(rest_perms_config[:options] || {}), rest_perms_config[:excludes] || [])
         
     | 
| 
      
 703 
     | 
    
         
            +
                    end
         
     | 
| 
      
 704 
     | 
    
         
            +
                    if !rest_perms_config[:name].nil?
         
     | 
| 
      
 705 
     | 
    
         
            +
                      perms.transform_keys! {|k| k == 'resourcePermissions' ? rest_perms_config[:name] : k}
         
     | 
| 
      
 706 
     | 
    
         
            +
                    end
         
     | 
| 
      
 707 
     | 
    
         
            +
                    record_payload.merge!(perms)
         
     | 
| 
      
 708 
     | 
    
         
            +
                  end
         
     | 
| 
       682 
709 
     | 
    
         
             
                  payload[rest_object_key] = record_payload
         
     | 
| 
       683 
710 
     | 
    
         
             
                end
         
     | 
| 
       684 
711 
     | 
    
         
             
                rest_interface.setopts(options)
         
     |