morpheus-cli 5.2.4.1 → 5.3.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/README.md +1 -3
- data/lib/morpheus/api/api_client.rb +48 -14
- data/lib/morpheus/api/certificate_types_interface.rb +14 -0
- data/lib/morpheus/api/certificates_interface.rb +9 -0
- data/lib/morpheus/api/integration_types_interface.rb +14 -0
- data/lib/morpheus/api/integrations_interface.rb +7 -22
- data/lib/morpheus/api/network_services_interface.rb +14 -0
- data/lib/morpheus/api/read_interface.rb +23 -0
- data/lib/morpheus/api/rest_interface.rb +12 -10
- data/lib/morpheus/api/roles_interface.rb +7 -0
- data/lib/morpheus/api/servers_interface.rb +7 -0
- data/lib/morpheus/api/user_settings_interface.rb +38 -18
- data/lib/morpheus/api/vdi_allocations_interface.rb +9 -0
- data/lib/morpheus/api/vdi_apps_interface.rb +9 -0
- data/lib/morpheus/api/vdi_gateways_interface.rb +9 -0
- data/lib/morpheus/api/vdi_interface.rb +28 -0
- data/lib/morpheus/api/vdi_pools_interface.rb +19 -0
- data/lib/morpheus/cli.rb +9 -2
- data/lib/morpheus/cli/activity_command.rb +7 -4
- data/lib/morpheus/cli/apps.rb +59 -75
- data/lib/morpheus/cli/catalog_item_types_command.rb +13 -13
- data/lib/morpheus/cli/certificates_command.rb +575 -0
- data/lib/morpheus/cli/cli_command.rb +61 -6
- data/lib/morpheus/cli/clouds.rb +1 -0
- data/lib/morpheus/cli/clusters.rb +5 -2
- data/lib/morpheus/cli/commands/standard/history_command.rb +4 -5
- data/lib/morpheus/cli/commands/standard/man_command.rb +4 -5
- data/lib/morpheus/cli/dashboard_command.rb +3 -3
- data/lib/morpheus/cli/execution_request_command.rb +15 -5
- data/lib/morpheus/cli/hosts.rb +245 -224
- data/lib/morpheus/cli/instances.rb +150 -167
- data/lib/morpheus/cli/integrations_command.rb +588 -41
- data/lib/morpheus/cli/invoices_command.rb +23 -46
- data/lib/morpheus/cli/login.rb +7 -0
- data/lib/morpheus/cli/mixins/option_source_helper.rb +15 -16
- data/lib/morpheus/cli/mixins/print_helper.rb +36 -18
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +3 -3
- data/lib/morpheus/cli/mixins/vdi_helper.rb +246 -0
- data/lib/morpheus/cli/network_domains_command.rb +2 -2
- data/lib/morpheus/cli/network_routers_command.rb +22 -9
- data/lib/morpheus/cli/networks_command.rb +2 -2
- data/lib/morpheus/cli/option_types.rb +34 -33
- data/lib/morpheus/cli/remote.rb +3 -2
- data/lib/morpheus/cli/reports_command.rb +5 -2
- data/lib/morpheus/cli/roles.rb +215 -55
- data/lib/morpheus/cli/service_plans_command.rb +4 -1
- data/lib/morpheus/cli/subnets_command.rb +11 -2
- data/lib/morpheus/cli/user_settings_command.rb +268 -57
- data/lib/morpheus/cli/vdi_allocations_command.rb +159 -0
- data/lib/morpheus/cli/vdi_apps_command.rb +317 -0
- data/lib/morpheus/cli/vdi_command.rb +359 -0
- data/lib/morpheus/cli/vdi_gateways_command.rb +290 -0
- data/lib/morpheus/cli/vdi_pools_command.rb +571 -0
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/rest_client.rb +30 -0
- data/lib/morpheus/terminal.rb +15 -7
- metadata +18 -2
| @@ -140,32 +140,32 @@ class Morpheus::Cli::InvoicesCommand | |
| 140 140 | 
             
                # construct params
         | 
| 141 141 | 
             
                params.merge!(parse_list_options(options))
         | 
| 142 142 | 
             
                if options[:clouds]
         | 
| 143 | 
            -
                  cloud_ids = parse_cloud_id_list(options[:clouds])
         | 
| 143 | 
            +
                  cloud_ids = parse_cloud_id_list(options[:clouds], {}, false, true)
         | 
| 144 144 | 
             
                  return 1, "clouds not found for #{options[:clouds]}" if cloud_ids.nil?
         | 
| 145 145 | 
             
                  params['zoneId'] = cloud_ids
         | 
| 146 146 | 
             
                end
         | 
| 147 147 | 
             
                if options[:groups]
         | 
| 148 | 
            -
                  group_ids = parse_group_id_list(options[:groups])
         | 
| 148 | 
            +
                  group_ids = parse_group_id_list(options[:groups], {}, false, true)
         | 
| 149 149 | 
             
                  return 1, "groups not found for #{options[:groups]}" if group_ids.nil?
         | 
| 150 150 | 
             
                  params['siteId'] = group_ids
         | 
| 151 151 | 
             
                end
         | 
| 152 152 | 
             
                if options[:instances]
         | 
| 153 | 
            -
                  instance_ids = parse_instance_id_list(options[:instances])
         | 
| 153 | 
            +
                  instance_ids = parse_instance_id_list(options[:instances], {}, false, true)
         | 
| 154 154 | 
             
                  return 1, "instances not found for #{options[:instances]}" if instance_ids.nil?
         | 
| 155 155 | 
             
                  params['instanceId'] = instance_ids
         | 
| 156 156 | 
             
                end
         | 
| 157 157 | 
             
                if options[:servers]
         | 
| 158 | 
            -
                  server_ids = parse_server_id_list(options[:servers])
         | 
| 158 | 
            +
                  server_ids = parse_server_id_list(options[:servers], {}, false, true)
         | 
| 159 159 | 
             
                  return 1, "servers not found for #{options[:servers]}" if server_ids.nil?
         | 
| 160 160 | 
             
                  params['serverId'] = server_ids
         | 
| 161 161 | 
             
                end
         | 
| 162 162 | 
             
                if options[:users]
         | 
| 163 | 
            -
                  user_ids = parse_user_id_list(options[:users])
         | 
| 163 | 
            +
                  user_ids = parse_user_id_list(options[:users], {}, false, true)
         | 
| 164 164 | 
             
                  return 1, "users not found for #{options[:users]}" if user_ids.nil?
         | 
| 165 165 | 
             
                  params['userId'] = user_ids
         | 
| 166 166 | 
             
                end
         | 
| 167 167 | 
             
                if options[:projects]
         | 
| 168 | 
            -
                  project_ids = parse_project_id_list(options[:projects])
         | 
| 168 | 
            +
                  project_ids = parse_project_id_list(options[:projects], {}, false, true)
         | 
| 169 169 | 
             
                  return 1, "projects not found for #{options[:projects]}" if project_ids.nil?
         | 
| 170 170 | 
             
                  params['projectId'] = project_ids
         | 
| 171 171 | 
             
                end
         | 
| @@ -636,37 +636,20 @@ Update an invoice. | |
| 636 636 | 
             
                params = {}
         | 
| 637 637 | 
             
                payload = {}
         | 
| 638 638 | 
             
                optparse = Morpheus::Cli::OptionParser.new do |opts|
         | 
| 639 | 
            -
                  opts.banner = subcommand_usage("[ | 
| 640 | 
            -
                  opts.on( '-- | 
| 641 | 
            -
                    payload[:daily] = true
         | 
| 642 | 
            -
                  end
         | 
| 643 | 
            -
                  opts.on( '--costing', "Refresh Costing Data" ) do
         | 
| 644 | 
            -
                    payload[:costing] = true
         | 
| 645 | 
            -
                  end
         | 
| 646 | 
            -
                  opts.on( '--current', "Collect the most up to date costing data." ) do
         | 
| 647 | 
            -
                    payload[:current] = true
         | 
| 648 | 
            -
                  end
         | 
| 649 | 
            -
                  opts.on( '--date DATE', String, "Date to collect costing for. By default the cost data is collected for the end of the previous period." ) do |val|
         | 
| 650 | 
            -
                    payload[:date] = val.to_s
         | 
| 651 | 
            -
                  end
         | 
| 652 | 
            -
                  opts.on( '-c', '--cloud CLOUD', "Specify cloud(s) to refresh costing for." ) do |val|
         | 
| 639 | 
            +
                  opts.banner = subcommand_usage("[-c CLOUD]")
         | 
| 640 | 
            +
                  opts.on( '-c', '--clouds CLOUD', "Specify clouds to refresh costing for." ) do |val|
         | 
| 653 641 | 
             
                    payload[:clouds] ||= []
         | 
| 654 642 | 
             
                    payload[:clouds] << val
         | 
| 655 643 | 
             
                  end
         | 
| 656 | 
            -
                  opts.on( '--all', "Refresh costing for all clouds." ) do
         | 
| 644 | 
            +
                  opts.on( '--all', "Refresh costing for all clouds. This can be used instead of --clouds" ) do
         | 
| 657 645 | 
             
                    payload[:all] = true
         | 
| 658 646 | 
             
                  end
         | 
| 659 | 
            -
                   | 
| 660 | 
            -
             | 
| 661 | 
            -
                   | 
| 647 | 
            +
                  opts.on( '--date DATE', String, "Date to collect costing for. By default the cost data is collected for the end of the previous job interval (hour or day)." ) do |val|
         | 
| 648 | 
            +
                    payload[:date] = val.to_s
         | 
| 649 | 
            +
                  end
         | 
| 662 650 | 
             
                  build_standard_update_options(opts, options, [:query, :auto_confirm])
         | 
| 663 651 | 
             
                  opts.footer = <<-EOT
         | 
| 664 | 
            -
            Refresh  | 
| 665 | 
            -
            By default, nothing is changed.
         | 
| 666 | 
            -
            Include --daily to regenerate invoice records.
         | 
| 667 | 
            -
            Include --costing to refresh actual costing data.
         | 
| 668 | 
            -
            Include --current to refresh costing data for the actual current time.
         | 
| 669 | 
            -
            To get the latest invoice costing data, include --daily --costing --current --all 
         | 
| 652 | 
            +
            Refresh invoice costing data for the specified clouds.
         | 
| 670 653 | 
             
            EOT
         | 
| 671 654 | 
             
                end
         | 
| 672 655 | 
             
                optparse.parse!(args)
         | 
| @@ -677,17 +660,11 @@ EOT | |
| 677 660 | 
             
                  payload = options[:payload]
         | 
| 678 661 | 
             
                end
         | 
| 679 662 | 
             
                payload.deep_merge!(parse_passed_options(options))
         | 
| 680 | 
            -
                # --clouds
         | 
| 663 | 
            +
                # --clouds lookup ID for name
         | 
| 681 664 | 
             
                if payload[:clouds]
         | 
| 682 | 
            -
                   | 
| 683 | 
            -
             | 
| 684 | 
            -
             | 
| 685 | 
            -
                    else
         | 
| 686 | 
            -
                      cloud = find_cloud_option(cloud_id)
         | 
| 687 | 
            -
                      return 1 if cloud.nil?
         | 
| 688 | 
            -
                      cloud['id']
         | 
| 689 | 
            -
                    end
         | 
| 690 | 
            -
                  }
         | 
| 665 | 
            +
                  cloud_ids = parse_cloud_id_list(payload[:clouds], {}, false, true)
         | 
| 666 | 
            +
                  return 1, "clouds not found for #{payload[:clouds]}" if cloud_ids.nil?
         | 
| 667 | 
            +
                  payload[:clouds] = cloud_ids
         | 
| 691 668 | 
             
                end
         | 
| 692 669 | 
             
                # are you sure?
         | 
| 693 670 | 
             
                unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to refresh invoices?")
         | 
| @@ -831,32 +808,32 @@ EOT | |
| 831 808 | 
             
                # construct params
         | 
| 832 809 | 
             
                params.merge!(parse_list_options(options))
         | 
| 833 810 | 
             
                if options[:clouds]
         | 
| 834 | 
            -
                  cloud_ids = parse_cloud_id_list(options[:clouds])
         | 
| 811 | 
            +
                  cloud_ids = parse_cloud_id_list(options[:clouds], {}, false, true)
         | 
| 835 812 | 
             
                  return 1, "clouds not found for #{options[:clouds]}" if cloud_ids.nil?
         | 
| 836 813 | 
             
                  params['zoneId'] = cloud_ids
         | 
| 837 814 | 
             
                end
         | 
| 838 815 | 
             
                if options[:groups]
         | 
| 839 | 
            -
                  group_ids = parse_group_id_list(options[:groups])
         | 
| 816 | 
            +
                  group_ids = parse_group_id_list(options[:groups], {}, false, true)
         | 
| 840 817 | 
             
                  return 1, "groups not found for #{options[:groups]}" if group_ids.nil?
         | 
| 841 818 | 
             
                  params['siteId'] = group_ids
         | 
| 842 819 | 
             
                end
         | 
| 843 820 | 
             
                if options[:instances]
         | 
| 844 | 
            -
                  instance_ids = parse_instance_id_list(options[:instances])
         | 
| 821 | 
            +
                  instance_ids = parse_instance_id_list(options[:instances], {}, false, true)
         | 
| 845 822 | 
             
                  return 1, "instances not found for #{options[:instances]}" if instance_ids.nil?
         | 
| 846 823 | 
             
                  params['instanceId'] = instance_ids
         | 
| 847 824 | 
             
                end
         | 
| 848 825 | 
             
                if options[:servers]
         | 
| 849 | 
            -
                  server_ids = parse_server_id_list(options[:servers])
         | 
| 826 | 
            +
                  server_ids = parse_server_id_list(options[:servers], {}, false, true)
         | 
| 850 827 | 
             
                  return 1, "servers not found for #{options[:servers]}" if server_ids.nil?
         | 
| 851 828 | 
             
                  params['serverId'] = server_ids
         | 
| 852 829 | 
             
                end
         | 
| 853 830 | 
             
                if options[:users]
         | 
| 854 | 
            -
                  user_ids = parse_user_id_list(options[:users])
         | 
| 831 | 
            +
                  user_ids = parse_user_id_list(options[:users], {}, false, true)
         | 
| 855 832 | 
             
                  return 1, "users not found for #{options[:users]}" if user_ids.nil?
         | 
| 856 833 | 
             
                  params['userId'] = user_ids
         | 
| 857 834 | 
             
                end
         | 
| 858 835 | 
             
                if options[:projects]
         | 
| 859 | 
            -
                  project_ids = parse_project_id_list(options[:projects])
         | 
| 836 | 
            +
                  project_ids = parse_project_id_list(options[:projects], {}, false, true)
         | 
| 860 837 | 
             
                  return 1, "projects not found for #{options[:projects]}" if project_ids.nil?
         | 
| 861 838 | 
             
                  params['projectId'] = project_ids
         | 
| 862 839 | 
             
                end
         | 
    
        data/lib/morpheus/cli/login.rb
    CHANGED
    
    | @@ -36,6 +36,13 @@ class Morpheus::Cli::Login | |
| 36 36 | 
             
                  opts.on( '-p', '--password PASSWORD', "Password" ) do |val|
         | 
| 37 37 | 
             
                    password = val
         | 
| 38 38 | 
             
                  end
         | 
| 39 | 
            +
                  opts.on( '--password-file FILE', String, "Password File, read a file containing the password." ) do |val|
         | 
| 40 | 
            +
                    password_file = File.expand_path(val)
         | 
| 41 | 
            +
                    if !File.exists?(password_file) || !File.file?(password_file) # check readable too
         | 
| 42 | 
            +
                      raise ::OptionParser::InvalidOption.new("File not found: #{password_file}")
         | 
| 43 | 
            +
                    end
         | 
| 44 | 
            +
                    password = File.read(password_file) #.to_s.split("\n").first.strip
         | 
| 45 | 
            +
                  end
         | 
| 39 46 | 
             
                  opts.on( '-t', '--test', "Test credentials only, does not update stored credentials for the appliance." ) do
         | 
| 40 47 | 
             
                    options[:test_only] = true
         | 
| 41 48 | 
             
                  end
         | 
| @@ -178,7 +178,7 @@ module Morpheus::Cli::OptionSourceHelper | |
| 178 178 | 
             
              # todo: some other common ones, accounts (tenants), etc.
         | 
| 179 179 | 
             
              # todo: a generic set of parse and find methods like 
         | 
| 180 180 | 
             
              # like this:
         | 
| 181 | 
            -
              def parse_option_source_id_list(option_source, id_list, api_params={}, refresh=false)
         | 
| 181 | 
            +
              def parse_option_source_id_list(option_source, id_list, api_params={}, refresh=false, allow_any_id=false)
         | 
| 182 182 | 
             
                option_source_label = option_source.to_s # .capitalize
         | 
| 183 183 | 
             
                option_data = load_option_source_data(option_source, api_params, refresh)
         | 
| 184 184 | 
             
                found_ids = []
         | 
| @@ -189,9 +189,8 @@ module Morpheus::Cli::OptionSourceHelper | |
| 189 189 | 
             
                    # never match blank nil or empty strings
         | 
| 190 190 | 
             
                    print_red_alert "#{option_source_label} cannot be not found by with a blank id!"
         | 
| 191 191 | 
             
                    return nil
         | 
| 192 | 
            -
                   | 
| 193 | 
            -
             | 
| 194 | 
            -
                  #   found_ids << record_id
         | 
| 192 | 
            +
                  elsif allow_any_id && record_id.to_s =~ /\A\d{1,}\Z/
         | 
| 193 | 
            +
                    found_ids << record_id.to_i
         | 
| 195 194 | 
             
                  else
         | 
| 196 195 | 
             
                    # search with in a presedence by value, then name, then id (usually same as value)
         | 
| 197 196 | 
             
                    # exact match on value first.
         | 
| @@ -228,28 +227,28 @@ module Morpheus::Cli::OptionSourceHelper | |
| 228 227 | 
             
                return found_ids
         | 
| 229 228 | 
             
              end
         | 
| 230 229 |  | 
| 231 | 
            -
              def parse_cloud_id_list(id_list, api_params={}, refresh=false)
         | 
| 232 | 
            -
                parse_option_source_id_list('clouds', id_list, api_params, refresh)
         | 
| 230 | 
            +
              def parse_cloud_id_list(id_list, api_params={}, refresh=false, allow_any_id=false)
         | 
| 231 | 
            +
                parse_option_source_id_list('clouds', id_list, api_params, refresh, allow_any_id)
         | 
| 233 232 | 
             
              end
         | 
| 234 233 |  | 
| 235 | 
            -
              def parse_group_id_list(id_list, api_params={}, refresh=false)
         | 
| 236 | 
            -
                parse_option_source_id_list('groups', id_list, api_params, refresh)
         | 
| 234 | 
            +
              def parse_group_id_list(id_list, api_params={}, refresh=false, allow_any_id=false)
         | 
| 235 | 
            +
                parse_option_source_id_list('groups', id_list, api_params, refresh, allow_any_id)
         | 
| 237 236 | 
             
              end
         | 
| 238 237 |  | 
| 239 | 
            -
              def parse_user_id_list(id_list, api_params={}, refresh=false)
         | 
| 240 | 
            -
                parse_option_source_id_list('users', id_list, api_params, refresh)
         | 
| 238 | 
            +
              def parse_user_id_list(id_list, api_params={}, refresh=false, allow_any_id=false)
         | 
| 239 | 
            +
                parse_option_source_id_list('users', id_list, api_params, refresh, allow_any_id)
         | 
| 241 240 | 
             
              end
         | 
| 242 241 |  | 
| 243 | 
            -
              def parse_tenant_id_list(id_list, api_params={}, refresh=false)
         | 
| 244 | 
            -
                parse_option_source_id_list('allTenants', id_list, api_params, refresh)
         | 
| 242 | 
            +
              def parse_tenant_id_list(id_list, api_params={}, refresh=false, allow_any_id=false)
         | 
| 243 | 
            +
                parse_option_source_id_list('allTenants', id_list, api_params, refresh, allow_any_id)
         | 
| 245 244 | 
             
              end
         | 
| 246 245 |  | 
| 247 | 
            -
              # def parse_blueprints_id_list(id_list)
         | 
| 248 | 
            -
              #   parse_option_source_id_list('blueprints', id_list, api_params, refresh)
         | 
| 246 | 
            +
              # def parse_blueprints_id_list(id_list, api_params={}, refresh=false, allow_any_id=false)
         | 
| 247 | 
            +
              #   parse_option_source_id_list('blueprints', id_list, api_params, refresh, allow_any_id)
         | 
| 249 248 | 
             
              # end
         | 
| 250 249 |  | 
| 251 | 
            -
              def parse_project_id_list(id_list, api_params={}, refresh=false)
         | 
| 252 | 
            -
                parse_option_source_id_list('projects', id_list, api_params, refresh)
         | 
| 250 | 
            +
              def parse_project_id_list(id_list, api_params={}, refresh=false, allow_any_id=false)
         | 
| 251 | 
            +
                parse_option_source_id_list('projects', id_list, api_params, refresh, allow_any_id)
         | 
| 253 252 | 
             
              end
         | 
| 254 253 |  | 
| 255 254 | 
             
            end
         | 
| @@ -228,7 +228,8 @@ module Morpheus::Cli::PrintHelper | |
| 228 228 | 
             
                out << cyan
         | 
| 229 229 | 
             
                if payload
         | 
| 230 230 | 
             
                  out << "\n"
         | 
| 231 | 
            -
                   | 
| 231 | 
            +
                  is_multipart = (payload.is_a?(Hash) && payload[:multipart] == true)
         | 
| 232 | 
            +
                  content_type = (headers && headers['Content-Type']) ? headers['Content-Type'] : (is_multipart ? 'multipart/form-data' : 'application/x-www-form-urlencoded')
         | 
| 232 233 | 
             
                  if content_type == 'application/json'
         | 
| 233 234 | 
             
                    if payload.is_a?(String)
         | 
| 234 235 | 
             
                      begin
         | 
| @@ -257,12 +258,21 @@ module Morpheus::Cli::PrintHelper | |
| 257 258 | 
             
                        out << payload
         | 
| 258 259 | 
             
                      end
         | 
| 259 260 | 
             
                    else
         | 
| 260 | 
            -
                      if content_type == 'application/x-www-form-urlencoded'
         | 
| 261 | 
            +
                      if content_type == 'application/x-www-form-urlencoded' || content_type.to_s.include?('multipart')
         | 
| 261 262 | 
             
                        body_str = payload.to_s
         | 
| 262 263 | 
             
                        begin
         | 
| 264 | 
            +
                          payload.delete(:multipart) if payload.is_a?(Hash)
         | 
| 265 | 
            +
                          # puts "grailsifying it!"
         | 
| 266 | 
            +
                          payload = Morpheus::RestClient.grails_params(payload)
         | 
| 267 | 
            +
                          payload.each do |k,v|
         | 
| 268 | 
            +
                            if v.is_a?(File)
         | 
| 269 | 
            +
                              payload[k] = "@#{v.path}"
         | 
| 270 | 
            +
                              payload[k] = v.path
         | 
| 271 | 
            +
                            end
         | 
| 272 | 
            +
                          end
         | 
| 263 273 | 
             
                          body_str = URI.encode_www_form(payload)
         | 
| 264 274 | 
             
                        rescue => ex
         | 
| 265 | 
            -
                           | 
| 275 | 
            +
                          raise ex
         | 
| 266 276 | 
             
                        end
         | 
| 267 277 | 
             
                        if options[:scrub]
         | 
| 268 278 | 
             
                          out << Morpheus::Logging.scrub_message(body_str)
         | 
| @@ -273,7 +283,7 @@ module Morpheus::Cli::PrintHelper | |
| 273 283 | 
             
                        if options[:scrub]
         | 
| 274 284 | 
             
                          out << Morpheus::Logging.scrub_message(payload)
         | 
| 275 285 | 
             
                        else
         | 
| 276 | 
            -
                          out << payload
         | 
| 286 | 
            +
                          out << payload.to_s
         | 
| 277 287 | 
             
                        end
         | 
| 278 288 | 
             
                      end
         | 
| 279 289 | 
             
                    end
         | 
| @@ -327,7 +337,9 @@ module Morpheus::Cli::PrintHelper | |
| 327 337 | 
             
                    else
         | 
| 328 338 | 
             
                      out << "  -d '#{payload}'"
         | 
| 329 339 | 
             
                    end
         | 
| 340 | 
            +
                    out << "\n"
         | 
| 330 341 | 
             
                  else
         | 
| 342 | 
            +
                    is_multipart = (payload.is_a?(Hash) && payload[:multipart] == true)
         | 
| 331 343 | 
             
                    content_type = headers['Content-Type'] || 'application/x-www-form-urlencoded'
         | 
| 332 344 |  | 
| 333 345 | 
             
                    if payload.is_a?(File)
         | 
| @@ -337,21 +349,22 @@ module Morpheus::Cli::PrintHelper | |
| 337 349 | 
             
                      out << "  -d @#{payload.path}"
         | 
| 338 350 | 
             
                    elsif payload.is_a?(String)
         | 
| 339 351 | 
             
                      out << "  -d '#{payload}'"
         | 
| 340 | 
            -
                     | 
| 341 | 
            -
                      if  | 
| 342 | 
            -
             | 
| 343 | 
            -
             | 
| 344 | 
            -
             | 
| 345 | 
            -
                         | 
| 346 | 
            -
                           | 
| 352 | 
            +
                    elsif payload.respond_to?(:map)
         | 
| 353 | 
            +
                      payload.delete(:multipart) if payload.is_a?(Hash)
         | 
| 354 | 
            +
                      # puts "grailsifying it!"
         | 
| 355 | 
            +
                      payload = Morpheus::RestClient.grails_params(payload)
         | 
| 356 | 
            +
                      payload.each do |k,v|
         | 
| 357 | 
            +
                        if v.is_a?(File)
         | 
| 358 | 
            +
                          out << "  -F '#{k}=@#{v.path}"
         | 
| 359 | 
            +
                        else
         | 
| 360 | 
            +
                          out << "  -d '#{URI.encode_www_form({(k) => v})}'"
         | 
| 347 361 | 
             
                        end
         | 
| 348 | 
            -
                        out << " | 
| 349 | 
            -
                      else
         | 
| 350 | 
            -
                        out << "  -d '#{payload}'"
         | 
| 362 | 
            +
                        out << "\n"
         | 
| 351 363 | 
             
                      end
         | 
| 364 | 
            +
                      #body_str = URI.encode_www_form(payload)
         | 
| 365 | 
            +
                      # out << "  -d '#{body_str}'"
         | 
| 352 366 | 
             
                    end
         | 
| 353 367 | 
             
                  end
         | 
| 354 | 
            -
                  out << "\n"
         | 
| 355 368 | 
             
                else
         | 
| 356 369 | 
             
                  out << "\n"
         | 
| 357 370 | 
             
                end
         | 
| @@ -431,12 +444,13 @@ module Morpheus::Cli::PrintHelper | |
| 431 444 | 
             
                out = ""
         | 
| 432 445 | 
             
                bars = []
         | 
| 433 446 | 
             
                percent = 0
         | 
| 447 | 
            +
                percent_sigdig = opts[:percent_sigdig] || 2
         | 
| 434 448 | 
             
                if max_value.to_i == 0
         | 
| 435 449 | 
             
                  percent = 0
         | 
| 436 450 | 
             
                else
         | 
| 437 451 | 
             
                  percent = ((used_value.to_f / max_value.to_f) * 100)
         | 
| 438 452 | 
             
                end
         | 
| 439 | 
            -
                percent_label = ((used_value.nil? || max_value.to_f == 0.0) ? "n/a" : "#{percent.round( | 
| 453 | 
            +
                percent_label = ((used_value.nil? || max_value.to_f == 0.0) ? "n/a" : "#{percent.round(percent_sigdig)}%").rjust(6, ' ')
         | 
| 440 454 | 
             
                bar_display = ""
         | 
| 441 455 | 
             
                if percent > 100
         | 
| 442 456 | 
             
                  max_bars.times { bars << "|" }
         | 
| @@ -674,7 +688,7 @@ module Morpheus::Cli::PrintHelper | |
| 674 688 | 
             
                  else
         | 
| 675 689 | 
             
                    # so let's use the passed in column definitions instead of the raw data properties
         | 
| 676 690 | 
             
                    # columns = options[:include_fields]
         | 
| 677 | 
            -
                    new_columns =  | 
| 691 | 
            +
                    new_columns = {}
         | 
| 678 692 | 
             
                    options[:include_fields].each do |f|
         | 
| 679 693 | 
             
                      matching_column = nil
         | 
| 680 694 | 
             
                      # column definitions vary right now, array of symbols/strings/hashes or perhaps a single hash
         | 
| @@ -692,7 +706,7 @@ module Morpheus::Cli::PrintHelper | |
| 692 706 | 
             
                          matching_column = columns[matching_key]
         | 
| 693 707 | 
             
                        end
         | 
| 694 708 | 
             
                      end
         | 
| 695 | 
            -
                      new_columns  | 
| 709 | 
            +
                      new_columns[f] = matching_column ? matching_column : f
         | 
| 696 710 | 
             
                    end
         | 
| 697 711 | 
             
                    columns = new_columns
         | 
| 698 712 | 
             
                  end
         | 
| @@ -720,6 +734,7 @@ module Morpheus::Cli::PrintHelper | |
| 720 734 | 
             
                  columns.each do |column_def|
         | 
| 721 735 | 
             
                    # r << column_def.display_method.respond_to?(:call) ? column_def.display_method.call(row_data) : get_object_value(row_data, column_def.display_method)
         | 
| 722 736 | 
             
                    value = column_def.display_method.call(row_data)        
         | 
| 737 | 
            +
                    value = JSON.fast_generate(value) if value.is_a?(Hash) || value.is_a?(Array)
         | 
| 723 738 | 
             
                    row << value
         | 
| 724 739 | 
             
                  end
         | 
| 725 740 | 
             
                  rows << row
         | 
| @@ -802,6 +817,7 @@ module Morpheus::Cli::PrintHelper | |
| 802 817 | 
             
                      columns.each do |column_def|
         | 
| 803 818 | 
             
                        # r << column_def.display_method.respond_to?(:call) ? column_def.display_method.call(row_data) : get_object_value(row_data, column_def.display_method)
         | 
| 804 819 | 
             
                        value = column_def.display_method.call(row_data)        
         | 
| 820 | 
            +
                        value = JSON.fast_generate(value) if value.is_a?(Hash) || value.is_a?(Array)
         | 
| 805 821 | 
             
                        row << value
         | 
| 806 822 | 
             
                      end
         | 
| 807 823 | 
             
                      rows << row
         | 
| @@ -879,6 +895,7 @@ module Morpheus::Cli::PrintHelper | |
| 879 895 | 
             
                  label = label.upcase if ALL_LABELS_UPCASE
         | 
| 880 896 | 
             
                  # value = get_object_value(obj, column_def.display_method)
         | 
| 881 897 | 
             
                  value = column_def.display_method.call(obj)
         | 
| 898 | 
            +
                  value = JSON.fast_generate(value) if value.is_a?(Hash) || value.is_a?(Array)
         | 
| 882 899 | 
             
                  if label.size > max_label_width
         | 
| 883 900 | 
             
                    max_label_width = label.size
         | 
| 884 901 | 
             
                  end
         | 
| @@ -1069,6 +1086,7 @@ module Morpheus::Cli::PrintHelper | |
| 1069 1086 | 
             
                    column_defs.each do |column_def|
         | 
| 1070 1087 | 
             
                      label = column_def.label
         | 
| 1071 1088 | 
             
                      value = column_def.display_method.call(obj)
         | 
| 1089 | 
            +
                      value = value.is_a?(String) ? value : JSON.fast_generate(value)
         | 
| 1072 1090 | 
             
                      # value = get_object_value(obj, column_def)
         | 
| 1073 1091 | 
             
                      if do_quotes
         | 
| 1074 1092 | 
             
                        cells << quote_csv_value(value)
         | 
| @@ -696,7 +696,7 @@ module Morpheus::Cli::ProvisioningHelper | |
| 696 696 | 
             
                # prompt for service plan
         | 
| 697 697 | 
             
                plan_id = nil
         | 
| 698 698 | 
             
                service_plan = nil
         | 
| 699 | 
            -
                service_plans_json =  | 
| 699 | 
            +
                service_plans_json = instances_interface.service_plans({zoneId: cloud_id, layoutId: layout['id'], siteId: group_id})
         | 
| 700 700 | 
             
                service_plans = service_plans_json["plans"]
         | 
| 701 701 | 
             
                if locked_fields.include?('plan.id')
         | 
| 702 702 | 
             
                  plan_id = options[:options]['plan']['id'] rescue nil
         | 
| @@ -764,7 +764,7 @@ module Morpheus::Cli::ProvisioningHelper | |
| 764 764 | 
             
                    # pluck out the resourcePoolId option type to prompt for
         | 
| 765 765 | 
             
                    resource_pool_option_type = option_type_list.find {|opt| ['resourcePool','resourcePoolId','azureResourceGroupId'].include?(opt['fieldName']) }
         | 
| 766 766 | 
             
                    option_type_list = option_type_list.reject {|opt| ['resourcePool','resourcePoolId','azureResourceGroupId'].include?(opt['fieldName']) }
         | 
| 767 | 
            -
                    resource_pool_options =  | 
| 767 | 
            +
                    resource_pool_options = options_interface.options_for_source('zonePools', {groupId: group_id, siteId: group_id, zoneId: cloud_id, cloudId: cloud_id, instanceTypeId: instance_type['id'], planId: service_plan["id"], layoutId: layout["id"]})['data']
         | 
| 768 768 | 
             
                    resource_pool = resource_pool_options.find {|opt| opt['id'] == options[:resource_pool].to_i} if options[:resource_pool]
         | 
| 769 769 |  | 
| 770 770 | 
             
                    if resource_pool
         | 
| @@ -1409,7 +1409,7 @@ module Morpheus::Cli::ProvisioningHelper | |
| 1409 1409 | 
             
                  if plan_info['addVolumes']
         | 
| 1410 1410 | 
             
                    volume_index = current_volumes.size
         | 
| 1411 1411 | 
             
                    has_another_volume = options[:options] && options[:options]["dataVolume#{volume_index}"]
         | 
| 1412 | 
            -
                    add_another_volume = has_another_volume || (!no_prompt && Morpheus::Cli::OptionTypes.confirm("Add data volume?"))
         | 
| 1412 | 
            +
                    add_another_volume = has_another_volume || (!no_prompt && Morpheus::Cli::OptionTypes.confirm("Add data volume?", {:default => false}))
         | 
| 1413 1413 | 
             
                    while add_another_volume do
         | 
| 1414 1414 | 
             
                        #puts "Configure Data #{volume_index} Volume"
         | 
| 1415 1415 |  | 
| @@ -0,0 +1,246 @@ | |
| 1 | 
            +
            require 'morpheus/cli/mixins/print_helper'
         | 
| 2 | 
            +
            # Provides common finder methods for VDI Pool management commands
         | 
| 3 | 
            +
            module Morpheus::Cli::VdiHelper
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              def self.included(klass)
         | 
| 6 | 
            +
                klass.send :include, Morpheus::Cli::PrintHelper
         | 
| 7 | 
            +
              end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              ## VDI Pools
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              def vdi_pools_interface
         | 
| 12 | 
            +
                raise "#{self.class} has not defined @vdi_pools_interface" if @vdi_pools_interface.nil?
         | 
| 13 | 
            +
                @vdi_pools_interface
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              def vdi_pool_object_key
         | 
| 17 | 
            +
                'vdiPool'
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              def vdi_pool_list_key
         | 
| 21 | 
            +
                'vdiPools'
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
              def find_vdi_pool_by_name_or_id(val)
         | 
| 25 | 
            +
                if val.to_s =~ /\A\d{1,}\Z/
         | 
| 26 | 
            +
                  return find_vdi_pool_by_id(val)
         | 
| 27 | 
            +
                else
         | 
| 28 | 
            +
                  return find_vdi_pool_by_name(val)
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
              def find_vdi_pool_by_id(id)
         | 
| 33 | 
            +
                begin
         | 
| 34 | 
            +
                  json_response = vdi_pools_interface.get(id.to_i)
         | 
| 35 | 
            +
                  return json_response[vdi_pool_object_key]
         | 
| 36 | 
            +
                rescue RestClient::Exception => e
         | 
| 37 | 
            +
                  if e.response && e.response.code == 404
         | 
| 38 | 
            +
                    print_red_alert "VDI Pool not found by id '#{id}'"
         | 
| 39 | 
            +
                  else
         | 
| 40 | 
            +
                    raise e
         | 
| 41 | 
            +
                  end
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
              end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
              def find_vdi_pool_by_name(name)
         | 
| 46 | 
            +
                json_response = vdi_pools_interface.list({name: name.to_s})
         | 
| 47 | 
            +
                vdi_pools = json_response[vdi_pool_list_key]
         | 
| 48 | 
            +
                if vdi_pools.empty?
         | 
| 49 | 
            +
                  print_red_alert "VDI Pool not found by name '#{name}'"
         | 
| 50 | 
            +
                  return nil
         | 
| 51 | 
            +
                elsif vdi_pools.size > 1
         | 
| 52 | 
            +
                  print_red_alert "#{vdi_pools.size} VDI Pools found by name '#{name}'"
         | 
| 53 | 
            +
                  print_error "\n"
         | 
| 54 | 
            +
                  puts_error as_pretty_table(vdi_pools, [:id, :name], {color:red})
         | 
| 55 | 
            +
                  print_red_alert "Try using ID instead"
         | 
| 56 | 
            +
                  print_error reset,"\n"
         | 
| 57 | 
            +
                  return nil
         | 
| 58 | 
            +
                else
         | 
| 59 | 
            +
                  return vdi_pools[0]
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
              end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
              def format_vdi_pool_status(vdi_pool, return_color=cyan)
         | 
| 64 | 
            +
                out = ""
         | 
| 65 | 
            +
                status_string = vdi_pool['status'].to_s.downcase
         | 
| 66 | 
            +
                if status_string
         | 
| 67 | 
            +
                  if ['available'].include?(status_string)
         | 
| 68 | 
            +
                    out << "#{green}#{status_string.upcase}"
         | 
| 69 | 
            +
                  elsif ['unavailable'].include?(status_string)
         | 
| 70 | 
            +
                    out << "#{red}#{status_string.upcase}"
         | 
| 71 | 
            +
                  else
         | 
| 72 | 
            +
                    out << "#{return_color}#{status_string.upcase}"
         | 
| 73 | 
            +
                  end
         | 
| 74 | 
            +
                end
         | 
| 75 | 
            +
                out + return_color
         | 
| 76 | 
            +
              end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
              ## VDI Allocations
         | 
| 79 | 
            +
             | 
| 80 | 
            +
              def vdi_allocations_interface
         | 
| 81 | 
            +
                raise "#{self.class} has not defined @vdi_allocations_interface" if @vdi_allocations_interface.nil?
         | 
| 82 | 
            +
                @vdi_allocations_interface
         | 
| 83 | 
            +
              end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
              def vdi_allocation_object_key
         | 
| 86 | 
            +
                'vdiAllocation'
         | 
| 87 | 
            +
              end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
              def vdi_allocation_list_key
         | 
| 90 | 
            +
                'vdiAllocations'
         | 
| 91 | 
            +
              end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
              def find_vdi_allocation_by_id(id)
         | 
| 94 | 
            +
                begin
         | 
| 95 | 
            +
                  json_response = vdi_allocations_interface.get(id.to_i)
         | 
| 96 | 
            +
                  return json_response[vdi_allocation_object_key]
         | 
| 97 | 
            +
                rescue RestClient::Exception => e
         | 
| 98 | 
            +
                  if e.response && e.response.code == 404
         | 
| 99 | 
            +
                    print_red_alert "VDI Allocation not found by id '#{id}'"
         | 
| 100 | 
            +
                  else
         | 
| 101 | 
            +
                    raise e
         | 
| 102 | 
            +
                  end
         | 
| 103 | 
            +
                end
         | 
| 104 | 
            +
              end
         | 
| 105 | 
            +
             | 
| 106 | 
            +
              def format_vdi_allocation_status(vdi_allocation, return_color=cyan)
         | 
| 107 | 
            +
                out = ""
         | 
| 108 | 
            +
                status_string = vdi_allocation['status'].to_s.downcase
         | 
| 109 | 
            +
                if status_string
         | 
| 110 | 
            +
                  if ['available'].include?(status_string)
         | 
| 111 | 
            +
                    out << "#{green}#{status_string.upcase}"
         | 
| 112 | 
            +
                  # elsif ['preparing'].include?(status_string)
         | 
| 113 | 
            +
                  #   out << "#{yellow}#{status_string.upcase}"
         | 
| 114 | 
            +
                  # elsif ['reserved', 'shutdown'].include?(status_string)
         | 
| 115 | 
            +
                  #   out << "#{yellow}#{status_string.upcase}"
         | 
| 116 | 
            +
                  elsif ['failed'].include?(status_string)
         | 
| 117 | 
            +
                    out << "#{red}#{status_string.upcase}"
         | 
| 118 | 
            +
                  else
         | 
| 119 | 
            +
                    out << "#{return_color}#{status_string.upcase}"
         | 
| 120 | 
            +
                  end
         | 
| 121 | 
            +
                end
         | 
| 122 | 
            +
                out + return_color
         | 
| 123 | 
            +
              end
         | 
| 124 | 
            +
             | 
| 125 | 
            +
              def get_available_vdi_apps(refresh=false)
         | 
| 126 | 
            +
                if !@available_vdi_apps || refresh
         | 
| 127 | 
            +
                  @available_vdi_apps = @vdi_apps_interface.list({max:-1})['vdiApps'] #  || []
         | 
| 128 | 
            +
                end
         | 
| 129 | 
            +
                return @available_vdi_apps
         | 
| 130 | 
            +
              end
         | 
| 131 | 
            +
              
         | 
| 132 | 
            +
              def get_vdi_app_by_name_or_code(name)
         | 
| 133 | 
            +
                return get_available_vdi_apps().find { |z| z['name'].downcase == name.downcase || z['code'].downcase == name.downcase}
         | 
| 134 | 
            +
              end
         | 
| 135 | 
            +
             | 
| 136 | 
            +
              ## VDI Apps
         | 
| 137 | 
            +
             | 
| 138 | 
            +
              def vdi_apps_interface
         | 
| 139 | 
            +
                raise "#{self.class} has not defined @vdi_apps_interface" if @vdi_apps_interface.nil?
         | 
| 140 | 
            +
                @vdi_apps_interface
         | 
| 141 | 
            +
              end
         | 
| 142 | 
            +
             | 
| 143 | 
            +
              def vdi_app_object_key
         | 
| 144 | 
            +
                'vdiApp'
         | 
| 145 | 
            +
              end
         | 
| 146 | 
            +
             | 
| 147 | 
            +
              def vdi_app_list_key
         | 
| 148 | 
            +
                'vdiApps'
         | 
| 149 | 
            +
              end
         | 
| 150 | 
            +
             | 
| 151 | 
            +
              def find_vdi_app_by_name_or_id(val)
         | 
| 152 | 
            +
                if val.to_s =~ /\A\d{1,}\Z/
         | 
| 153 | 
            +
                  return find_vdi_app_by_id(val)
         | 
| 154 | 
            +
                else
         | 
| 155 | 
            +
                  return find_vdi_app_by_name(val)
         | 
| 156 | 
            +
                end
         | 
| 157 | 
            +
              end
         | 
| 158 | 
            +
             | 
| 159 | 
            +
              def find_vdi_app_by_id(id)
         | 
| 160 | 
            +
                begin
         | 
| 161 | 
            +
                  json_response = vdi_apps_interface.get(id.to_i)
         | 
| 162 | 
            +
                  return json_response[vdi_app_object_key]
         | 
| 163 | 
            +
                rescue RestClient::Exception => e
         | 
| 164 | 
            +
                  if e.response && e.response.code == 404
         | 
| 165 | 
            +
                    print_red_alert "VDI App not found by id '#{id}'"
         | 
| 166 | 
            +
                  else
         | 
| 167 | 
            +
                    raise e
         | 
| 168 | 
            +
                  end
         | 
| 169 | 
            +
                end
         | 
| 170 | 
            +
              end
         | 
| 171 | 
            +
             | 
| 172 | 
            +
              def find_vdi_app_by_name(name)
         | 
| 173 | 
            +
                json_response = vdi_apps_interface.list({name: name.to_s})
         | 
| 174 | 
            +
                vdi_apps = json_response[vdi_app_list_key]
         | 
| 175 | 
            +
                if vdi_apps.empty?
         | 
| 176 | 
            +
                  print_red_alert "VDI App not found by name '#{name}'"
         | 
| 177 | 
            +
                  return nil
         | 
| 178 | 
            +
                elsif vdi_apps.size > 1
         | 
| 179 | 
            +
                  print_red_alert "#{vdi_apps.size} VDI App found by name '#{name}'"
         | 
| 180 | 
            +
                  print_error "\n"
         | 
| 181 | 
            +
                  puts_error as_pretty_table(vdi_apps, {"ID" => 'id', "NAME" => 'name'}, {color:red})
         | 
| 182 | 
            +
                  print_red_alert "Try using ID instead"
         | 
| 183 | 
            +
                  print_error reset,"\n"
         | 
| 184 | 
            +
                  return nil
         | 
| 185 | 
            +
                else
         | 
| 186 | 
            +
                  return vdi_apps[0]
         | 
| 187 | 
            +
                end
         | 
| 188 | 
            +
              end
         | 
| 189 | 
            +
             | 
| 190 | 
            +
             | 
| 191 | 
            +
              ## VDI Gateways
         | 
| 192 | 
            +
             | 
| 193 | 
            +
              def vdi_gateways_interface
         | 
| 194 | 
            +
                raise "#{self.class} has not defined @vdi_gateways_interface" if @vdi_gateways_interface.nil?
         | 
| 195 | 
            +
                @vdi_gateways_interface
         | 
| 196 | 
            +
              end
         | 
| 197 | 
            +
             | 
| 198 | 
            +
              def vdi_gateway_object_key
         | 
| 199 | 
            +
                'vdiGateway'
         | 
| 200 | 
            +
              end
         | 
| 201 | 
            +
             | 
| 202 | 
            +
              def vdi_gateway_list_key
         | 
| 203 | 
            +
                'vdiGateways'
         | 
| 204 | 
            +
              end
         | 
| 205 | 
            +
             | 
| 206 | 
            +
              def find_vdi_gateway_by_name_or_id(val)
         | 
| 207 | 
            +
                if val.to_s =~ /\A\d{1,}\Z/
         | 
| 208 | 
            +
                  return find_vdi_gateway_by_id(val)
         | 
| 209 | 
            +
                else
         | 
| 210 | 
            +
                  return find_vdi_gateway_by_name(val)
         | 
| 211 | 
            +
                end
         | 
| 212 | 
            +
              end
         | 
| 213 | 
            +
             | 
| 214 | 
            +
              def find_vdi_gateway_by_id(id)
         | 
| 215 | 
            +
                begin
         | 
| 216 | 
            +
                  json_response = vdi_gateways_interface.get(id.to_i)
         | 
| 217 | 
            +
                  return json_response[vdi_gateway_object_key]
         | 
| 218 | 
            +
                rescue RestClient::Exception => e
         | 
| 219 | 
            +
                  if e.response && e.response.code == 404
         | 
| 220 | 
            +
                    print_red_alert "VDI Gateway not found by id '#{id}'"
         | 
| 221 | 
            +
                  else
         | 
| 222 | 
            +
                    raise e
         | 
| 223 | 
            +
                  end
         | 
| 224 | 
            +
                end
         | 
| 225 | 
            +
              end
         | 
| 226 | 
            +
             | 
| 227 | 
            +
              def find_vdi_gateway_by_name(name)
         | 
| 228 | 
            +
                json_response = vdi_gateways_interface.list({name: name.to_s})
         | 
| 229 | 
            +
                vdi_gateways = json_response[vdi_gateway_list_key]
         | 
| 230 | 
            +
                if vdi_gateways.empty?
         | 
| 231 | 
            +
                  print_red_alert "VDI Gateway not found by name '#{name}'"
         | 
| 232 | 
            +
                  return nil
         | 
| 233 | 
            +
                elsif vdi_gateways.size > 1
         | 
| 234 | 
            +
                  print_red_alert "#{vdi_gateways.size} VDI Gateway found by name '#{name}'"
         | 
| 235 | 
            +
                  print_error "\n"
         | 
| 236 | 
            +
                  puts_error as_pretty_table(vdi_gateways, {"ID" => 'id', "NAME" => 'name'}, {color:red})
         | 
| 237 | 
            +
                  print_red_alert "Try using ID instead"
         | 
| 238 | 
            +
                  print_error reset,"\n"
         | 
| 239 | 
            +
                  return nil
         | 
| 240 | 
            +
                else
         | 
| 241 | 
            +
                  return vdi_gateways[0]
         | 
| 242 | 
            +
                end
         | 
| 243 | 
            +
              end
         | 
| 244 | 
            +
             | 
| 245 | 
            +
             | 
| 246 | 
            +
            end
         |