morpheus-cli 6.1.2 → 6.2.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 +8 -0
 - data/lib/morpheus/api/backup_jobs_interface.rb +4 -0
 - data/lib/morpheus/api/backup_restores_interface.rb +23 -0
 - data/lib/morpheus/api/backup_results_interface.rb +28 -0
 - data/lib/morpheus/api/backups_interface.rb +5 -4
 - data/lib/morpheus/api/monitoring_settings_interface.rb +0 -4
 - data/lib/morpheus/cli/cli_command.rb +176 -46
 - data/lib/morpheus/cli/commands/appliance_settings_command.rb +7 -19
 - data/lib/morpheus/cli/commands/apps.rb +1 -1
 - data/lib/morpheus/cli/commands/backup_jobs_command.rb +78 -20
 - data/lib/morpheus/cli/commands/backup_restores_command.rb +144 -0
 - data/lib/morpheus/cli/commands/backup_results_command.rb +149 -0
 - data/lib/morpheus/cli/commands/backups_command.rb +215 -93
 - data/lib/morpheus/cli/commands/hosts.rb +15 -2
 - data/lib/morpheus/cli/commands/instances.rb +18 -3
 - data/lib/morpheus/cli/commands/monitoring_settings.rb +0 -16
 - data/lib/morpheus/cli/commands/plugins.rb +2 -1
 - data/lib/morpheus/cli/commands/roles.rb +9 -9
 - data/lib/morpheus/cli/commands/service_catalog_command.rb +50 -83
 - data/lib/morpheus/cli/commands/user_sources_command.rb +36 -8
 - data/lib/morpheus/cli/commands/view.rb +20 -20
 - data/lib/morpheus/cli/mixins/backups_helper.rb +58 -0
 - data/lib/morpheus/cli/mixins/print_helper.rb +27 -4
 - data/lib/morpheus/cli/option_types.rb +10 -7
 - data/lib/morpheus/cli/version.rb +1 -1
 - data/lib/morpheus/formatters.rb +1 -1
 - data/lib/morpheus/routes.rb +18 -3
 - metadata +6 -2
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 3ede124df9259964d52e159be3a4097dd21987e35a20423ef81c63efb65be54d
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 270fb5f083ecb5b7643aef13bb2b37e5e3ee02fd706ded8c394635376bbda14b
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 86475908b6b602bcb9185e1e4a3c554f7fdb581e010e6e7e49e075124eb24d087bde16d90cb07b8dd8cb944da9d1f7de34f9d3d4252c9859811c4e9acd51eb7c
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: e1c6ed1cb7a06ec481687e516582131348a3f4292c618ebbe1a81c3b422e17d49f8ca85e65283d027e1516dd28c2ac35820691b90435a3933474c0ac44308c74
         
     | 
    
        data/Dockerfile
    CHANGED
    
    
| 
         @@ -862,6 +862,14 @@ class Morpheus::APIClient 
     | 
|
| 
       862 
862 
     | 
    
         
             
                Morpheus::BackupJobsInterface.new(common_interface_options).setopts(@options)
         
     | 
| 
       863 
863 
     | 
    
         
             
              end
         
     | 
| 
       864 
864 
     | 
    
         | 
| 
      
 865 
     | 
    
         
            +
              def backup_results
         
     | 
| 
      
 866 
     | 
    
         
            +
                Morpheus::BackupResultsInterface.new(common_interface_options).setopts(@options)
         
     | 
| 
      
 867 
     | 
    
         
            +
              end
         
     | 
| 
      
 868 
     | 
    
         
            +
             
     | 
| 
      
 869 
     | 
    
         
            +
              def backup_restores
         
     | 
| 
      
 870 
     | 
    
         
            +
                Morpheus::BackupRestoresInterface.new(common_interface_options).setopts(@options)
         
     | 
| 
      
 871 
     | 
    
         
            +
              end
         
     | 
| 
      
 872 
     | 
    
         
            +
             
     | 
| 
       865 
873 
     | 
    
         
             
              def backup_services
         
     | 
| 
       866 
874 
     | 
    
         
             
                Morpheus::BackupServicesInterface.new(common_interface_options).setopts(@options)
         
     | 
| 
       867 
875 
     | 
    
         
             
              end
         
     | 
| 
         @@ -6,4 +6,8 @@ class Morpheus::BackupJobsInterface < Morpheus::RestInterface 
     | 
|
| 
       6 
6 
     | 
    
         
             
                "/api/backups/jobs"
         
     | 
| 
       7 
7 
     | 
    
         
             
              end
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
      
 9 
     | 
    
         
            +
              def execute_job(id, payload={}, params={}, headers={})
         
     | 
| 
      
 10 
     | 
    
         
            +
                execute(method: :post, url: "#{base_path}/#{CGI::escape(id.to_s)}/execute", params: params, payload: payload, headers: headers)
         
     | 
| 
      
 11 
     | 
    
         
            +
              end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
       9 
13 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,23 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'morpheus/api/api_client'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            class Morpheus::BackupRestoresInterface < Morpheus::APIClient
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
              def base_path
         
     | 
| 
      
 6 
     | 
    
         
            +
                "/api/backups/restores"
         
     | 
| 
      
 7 
     | 
    
         
            +
              end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              def list(params={}, headers={})
         
     | 
| 
      
 10 
     | 
    
         
            +
                execute(method: :get, url: "#{base_path}", params: params, headers: headers)
         
     | 
| 
      
 11 
     | 
    
         
            +
              end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
              def get(id, params={}, headers={})
         
     | 
| 
      
 14 
     | 
    
         
            +
                validate_id!(id)
         
     | 
| 
      
 15 
     | 
    
         
            +
                execute(method: :get, url: "#{base_path}/#{CGI::escape(id.to_s)}", params: params, headers: headers)
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              def destroy(id, params = {}, headers={})
         
     | 
| 
      
 19 
     | 
    
         
            +
                validate_id!(id)
         
     | 
| 
      
 20 
     | 
    
         
            +
                execute(method: :delete, url: "#{base_path}/#{CGI::escape(id.to_s)}", params: params, headers: headers)
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,28 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'morpheus/api/api_client'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            class Morpheus::BackupResultsInterface < Morpheus::APIClient
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
              def base_path
         
     | 
| 
      
 6 
     | 
    
         
            +
                "/api/backups/results"
         
     | 
| 
      
 7 
     | 
    
         
            +
              end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              def list(params={}, headers={})
         
     | 
| 
      
 10 
     | 
    
         
            +
                execute(method: :get, url: "#{base_path}", params: params, headers: headers)
         
     | 
| 
      
 11 
     | 
    
         
            +
              end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
              def get(id, params={}, headers={})
         
     | 
| 
      
 14 
     | 
    
         
            +
                validate_id!(id)
         
     | 
| 
      
 15 
     | 
    
         
            +
                execute(method: :get, url: "#{base_path}/#{CGI::escape(id.to_s)}", params: params, headers: headers)
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              def cancel(id, payload={}, params={}, headers={})
         
     | 
| 
      
 19 
     | 
    
         
            +
                validate_id!(id)
         
     | 
| 
      
 20 
     | 
    
         
            +
                execute(method: :put, url: "#{base_path}/#{CGI::escape(id.to_s)}", params: params, payload: payload, headers: headers)
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
              def destroy(id, params = {}, headers={})
         
     | 
| 
      
 24 
     | 
    
         
            +
                validate_id!(id)
         
     | 
| 
      
 25 
     | 
    
         
            +
                execute(method: :delete, url: "#{base_path}/#{CGI::escape(id.to_s)}", params: params, headers: headers)
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -10,11 +10,12 @@ class Morpheus::BackupsInterface < Morpheus::RestInterface 
     | 
|
| 
       10 
10 
     | 
    
         
             
                execute(method: :post, url: "#{base_path}/create", params: params, payload: payload, headers: headers)
         
     | 
| 
       11 
11 
     | 
    
         
             
              end
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
     | 
    
         
            -
              def summary(params={})
         
     | 
| 
       14 
     | 
    
         
            -
                execute(method: :get, url: "#{base_path}/summary", params: params)
         
     | 
| 
      
 13 
     | 
    
         
            +
              def summary(params={}, headers={})
         
     | 
| 
      
 14 
     | 
    
         
            +
                execute(method: :get, url: "#{base_path}/summary", params: params, headers: headers)
         
     | 
| 
       15 
15 
     | 
    
         
             
              end
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
       17 
     | 
    
         
            -
              def  
     | 
| 
       18 
     | 
    
         
            -
                execute(method: : 
     | 
| 
      
 17 
     | 
    
         
            +
              def execute_backup(id, payload={}, params={}, headers={})
         
     | 
| 
      
 18 
     | 
    
         
            +
                execute(method: :post, url: "#{base_path}/#{CGI::escape(id.to_s)}/execute", params: params, payload: payload, headers: headers)
         
     | 
| 
       19 
19 
     | 
    
         
             
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
       20 
21 
     | 
    
         
             
            end
         
     | 
| 
         @@ -18,8 +18,4 @@ class Morpheus::MonitoringSettingsInterface < Morpheus::APIClient 
     | 
|
| 
       18 
18 
     | 
    
         
             
                execute(method: :put, url: "#{base_path}/service-now", payload: payload, params: params, headers: headers)
         
     | 
| 
       19 
19 
     | 
    
         
             
              end
         
     | 
| 
       20 
20 
     | 
    
         | 
| 
       21 
     | 
    
         
            -
              def update_new_relic(payload, params={}, headers={})
         
     | 
| 
       22 
     | 
    
         
            -
                execute(method: :put, url: "#{base_path}/new-relic", payload: payload, params: params, headers: headers)
         
     | 
| 
       23 
     | 
    
         
            -
              end
         
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
21 
     | 
    
         
             
            end
         
     | 
| 
         @@ -267,6 +267,11 @@ module Morpheus 
     | 
|
| 
       267 
267 
     | 
    
         
             
                    build_standard_post_options(opts, options, includes, excludes)
         
     | 
| 
       268 
268 
     | 
    
         
             
                  end
         
     | 
| 
       269 
269 
     | 
    
         | 
| 
      
 270 
     | 
    
         
            +
                  # todo: this can go away once every command is using execute_api()
         
     | 
| 
      
 271 
     | 
    
         
            +
                  def build_standard_add_many_options(opts, options, includes=[], excludes=[])
         
     | 
| 
      
 272 
     | 
    
         
            +
                    build_standard_post_options(opts, options, includes + [:payloads], excludes)
         
     | 
| 
      
 273 
     | 
    
         
            +
                  end
         
     | 
| 
      
 274 
     | 
    
         
            +
             
     | 
| 
       270 
275 
     | 
    
         
             
                  def build_standard_update_options(opts, options, includes=[], excludes=[])
         
     | 
| 
       271 
276 
     | 
    
         
             
                    build_standard_put_options(opts, options, includes, excludes)
         
     | 
| 
       272 
277 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -551,13 +556,14 @@ module Morpheus 
     | 
|
| 
       551 
556 
     | 
    
         
             
                            end
         
     | 
| 
       552 
557 
     | 
    
         
             
                          end
         
     | 
| 
       553 
558 
     | 
    
         
             
                        end if all_option_keys.include?(:payloads)
         
     | 
| 
       554 
     | 
    
         
            -
                        opts.on('-- 
     | 
| 
       555 
     | 
    
         
            -
                          options[: 
     | 
| 
      
 559 
     | 
    
         
            +
                        opts.on('--ignore-payload-errors', "Continue processing any remaining payloads if an error occurs. The default behavior is to stop processing when an error occurs.") do
         
     | 
| 
      
 560 
     | 
    
         
            +
                          options[:ignore_payload_errors] = true
         
     | 
| 
       556 
561 
     | 
    
         
             
                        end if all_option_keys.include?(:payloads)
         
     | 
| 
       557 
562 
     | 
    
         
             
                      when :payloads
         
     | 
| 
       558 
     | 
    
         
            -
                        # added  
     | 
| 
      
 563 
     | 
    
         
            +
                        # added with :payload too... just need it here to avoid unknown key error
         
     | 
| 
      
 564 
     | 
    
         
            +
                        # todo: remove this when every command supporting :payload is updated to use parse_payload(options) and execute_api(options)
         
     | 
| 
       559 
565 
     | 
    
         
             
                      when :list
         
     | 
| 
       560 
     | 
    
         
            -
                        opts.on( '-m', '--max MAX', "Max Results" ) do |val|
         
     | 
| 
      
 566 
     | 
    
         
            +
                        opts.on( '-m', '--max MAX', "Max Results (use -1 for all results)" ) do |val|
         
     | 
| 
       561 
567 
     | 
    
         
             
                          # api supports max=-1 for all at the moment..
         
     | 
| 
       562 
568 
     | 
    
         
             
                          if val.to_s == "all" || val.to_s == "-1"
         
     | 
| 
       563 
569 
     | 
    
         
             
                            options[:max] = "-1"
         
     | 
| 
         @@ -1365,6 +1371,11 @@ module Morpheus 
     | 
|
| 
       1365 
1371 
     | 
    
         
             
                      # params['phrase'] =  = args.join(" ")
         
     | 
| 
       1366 
1372 
     | 
    
         
             
                    end
         
     | 
| 
       1367 
1373 
     | 
    
         
             
                    params.merge!(parse_list_options(options))
         
     | 
| 
      
 1374 
     | 
    
         
            +
                    # query parameters are stored in :params
         
     | 
| 
      
 1375 
     | 
    
         
            +
                    # preserve anything already set in :params by the OptionParser or command specific logic..
         
     | 
| 
      
 1376 
     | 
    
         
            +
                    options[:params] ||= {}
         
     | 
| 
      
 1377 
     | 
    
         
            +
                    options[:params].deep_merge!(params)
         
     | 
| 
      
 1378 
     | 
    
         
            +
                    return options
         
     | 
| 
       1368 
1379 
     | 
    
         
             
                  end
         
     | 
| 
       1369 
1380 
     | 
    
         | 
| 
       1370 
1381 
     | 
    
         
             
                  # The default way to build options for the list command
         
     | 
| 
         @@ -1490,50 +1501,121 @@ module Morpheus 
     | 
|
| 
       1490 
1501 
     | 
    
         
             
                    return subtitles
         
     | 
| 
       1491 
1502 
     | 
    
         
             
                  end
         
     | 
| 
       1492 
1503 
     | 
    
         | 
| 
       1493 
     | 
    
         
            -
                   
     | 
| 
       1494 
     | 
    
         
            -
             
     | 
| 
       1495 
     | 
    
         
            -
             
     | 
| 
       1496 
     | 
    
         
            -
             
     | 
| 
       1497 
     | 
    
         
            -
             
     | 
| 
       1498 
     | 
    
         
            -
             
     | 
| 
       1499 
     | 
    
         
            -
                     
     | 
| 
       1500 
     | 
    
         
            -
                     
     | 
| 
       1501 
     | 
    
         
            -
             
     | 
| 
       1502 
     | 
    
         
            -
             
     | 
| 
       1503 
     | 
    
         
            -
             
     | 
| 
      
 1504 
     | 
    
         
            +
                  # Construct the request query parameters from the standard command options
         
     | 
| 
      
 1505 
     | 
    
         
            +
                  # This populates :params with a map of parameters.
         
     | 
| 
      
 1506 
     | 
    
         
            +
                  # This should replace the use of parse_query_options, parse_list_options and parse_list_options! and parse_get_options
         
     | 
| 
      
 1507 
     | 
    
         
            +
                  # which are used everywhere eg. params.merge!(parse_query_options(options))
         
     | 
| 
      
 1508 
     | 
    
         
            +
                  def parse_options(options, params={})
         
     | 
| 
      
 1509 
     | 
    
         
            +
                    params = params ? params.dup : {}
         
     | 
| 
      
 1510 
     | 
    
         
            +
                    # parse_list_options!(args, options, params)
         
     | 
| 
      
 1511 
     | 
    
         
            +
                    # merge in options set with -Q max=3, --query max=3&sort=id
         
     | 
| 
      
 1512 
     | 
    
         
            +
                    params.deep_merge!(options[:query_filters]) if options[:query_filters]
         
     | 
| 
      
 1513 
     | 
    
         
            +
                    # query parameters are stored in :params
         
     | 
| 
      
 1514 
     | 
    
         
            +
                    # preserve anything already set in :params by the OptionParser or command specific logic..
         
     | 
| 
      
 1515 
     | 
    
         
            +
                    options[:params] ||= {}
         
     | 
| 
      
 1516 
     | 
    
         
            +
                    options[:params].deep_merge!(params)
         
     | 
| 
      
 1517 
     | 
    
         
            +
                    # (JSON) body parameters (JSON) are stored in :payload
         
     | 
| 
      
 1518 
     | 
    
         
            +
                    # if options[:payload]
         
     | 
| 
      
 1519 
     | 
    
         
            +
                    # end
         
     | 
| 
      
 1520 
     | 
    
         
            +
                    # ok now call execute_request(@api_client.whoami, :get, nil, options)
         
     | 
| 
      
 1521 
     | 
    
         
            +
                    return options
         
     | 
| 
      
 1522 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1523 
     | 
    
         
            +
             
     | 
| 
      
 1524 
     | 
    
         
            +
                  # Parse payload(s) from the standard command options or else invoke the given block. 
         
     | 
| 
      
 1525 
     | 
    
         
            +
                  # First looks for --payload or --payload options and  if they are nil then the block is executed to establish the payload
         
     | 
| 
      
 1526 
     | 
    
         
            +
                  # By default this also merges all the values passed with -O, --options foo="bar" into payload under the object_key context.
         
     | 
| 
      
 1527 
     | 
    
         
            +
                  # and they are merged under the object_key context (if passed). This can be disabled with apply_options: false
         
     | 
| 
      
 1528 
     | 
    
         
            +
                  #
         
     | 
| 
      
 1529 
     | 
    
         
            +
                  # @param options [Hash] standard command options
         
     | 
| 
      
 1530 
     | 
    
         
            +
                  # @option options [Hash] :payload is a Hash of objects to serialize as the payload
         
     | 
| 
      
 1531 
     | 
    
         
            +
                  # @option options [Hash] :payloads is an array of payload objects@yield [street_name] Invokes the block with a street name for eac
         
     | 
| 
      
 1532 
     | 
    
         
            +
                  #                        This is silly and should go away, instead you should iterate in the terminal environment
         
     | 
| 
      
 1533 
     | 
    
         
            +
                  # @option options [Boolean] :apply_options can be set to false to skip -O options merge
         
     | 
| 
      
 1534 
     | 
    
         
            +
                  # @param object_key [String] The name of the object being constructed, -O --options will be merged under this context.
         
     | 
| 
      
 1535 
     | 
    
         
            +
                  # @return array of payloads
         
     | 
| 
      
 1536 
     | 
    
         
            +
                  # @yield [payload] Invokes the block to establish :payload (only when --payload(s) is not used)
         
     | 
| 
      
 1537 
     | 
    
         
            +
                  def parse_payload(options, object_key=nil, &block)
         
     | 
| 
      
 1538 
     | 
    
         
            +
                    # populate options[:params] here too
         
     | 
| 
      
 1539 
     | 
    
         
            +
                    parse_options(options)
         
     | 
| 
       1504 
1540 
     | 
    
         
             
                    payloads = []
         
     | 
| 
      
 1541 
     | 
    
         
            +
                    # todo: only need to support a a single payload here, :payloads is silly and is going away
         
     | 
| 
       1505 
1542 
     | 
    
         
             
                    if options[:payload]
         
     | 
| 
       1506 
1543 
     | 
    
         
             
                      # --payload option was used
         
     | 
| 
       1507 
1544 
     | 
    
         
             
                      payload = options[:payload]
         
     | 
| 
       1508 
1545 
     | 
    
         
             
                      # support -O OPTION switch on top of --payload
         
     | 
| 
       1509 
     | 
    
         
            -
                      apply_options(payload, options, object_key)
         
     | 
| 
      
 1546 
     | 
    
         
            +
                      apply_options(payload, options, object_key) unless options[:apply_options] == false
         
     | 
| 
       1510 
1547 
     | 
    
         
             
                      payloads << payload
         
     | 
| 
       1511 
1548 
     | 
    
         
             
                    elsif options[:payloads]
         
     | 
| 
       1512 
1549 
     | 
    
         
             
                      # --payloads option was used
         
     | 
| 
       1513 
1550 
     | 
    
         
             
                      payloads = options[:payloads]
         
     | 
| 
       1514 
     | 
    
         
            -
                      #  
     | 
| 
       1515 
     | 
    
         
            -
             
     | 
| 
       1516 
     | 
    
         
            -
             
     | 
| 
      
 1551 
     | 
    
         
            +
                      # support -O OPTION switch on top of --payloads
         
     | 
| 
      
 1552 
     | 
    
         
            +
                      payloads.each do |payload|
         
     | 
| 
      
 1553 
     | 
    
         
            +
                        apply_options(payload, options, object_key) unless options[:apply_options] == false
         
     | 
| 
      
 1554 
     | 
    
         
            +
                      end
         
     | 
| 
      
 1555 
     | 
    
         
            +
                    #else
         
     | 
| 
      
 1556 
     | 
    
         
            +
                    # should always do this, but a lot of methods rely on this returning nil right now, not {}
         
     | 
| 
      
 1557 
     | 
    
         
            +
                    # so for now only do it if block is given
         
     | 
| 
      
 1558 
     | 
    
         
            +
                    elsif block_given?
         
     | 
| 
      
 1559 
     | 
    
         
            +
                      # yield to block to construct the payload, 
         
     | 
| 
      
 1560 
     | 
    
         
            +
                      # this is typically where prompting for inputs with optionTypes happens
         
     | 
| 
       1517 
1561 
     | 
    
         
             
                      payload = {}
         
     | 
| 
       1518 
     | 
    
         
            -
                      apply_options(payload, options, object_key)
         
     | 
| 
      
 1562 
     | 
    
         
            +
                      apply_options(payload, options, object_key) unless options[:apply_options] == false
         
     | 
| 
       1519 
1563 
     | 
    
         
             
                      if block_given?
         
     | 
| 
       1520 
     | 
    
         
            -
                         
     | 
| 
       1521 
     | 
    
         
            -
                        #payload = result if result
         
     | 
| 
      
 1564 
     | 
    
         
            +
                        yield payload
         
     | 
| 
       1522 
1565 
     | 
    
         
             
                      end
         
     | 
| 
       1523 
1566 
     | 
    
         
             
                      payloads << payload
         
     | 
| 
      
 1567 
     | 
    
         
            +
                      options[:payload] = payload
         
     | 
| 
       1524 
1568 
     | 
    
         
             
                    end
         
     | 
| 
       1525 
     | 
    
         
            -
                    return payloads
         
     | 
| 
      
 1569 
     | 
    
         
            +
                    return payloads.first
         
     | 
| 
       1526 
1570 
     | 
    
         
             
                  end
         
     | 
| 
       1527 
1571 
     | 
    
         | 
| 
       1528 
     | 
    
         
            -
                   
     | 
| 
      
 1572 
     | 
    
         
            +
                  # support -O OPTION switch
         
     | 
| 
      
 1573 
     | 
    
         
            +
                  def apply_options(payload, options, object_key=nil)
         
     | 
| 
      
 1574 
     | 
    
         
            +
                    payload ||= {}
         
     | 
| 
      
 1575 
     | 
    
         
            +
                    if options[:options]
         
     | 
| 
      
 1576 
     | 
    
         
            +
                      # allow options[:object_key] to be used
         
     | 
| 
      
 1577 
     | 
    
         
            +
                      object_key = object_key ? object_key : options[:object_key]
         
     | 
| 
      
 1578 
     | 
    
         
            +
                      # could use parse_passed_options() here to support exclusion of certain options
         
     | 
| 
      
 1579 
     | 
    
         
            +
                      #passed_options = parse_passed_options(options, options[:apply_options] || {})
         
     | 
| 
      
 1580 
     | 
    
         
            +
                      passed_options = options[:options].reject {|k,v| k.is_a?(Symbol)}
         
     | 
| 
      
 1581 
     | 
    
         
            +
                      if object_key
         
     | 
| 
      
 1582 
     | 
    
         
            +
                        payload.deep_merge!({object_key => passed_options})
         
     | 
| 
      
 1583 
     | 
    
         
            +
                      else
         
     | 
| 
      
 1584 
     | 
    
         
            +
                        payload.deep_merge!(passed_options)
         
     | 
| 
      
 1585 
     | 
    
         
            +
                      end
         
     | 
| 
      
 1586 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1587 
     | 
    
         
            +
                    payload
         
     | 
| 
      
 1588 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1589 
     | 
    
         
            +
             
     | 
| 
      
 1590 
     | 
    
         
            +
                  # Executes the block with each payload (:payload or :payloads as parsed from --payload FILE and --payloads --PATH)
         
     | 
| 
      
 1591 
     | 
    
         
            +
                  # This is a wrapper to support execution on 1-N payloads 
         
     | 
| 
      
 1592 
     | 
    
         
            +
                  # It also looks for --ignore-payload-errors behavior to continue processing
         
     | 
| 
      
 1593 
     | 
    
         
            +
                  # It is up to the block to actually make the api request
         
     | 
| 
      
 1594 
     | 
    
         
            +
                  # @param options [Hash] standard command options
         
     | 
| 
      
 1595 
     | 
    
         
            +
                  # @raise [Error] if there is no :payload or :payloads defined.
         
     | 
| 
      
 1596 
     | 
    
         
            +
                  # @yield [payload] Yields each payload to the block
         
     | 
| 
      
 1597 
     | 
    
         
            +
                  # @return parsed command result of the last return value of the block ie. [0, nil]
         
     | 
| 
      
 1598 
     | 
    
         
            +
                  def handle_each_payload(options, &block)
         
     | 
| 
      
 1599 
     | 
    
         
            +
                    payloads = []
         
     | 
| 
      
 1600 
     | 
    
         
            +
                    if options[:payloads]
         
     | 
| 
      
 1601 
     | 
    
         
            +
                      payloads = options[:payloads]
         
     | 
| 
      
 1602 
     | 
    
         
            +
                    elsif options[:payload]
         
     | 
| 
      
 1603 
     | 
    
         
            +
                      payloads << options[:payload]
         
     | 
| 
      
 1604 
     | 
    
         
            +
                    else
         
     | 
| 
      
 1605 
     | 
    
         
            +
                      raise "handle_each_payload() requires :payload or :payloads"
         
     | 
| 
      
 1606 
     | 
    
         
            +
                    end
         
     | 
| 
       1529 
1607 
     | 
    
         
             
                    if !payloads.is_a?(Array) || payloads.compact.empty?
         
     | 
| 
       1530 
     | 
    
         
            -
                      raise " 
     | 
| 
      
 1608 
     | 
    
         
            +
                      raise "handle_each_payload() requires a payload"
         
     | 
| 
      
 1609 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1610 
     | 
    
         
            +
                    if !block_given?
         
     | 
| 
      
 1611 
     | 
    
         
            +
                      raise "handle_each_payload() requires a block to process the payload(s) with"
         
     | 
| 
       1531 
1612 
     | 
    
         
             
                    end
         
     | 
| 
       1532 
1613 
     | 
    
         
             
                    results = []
         
     | 
| 
       1533 
1614 
     | 
    
         
             
                    payloads.each do |payload|
         
     | 
| 
       1534 
1615 
     | 
    
         
             
                      begin
         
     | 
| 
       1535 
1616 
     | 
    
         
             
                        result = yield payload
         
     | 
| 
       1536 
     | 
    
         
            -
                        results <<  
     | 
| 
      
 1617 
     | 
    
         
            +
                        results << Morpheus::Cli::CliRegistry.parse_command_result(result)
         
     | 
| 
      
 1618 
     | 
    
         
            +
                        #results << [0, nil]
         
     | 
| 
       1537 
1619 
     | 
    
         
             
                      rescue => e
         
     | 
| 
       1538 
1620 
     | 
    
         
             
                        if options[:payloads_ignore_error]
         
     | 
| 
       1539 
1621 
     | 
    
         
             
                          # results << [1, e.message]
         
     | 
| 
         @@ -1548,16 +1630,67 @@ module Morpheus 
     | 
|
| 
       1548 
1630 
     | 
    
         
             
                    return results.last
         
     | 
| 
       1549 
1631 
     | 
    
         
             
                  end
         
     | 
| 
       1550 
1632 
     | 
    
         | 
| 
       1551 
     | 
    
         
            -
                   
     | 
| 
       1552 
     | 
    
         
            -
             
     | 
| 
       1553 
     | 
    
         
            -
             
     | 
| 
       1554 
     | 
    
         
            -
             
     | 
| 
      
 1633 
     | 
    
         
            +
                  # Standard handler for all commands that execute an api request.
         
     | 
| 
      
 1634 
     | 
    
         
            +
                  # This looks for a payload that can be set with --payload or --payloads or the default prompting
         
     | 
| 
      
 1635 
     | 
    
         
            +
                  # It is up to the block to handle the rendering behavior
         
     | 
| 
      
 1636 
     | 
    
         
            +
                  # @param api_interface [APIClient] An APIClient instance
         
     | 
| 
      
 1637 
     | 
    
         
            +
                  # @param api_method [String or Symbol] api method to invoke eg. :get, :create, :update, :destroy
         
     | 
| 
      
 1638 
     | 
    
         
            +
                  # @param args [Array] Array of arguments to be passed to the api method, usually just the [payload] or [payload, query_params]
         
     | 
| 
      
 1639 
     | 
    
         
            +
                  # @param options [Hash] options
         
     | 
| 
      
 1640 
     | 
    
         
            +
                  # @param object_key [String or Symbol] name of object being constructed, used by default rendering eg. --fields id,name
         
     | 
| 
      
 1641 
     | 
    
         
            +
                  # @yield [json_response] Invokes the block with the json response to handle rendering.
         
     | 
| 
      
 1642 
     | 
    
         
            +
                  # @return parsed command result of the last block.call(json_response)
         
     | 
| 
      
 1643 
     | 
    
         
            +
                  #
         
     | 
| 
      
 1644 
     | 
    
         
            +
                  # @example Fetch first 100 backups
         
     | 
| 
      
 1645 
     | 
    
         
            +
                  #   execute_api(@api_client.backups, :list, [{"max" => 100}], options) do |json_response|
         
     | 
| 
      
 1646 
     | 
    
         
            +
                  #     print_green_success "Fetched first #{json_response['backups'].size} of #{json_response['meta']['total']} backups"
         
     | 
| 
      
 1647 
     | 
    
         
            +
                  #   end
         
     | 
| 
      
 1648 
     | 
    
         
            +
                  #
         
     | 
| 
      
 1649 
     | 
    
         
            +
                  # @example Create a backup, uses POST with options[:payload] as the body
         
     | 
| 
      
 1650 
     | 
    
         
            +
                  #   @options[:payload] = {"backup" => { }}
         
     | 
| 
      
 1651 
     | 
    
         
            +
                  #   execute_api(@api_client.backups, :create, nil, options, 'backup') do |json_response|
         
     | 
| 
      
 1652 
     | 
    
         
            +
                  #     print_green_success "Added backup #{json_response['backup']['name']}"
         
     | 
| 
      
 1653 
     | 
    
         
            +
                  #   end
         
     | 
| 
      
 1654 
     | 
    
         
            +
                  #
         
     | 
| 
      
 1655 
     | 
    
         
            +
                  def execute_api(api_interface, api_method, args, options, object_key=nil, &block)
         
     | 
| 
      
 1656 
     | 
    
         
            +
                    args = args.is_a?(Array) ? args : [args].compact
         
     | 
| 
      
 1657 
     | 
    
         
            +
                    if options[:payload] || options[:payloads]
         
     | 
| 
      
 1658 
     | 
    
         
            +
                      execute_api_payload(api_interface, api_method, args, options, object_key, &block)
         
     | 
| 
      
 1659 
     | 
    
         
            +
                    else
         
     | 
| 
      
 1660 
     | 
    
         
            +
                      execute_api_request(api_interface, api_method, args, options, object_key, &block)
         
     | 
| 
      
 1661 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1662 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1663 
     | 
    
         
            +
             
     | 
| 
      
 1664 
     | 
    
         
            +
                  # Standard handler for all POST commands that send a request for a payload
         
     | 
| 
      
 1665 
     | 
    
         
            +
                  # This supports the --payloads option for 1-N payloads, that is silly and will probably go away
         
     | 
| 
      
 1666 
     | 
    
         
            +
                  def execute_api_payload(api_interface, api_method, args, options, object_key=nil, &block)
         
     | 
| 
      
 1667 
     | 
    
         
            +
                    handle_each_payload(options) do |payload|
         
     | 
| 
      
 1668 
     | 
    
         
            +
                      execute_api_request(api_interface, api_method, (args || []) + [payload], options, object_key, &block)
         
     | 
| 
      
 1669 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1670 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1671 
     | 
    
         
            +
             
     | 
| 
      
 1672 
     | 
    
         
            +
                  # Standard handler for executing any API request
         
     | 
| 
      
 1673 
     | 
    
         
            +
                  # Supports the --dry-run option and standard rendering options --json, --yaml, --fields, --select, etc.
         
     | 
| 
      
 1674 
     | 
    
         
            +
                  def execute_api_request(api_interface, api_method, args, options, object_key=nil, &block)
         
     | 
| 
      
 1675 
     | 
    
         
            +
                    args = args.is_a?(Array) ? args : [args].compact # allow caller to pass [payload] or payload
         
     | 
| 
      
 1676 
     | 
    
         
            +
                    api_interface.setopts(options) # this is needed to support --timeout and --headers
         
     | 
| 
      
 1677 
     | 
    
         
            +
                    # this assumes the interface parameter order is: [payload, params] and not vice versa
         
     | 
| 
      
 1678 
     | 
    
         
            +
                    if options[:params] && !options[:params].empty?
         
     | 
| 
      
 1679 
     | 
    
         
            +
                      args << options[:params]
         
     | 
| 
      
 1680 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1681 
     | 
    
         
            +
                    if options[:dry_run]
         
     | 
| 
      
 1682 
     | 
    
         
            +
                      # this is a dry run
         
     | 
| 
      
 1683 
     | 
    
         
            +
                      dry_response = api_interface.dry.send(api_method, *args)
         
     | 
| 
      
 1684 
     | 
    
         
            +
                      print_dry_run(dry_response, options)
         
     | 
| 
      
 1685 
     | 
    
         
            +
                      return 0, nil
         
     | 
| 
       1555 
1686 
     | 
    
         
             
                    else
         
     | 
| 
       1556 
     | 
    
         
            -
                       
     | 
| 
      
 1687 
     | 
    
         
            +
                      # execute the request and render the result
         
     | 
| 
      
 1688 
     | 
    
         
            +
                      json_response = api_interface.send(api_method, *args)
         
     | 
| 
      
 1689 
     | 
    
         
            +
                      return render_response(json_response, options, object_key, &block)
         
     | 
| 
       1557 
1690 
     | 
    
         
             
                    end
         
     | 
| 
       1558 
     | 
    
         
            -
                    return payload
         
     | 
| 
       1559 
1691 
     | 
    
         
             
                  end
         
     | 
| 
       1560 
1692 
     | 
    
         | 
| 
      
 1693 
     | 
    
         
            +
                  # Parse an array from a string (csv)
         
     | 
| 
       1561 
1694 
     | 
    
         
             
                  def parse_array(val, opts={})
         
     | 
| 
       1562 
1695 
     | 
    
         
             
                    opts = {strip:true, allow_blank:false}.merge(opts)
         
     | 
| 
       1563 
1696 
     | 
    
         
             
                    values = []
         
     | 
| 
         @@ -1580,19 +1713,6 @@ module Morpheus 
     | 
|
| 
       1580 
1713 
     | 
    
         
             
                    parse_array(val, {strip:true, allow_blank:false})
         
     | 
| 
       1581 
1714 
     | 
    
         
             
                  end
         
     | 
| 
       1582 
1715 
     | 
    
         | 
| 
       1583 
     | 
    
         
            -
                  # support -O OPTION switch
         
     | 
| 
       1584 
     | 
    
         
            -
                  def apply_options(payload, options, object_key=nil)
         
     | 
| 
       1585 
     | 
    
         
            -
                    payload ||= {}
         
     | 
| 
       1586 
     | 
    
         
            -
                    if options[:options]
         
     | 
| 
       1587 
     | 
    
         
            -
                      if object_key
         
     | 
| 
       1588 
     | 
    
         
            -
                        payload.deep_merge!({object_key => options[:options].reject {|k,v| k.is_a?(Symbol)}})
         
     | 
| 
       1589 
     | 
    
         
            -
                      else
         
     | 
| 
       1590 
     | 
    
         
            -
                        payload.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol)})
         
     | 
| 
       1591 
     | 
    
         
            -
                      end
         
     | 
| 
       1592 
     | 
    
         
            -
                    end
         
     | 
| 
       1593 
     | 
    
         
            -
                    payload
         
     | 
| 
       1594 
     | 
    
         
            -
                  end
         
     | 
| 
       1595 
     | 
    
         
            -
             
     | 
| 
       1596 
1716 
     | 
    
         
             
                  def validate_outfile(outfile, options)
         
     | 
| 
       1597 
1717 
     | 
    
         
             
                    full_filename = File.expand_path(outfile)
         
     | 
| 
       1598 
1718 
     | 
    
         
             
                    outdir = File.dirname(full_filename)
         
     | 
| 
         @@ -1619,6 +1739,8 @@ module Morpheus 
     | 
|
| 
       1619 
1739 
     | 
    
         
             
                  # basic rendering for options :json, :yml, :csv, :quiet, and :outfile
         
     | 
| 
       1620 
1740 
     | 
    
         
             
                  # returns the string rendered, or nil if nothing was rendered.
         
     | 
| 
       1621 
1741 
     | 
    
         
             
                  def render_response(json_response, options, object_key=nil, &block)
         
     | 
| 
      
 1742 
     | 
    
         
            +
                    # allow options[:object_key] to be used
         
     | 
| 
      
 1743 
     | 
    
         
            +
                    object_key = object_key ? object_key : options[:object_key]
         
     | 
| 
       1622 
1744 
     | 
    
         
             
                    output = nil
         
     | 
| 
       1623 
1745 
     | 
    
         
             
                    if options[:select_fields]
         
     | 
| 
       1624 
1746 
     | 
    
         
             
                      # support foos get --raw-select foo.x,foo.y,foo.z
         
     | 
| 
         @@ -1676,7 +1798,7 @@ module Morpheus 
     | 
|
| 
       1676 
1798 
     | 
    
         
             
                      else
         
     | 
| 
       1677 
1799 
     | 
    
         
             
                        # no render happened, so calling the block if given
         
     | 
| 
       1678 
1800 
     | 
    
         
             
                        if block_given?
         
     | 
| 
       1679 
     | 
    
         
            -
                          result = yield
         
     | 
| 
      
 1801 
     | 
    
         
            +
                          result = yield json_response
         
     | 
| 
       1680 
1802 
     | 
    
         
             
                          if result
         
     | 
| 
       1681 
1803 
     | 
    
         
             
                            return result
         
     | 
| 
       1682 
1804 
     | 
    
         
             
                          else
         
     | 
| 
         @@ -1903,6 +2025,14 @@ module Morpheus 
     | 
|
| 
       1903 
2025 
     | 
    
         
             
                    # add aliases here as needed
         
     | 
| 
       1904 
2026 
     | 
    
         
             
                    if key == "cloud"
         
     | 
| 
       1905 
2027 
     | 
    
         
             
                      key = "zone"
         
     | 
| 
      
 2028 
     | 
    
         
            +
                    elsif key == "site"
         
     | 
| 
      
 2029 
     | 
    
         
            +
                      key = "group"
         
     | 
| 
      
 2030 
     | 
    
         
            +
                    elsif key == "backupJob"
         
     | 
| 
      
 2031 
     | 
    
         
            +
                      key = "job"
         
     | 
| 
      
 2032 
     | 
    
         
            +
                    elsif key == "backupResult"
         
     | 
| 
      
 2033 
     | 
    
         
            +
                      key = "result"
         
     | 
| 
      
 2034 
     | 
    
         
            +
                    elsif key == "backupRestore"
         
     | 
| 
      
 2035 
     | 
    
         
            +
                      key = "restore"
         
     | 
| 
       1906 
2036 
     | 
    
         
             
                    end
         
     | 
| 
       1907 
2037 
     | 
    
         
             
                    return key
         
     | 
| 
       1908 
2038 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -231,9 +231,7 @@ class Morpheus::Cli::ApplianceSettingsCommand 
     | 
|
| 
       231 
231 
     | 
    
         
             
                end
         
     | 
| 
       232 
232 
     | 
    
         | 
| 
       233 
233 
     | 
    
         
             
                begin
         
     | 
| 
       234 
     | 
    
         
            -
                   
     | 
| 
       235 
     | 
    
         
            -
             
     | 
| 
       236 
     | 
    
         
            -
                  if !payload
         
     | 
| 
      
 234 
     | 
    
         
            +
                  parse_payload(options) do |payload|
         
     | 
| 
       237 
235 
     | 
    
         
             
                    available_zone_types = @appliance_settings_interface.cloud_types['zoneTypes']
         
     | 
| 
       238 
236 
     | 
    
         | 
| 
       239 
237 
     | 
    
         
             
                    if options[:enableZoneTypes]
         
     | 
| 
         @@ -283,29 +281,19 @@ class Morpheus::Cli::ApplianceSettingsCommand 
     | 
|
| 
       283 
281 
     | 
    
         
             
                        exit 1
         
     | 
| 
       284 
282 
     | 
    
         
             
                      end
         
     | 
| 
       285 
283 
     | 
    
         
             
                    end
         
     | 
| 
       286 
     | 
    
         
            -
             
     | 
| 
       287 
     | 
    
         
            -
                    payload = {'applianceSettings' => params}
         
     | 
| 
      
 284 
     | 
    
         
            +
                    payload['applianceSettings'] = params
         
     | 
| 
       288 
285 
     | 
    
         
             
                  end
         
     | 
| 
       289 
     | 
    
         
            -
             
     | 
| 
       290 
     | 
    
         
            -
                  @appliance_settings_interface.setopts(options)
         
     | 
| 
       291 
     | 
    
         
            -
                  if options[:dry_run]
         
     | 
| 
       292 
     | 
    
         
            -
                    print_dry_run @appliance_settings_interface.dry.update(payload)
         
     | 
| 
       293 
     | 
    
         
            -
                    return
         
     | 
| 
       294 
     | 
    
         
            -
                  end
         
     | 
| 
       295 
     | 
    
         
            -
                  json_response = @appliance_settings_interface.update(payload)
         
     | 
| 
       296 
     | 
    
         
            -
             
     | 
| 
       297 
     | 
    
         
            -
                  if options[:json]
         
     | 
| 
       298 
     | 
    
         
            -
                    puts as_json(json_response, options)
         
     | 
| 
       299 
     | 
    
         
            -
                  elsif !options[:quiet]
         
     | 
| 
      
 286 
     | 
    
         
            +
                  execute_api(@appliance_settings_interface, :update, nil, options, "applianceSettings") do |json_response|
         
     | 
| 
       300 
287 
     | 
    
         
             
                    if json_response['success']
         
     | 
| 
       301 
288 
     | 
    
         
             
                      print_green_success  "Updated appliance settings"
         
     | 
| 
       302 
289 
     | 
    
         
             
                      get([] + (options[:remote] ? ["-r",options[:remote]] : []))
         
     | 
| 
       303 
290 
     | 
    
         
             
                    else
         
     | 
| 
       304 
     | 
    
         
            -
                       
     | 
| 
      
 291 
     | 
    
         
            +
                      #todo: API should return 400 on error and then this is not needed
         
     | 
| 
      
 292 
     | 
    
         
            +
                      #print_red_alert "Error updating appliance settings"
         
     | 
| 
      
 293 
     | 
    
         
            +
                      print_rest_errors(json_response)
         
     | 
| 
      
 294 
     | 
    
         
            +
                      [1, "Error updating appliance settings"]
         
     | 
| 
       305 
295 
     | 
    
         
             
                    end
         
     | 
| 
       306 
296 
     | 
    
         
             
                  end
         
     | 
| 
       307 
     | 
    
         
            -
                  return 0
         
     | 
| 
       308 
     | 
    
         
            -
             
     | 
| 
       309 
297 
     | 
    
         
             
                rescue RestClient::Exception => e
         
     | 
| 
       310 
298 
     | 
    
         
             
                  print_rest_exception(e, options)
         
     | 
| 
       311 
299 
     | 
    
         
             
                  exit 1
         
     | 
| 
         @@ -790,7 +790,7 @@ class Morpheus::Cli::Apps 
     | 
|
| 
       790 
790 
     | 
    
         
             
                          if !instance['connectionInfo'].nil? && instance['connectionInfo'].empty? == false
         
     | 
| 
       791 
791 
     | 
    
         
             
                            connection_string = "#{instance['connectionInfo'][0]['ip']}:#{instance['connectionInfo'][0]['port']}"
         
     | 
| 
       792 
792 
     | 
    
         
             
                          end
         
     | 
| 
       793 
     | 
    
         
            -
                          {id: instance['id'], name: instance['name'], connection: connection_string, environment: instance['instanceContext'], nodes: (instance['containers'] || []).count, status: format_instance_status(instance), type: instance['instanceType']['name'], group: !instance['group'].nil? ? instance['group']['name'] : nil, cloud: !instance['cloud'].nil? ? instance['cloud']['name'] : nil}
         
     | 
| 
      
 793 
     | 
    
         
            +
                          {id: instance['id'], name: instance['displayName'] ? instance['displayName'] : instance['name'], connection: connection_string, environment: instance['instanceContext'], nodes: (instance['containers'] || []).count, status: format_instance_status(instance), type: instance['instanceType']['name'], group: !instance['group'].nil? ? instance['group']['name'] : nil, cloud: !instance['cloud'].nil? ? instance['cloud']['name'] : nil}
         
     | 
| 
       794 
794 
     | 
    
         
             
                        end
         
     | 
| 
       795 
795 
     | 
    
         
             
                        instances_rows = instances_rows.sort {|x,y| x[:id] <=> y[:id] } #oldest to newest..
         
     | 
| 
       796 
796 
     | 
    
         
             
                        print cyan
         
     |