aspera-cli 4.24.0 → 4.24.2
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
 - checksums.yaml.gz.sig +0 -0
 - data/CHANGELOG.md +19 -1
 - data/README.md +1264 -941
 - data/bin/ascli +20 -1
 - data/bin/asession +23 -27
 - data/lib/aspera/agent/base.rb +10 -21
 - data/lib/aspera/agent/connect.rb +2 -3
 - data/lib/aspera/agent/desktop.rb +2 -2
 - data/lib/aspera/agent/direct.rb +49 -32
 - data/lib/aspera/agent/factory.rb +31 -0
 - data/lib/aspera/api/aoc.rb +79 -49
 - data/lib/aspera/api/faspex.rb +212 -0
 - data/lib/aspera/api/node.rb +99 -84
 - data/lib/aspera/ascp/installation.rb +22 -21
 - data/lib/aspera/ascp/management.rb +119 -23
 - data/lib/aspera/assert.rb +14 -8
 - data/lib/aspera/cli/extended_value.rb +15 -15
 - data/lib/aspera/cli/formatter.rb +7 -5
 - data/lib/aspera/cli/hints.rb +8 -0
 - data/lib/aspera/cli/info.rb +4 -4
 - data/lib/aspera/cli/main.rb +56 -71
 - data/lib/aspera/cli/manager.rb +7 -4
 - data/lib/aspera/cli/plugins/alee.rb +2 -1
 - data/lib/aspera/cli/plugins/aoc.rb +110 -186
 - data/lib/aspera/cli/plugins/ats.rb +4 -4
 - data/lib/aspera/cli/plugins/base.rb +335 -0
 - data/lib/aspera/cli/plugins/basic_auth.rb +45 -0
 - data/lib/aspera/cli/plugins/config.rb +263 -221
 - data/lib/aspera/cli/plugins/console.rb +15 -15
 - data/lib/aspera/cli/plugins/cos.rb +2 -2
 - data/lib/aspera/cli/plugins/factory.rb +78 -0
 - data/lib/aspera/cli/plugins/faspex.rb +17 -20
 - data/lib/aspera/cli/plugins/faspex5.rb +79 -193
 - data/lib/aspera/cli/plugins/faspio.rb +14 -13
 - data/lib/aspera/cli/plugins/httpgw.rb +13 -12
 - data/lib/aspera/cli/plugins/node.rb +34 -32
 - data/lib/aspera/cli/plugins/oauth.rb +48 -0
 - data/lib/aspera/cli/plugins/orchestrator.rb +15 -13
 - data/lib/aspera/cli/plugins/preview.rb +4 -4
 - data/lib/aspera/cli/plugins/server.rb +15 -13
 - data/lib/aspera/cli/plugins/shares.rb +18 -15
 - data/lib/aspera/cli/sync_actions.rb +1 -1
 - data/lib/aspera/cli/transfer_agent.rb +24 -20
 - data/lib/aspera/cli/transfer_progress.rb +6 -6
 - data/lib/aspera/cli/version.rb +3 -3
 - data/lib/aspera/cli/wizard.rb +74 -65
 - data/lib/aspera/colors.rb +6 -0
 - data/lib/aspera/command_line_builder.rb +45 -50
 - data/lib/aspera/command_line_converter.rb +2 -1
 - data/lib/aspera/coverage.rb +1 -1
 - data/lib/aspera/data_repository.rb +1 -1
 - data/lib/aspera/environment.rb +13 -9
 - data/lib/aspera/faspex_gw.rb +6 -4
 - data/lib/aspera/faspex_postproc.rb +1 -1
 - data/lib/aspera/keychain/macos_security.rb +1 -1
 - data/lib/aspera/log.rb +88 -37
 - data/lib/aspera/nagios.rb +1 -1
 - data/lib/aspera/oauth/base.rb +17 -10
 - data/lib/aspera/oauth/factory.rb +8 -8
 - data/lib/aspera/oauth/web.rb +2 -2
 - data/lib/aspera/products/connect.rb +4 -3
 - data/lib/aspera/products/desktop.rb +1 -4
 - data/lib/aspera/products/other.rb +9 -1
 - data/lib/aspera/products/transferd.rb +0 -1
 - data/lib/aspera/rest.rb +126 -83
 - data/lib/aspera/ssh.rb +3 -3
 - data/lib/aspera/sync/args.schema.yaml +46 -3
 - data/lib/aspera/sync/conf.schema.yaml +130 -94
 - data/lib/aspera/sync/operations.rb +71 -74
 - data/lib/aspera/temp_file_manager.rb +17 -5
 - data/lib/aspera/transfer/error.rb +16 -7
 - data/lib/aspera/transfer/parameters.rb +34 -20
 - data/lib/aspera/transfer/resumer.rb +74 -0
 - data/lib/aspera/transfer/spec.rb +4 -3
 - data/lib/aspera/transfer/spec.schema.yaml +132 -51
 - data/lib/aspera/transfer/spec_doc.rb +41 -35
 - data/lib/aspera/uri_reader.rb +1 -1
 - data/lib/aspera/web_auth.rb +6 -6
 - data.tar.gz.sig +0 -0
 - metadata +9 -7
 - metadata.gz.sig +2 -2
 - data/lib/aspera/cli/basic_auth_plugin.rb +0 -43
 - data/lib/aspera/cli/plugin.rb +0 -333
 - data/lib/aspera/cli/plugin_factory.rb +0 -81
 - data/lib/aspera/resumer.rb +0 -77
 - data/lib/aspera/transfer/error_info.rb +0 -91
 
| 
         @@ -88,10 +88,10 @@ module Aspera 
     | 
|
| 
       88 
88 
     | 
    
         
             
                  def use_ascp_from_product(product_name)
         
     | 
| 
       89 
89 
     | 
    
         
             
                    if product_name.eql?(FIRST_FOUND)
         
     | 
| 
       90 
90 
     | 
    
         
             
                      pl = installed_products.first
         
     | 
| 
       91 
     | 
    
         
            -
                      raise " 
     | 
| 
      
 91 
     | 
    
         
            +
                      raise "No Aspera transfer module or SDK found.\nRefer to the manual or install SDK with command:\nascli conf transferd install" if pl.nil?
         
     | 
| 
       92 
92 
     | 
    
         
             
                    else
         
     | 
| 
       93 
93 
     | 
    
         
             
                      pl = installed_products.find{ |i| i[:name].eql?(product_name)}
         
     | 
| 
       94 
     | 
    
         
            -
                      raise " 
     | 
| 
      
 94 
     | 
    
         
            +
                      raise "No such product installed: #{product_name}" if pl.nil?
         
     | 
| 
       95 
95 
     | 
    
         
             
                    end
         
     | 
| 
       96 
96 
     | 
    
         
             
                    self.ascp_path = pl[:ascp_path]
         
     | 
| 
       97 
97 
     | 
    
         
             
                    Log.log.debug{"ascp_path=#{@path_to_ascp}"}
         
     | 
| 
         @@ -271,7 +271,9 @@ module Aspera 
     | 
|
| 
       271 
271 
     | 
    
         
             
                      Zip::File.open(sdk_archive_path) do |zip_file|
         
     | 
| 
       272 
272 
     | 
    
         
             
                        zip_file.each do |entry|
         
     | 
| 
       273 
273 
     | 
    
         
             
                          next if entry.name.end_with?('/')
         
     | 
| 
       274 
     | 
    
         
            -
                           
     | 
| 
      
 274 
     | 
    
         
            +
                          entry.get_input_stream do |io|
         
     | 
| 
      
 275 
     | 
    
         
            +
                            yield(entry.name, io, nil)
         
     | 
| 
      
 276 
     | 
    
         
            +
                          end
         
     | 
| 
       275 
277 
     | 
    
         
             
                        end
         
     | 
| 
       276 
278 
     | 
    
         
             
                      end
         
     | 
| 
       277 
279 
     | 
    
         
             
                    # Other Unixes use tar.gz
         
     | 
| 
         @@ -296,7 +298,7 @@ module Aspera 
     | 
|
| 
       296 
298 
     | 
    
         
             
                  # @param folder   [String] Destination folder path
         
     | 
| 
       297 
299 
     | 
    
         
             
                  # @param backup   [Bool]   If destination folder exists, then rename
         
     | 
| 
       298 
300 
     | 
    
         
             
                  # @param with_exe [Bool]   If false, only retrieves files, but do not generate or restrict access
         
     | 
| 
       299 
     | 
    
         
            -
                  # @param &block   [Proc]   A lambda that receives a file path from archive and tells  
     | 
| 
      
 301 
     | 
    
         
            +
                  # @param &block   [Proc]   A lambda that receives a file path from archive and tells destination sub folder(end with /) or file, or nil to not extract
         
     | 
| 
       300 
302 
     | 
    
         
             
                  # @return ascp version (from execution)
         
     | 
| 
       301 
303 
     | 
    
         
             
                  def install_sdk(url: nil, version: nil, folder: nil, backup: true, with_exe: true, &block)
         
     | 
| 
       302 
304 
     | 
    
         
             
                    url = sdk_url_for_platform(version: version) if url.nil? || url.eql?('DEF')
         
     | 
| 
         @@ -308,6 +310,7 @@ module Aspera 
     | 
|
| 
       308 
310 
     | 
    
         
             
                        Products::Transferd::RUNTIME_FOLDERS.any?{ |i| name.match?(%r{^[^/]*/#{i}/})} ? '/' : nil
         
     | 
| 
       309 
311 
     | 
    
         
             
                      end
         
     | 
| 
       310 
312 
     | 
    
         
             
                    end
         
     | 
| 
      
 313 
     | 
    
         
            +
                    FileUtils.mkdir_p(folder)
         
     | 
| 
       311 
314 
     | 
    
         
             
                    # rename old install
         
     | 
| 
       312 
315 
     | 
    
         
             
                    if backup && !Dir.empty?(folder)
         
     | 
| 
       313 
316 
     | 
    
         
             
                      Log.log.warn('Previous install exists, renaming folder.')
         
     | 
| 
         @@ -333,7 +336,7 @@ module Aspera 
     | 
|
| 
       333 
336 
     | 
    
         
             
                      end
         
     | 
| 
       334 
337 
     | 
    
         
             
                    end
         
     | 
| 
       335 
338 
     | 
    
         
             
                    return unless with_exe
         
     | 
| 
       336 
     | 
    
         
            -
                    #  
     | 
| 
      
 339 
     | 
    
         
            +
                    # Ensure necessary files are there, or generate them
         
     | 
| 
       337 
340 
     | 
    
         
             
                    SDK_FILES.each do |file_id_sym|
         
     | 
| 
       338 
341 
     | 
    
         
             
                      file_path = path(file_id_sym)
         
     | 
| 
       339 
342 
     | 
    
         
             
                      if file_path && EXE_FILES.include?(file_id_sym)
         
     | 
| 
         @@ -355,6 +358,8 @@ module Aspera 
     | 
|
| 
       355 
358 
     | 
    
         
             
                  # policy for product selection
         
     | 
| 
       356 
359 
     | 
    
         
             
                  FIRST_FOUND = 'FIRST'
         
     | 
| 
       357 
360 
     | 
    
         | 
| 
      
 361 
     | 
    
         
            +
                  private_constant :FIRST_FOUND
         
     | 
| 
      
 362 
     | 
    
         
            +
             
     | 
| 
       358 
363 
     | 
    
         
             
                  def initialize
         
     | 
| 
       359 
364 
     | 
    
         
             
                    @path_to_ascp = nil
         
     | 
| 
       360 
365 
     | 
    
         
             
                    @sdk_dir = nil
         
     | 
| 
         @@ -366,22 +371,18 @@ module Aspera 
     | 
|
| 
       366 
371 
     | 
    
         | 
| 
       367 
372 
     | 
    
         
             
                  # @return the list of installed products in format of product_locations_on_current_os
         
     | 
| 
       368 
373 
     | 
    
         
             
                  def installed_products
         
     | 
| 
       369 
     | 
    
         
            -
                     
     | 
| 
       370 
     | 
    
         
            -
             
     | 
| 
       371 
     | 
    
         
            -
             
     | 
| 
       372 
     | 
    
         
            -
             
     | 
| 
       373 
     | 
    
         
            -
             
     | 
| 
       374 
     | 
    
         
            -
             
     | 
| 
       375 
     | 
    
         
            -
             
     | 
| 
       376 
     | 
    
         
            -
             
     | 
| 
       377 
     | 
    
         
            -
             
     | 
| 
       378 
     | 
    
         
            -
             
     | 
| 
       379 
     | 
    
         
            -
             
     | 
| 
       380 
     | 
    
         
            -
             
     | 
| 
       381 
     | 
    
         
            -
                      # search installed products: with ascp
         
     | 
| 
       382 
     | 
    
         
            -
                      @found_products = Products::Other.find(scan_locations)
         
     | 
| 
       383 
     | 
    
         
            -
                    end
         
     | 
| 
       384 
     | 
    
         
            -
                    return @found_products
         
     | 
| 
      
 374 
     | 
    
         
            +
                    return @found_products unless @found_products.nil?
         
     | 
| 
      
 375 
     | 
    
         
            +
                    # :expected  M app name is taken from the manifest if present, else defaults to this value
         
     | 
| 
      
 376 
     | 
    
         
            +
                    # :app_root  M main folder for the application
         
     | 
| 
      
 377 
     | 
    
         
            +
                    # :log_root  O location of log files (Linux uses syslog)
         
     | 
| 
      
 378 
     | 
    
         
            +
                    # :run_root  O only for Connect Client, location of http port file
         
     | 
| 
      
 379 
     | 
    
         
            +
                    # :sub_bin   O subfolder with executables, default : bin
         
     | 
| 
      
 380 
     | 
    
         
            +
                    scan_locations = Products::Transferd.locations +
         
     | 
| 
      
 381 
     | 
    
         
            +
                      Products::Desktop.locations +
         
     | 
| 
      
 382 
     | 
    
         
            +
                      Products::Connect.locations +
         
     | 
| 
      
 383 
     | 
    
         
            +
                      Products::Other::LOCATION_ON_THIS_OS
         
     | 
| 
      
 384 
     | 
    
         
            +
                    # search installed products: with ascp
         
     | 
| 
      
 385 
     | 
    
         
            +
                    @found_products = Products::Other.find(scan_locations)
         
     | 
| 
       385 
386 
     | 
    
         
             
                  end
         
     | 
| 
       386 
387 
     | 
    
         
             
                end
         
     | 
| 
       387 
388 
     | 
    
         
             
              end
         
     | 
| 
         @@ -6,6 +6,90 @@ module Aspera 
     | 
|
| 
       6 
6 
     | 
    
         
             
              module Ascp
         
     | 
| 
       7 
7 
     | 
    
         
             
                # processing of ascp management port events
         
     | 
| 
       8 
8 
     | 
    
         
             
                class Management
         
     | 
| 
      
 9 
     | 
    
         
            +
                  # from https://www.google.com/search?q=FASP+error+codes
         
     | 
| 
      
 10 
     | 
    
         
            +
                  # Note that the fact that an error is retry-able is not internally defined by protocol, it's client-side responsibility
         
     | 
| 
      
 11 
     | 
    
         
            +
                  # rubocop:disable Layout/FirstHashElementLineBreak
         
     | 
| 
      
 12 
     | 
    
         
            +
                  ERRORS = {
         
     | 
| 
      
 13 
     | 
    
         
            +
                    # id   retry-able    mnemo/code                        message                                              additional info
         
     | 
| 
      
 14 
     | 
    
         
            +
                    0  => {r: false, c: 'UNKNOWN',                     m: 'unknown',                                        a: 'unknown'},
         
     | 
| 
      
 15 
     | 
    
         
            +
                    1  => {r: false, c: 'FASP_PROTO',                  m: 'Generic fasp(tm) protocol error',                a: 'fasp(tm) error'},
         
     | 
| 
      
 16 
     | 
    
         
            +
                    2  => {r: false, c: 'ASCP',                        m: 'Generic SCP error',                              a: 'ASCP error'},
         
     | 
| 
      
 17 
     | 
    
         
            +
                    3  => {r: false, c: 'AMBIGUOUS_TARGET',            m: 'Target incorrectly specified',                   a: 'Ambiguous target'},
         
     | 
| 
      
 18 
     | 
    
         
            +
                    4  => {r: false, c: 'NO_SUCH_FILE',                m: 'No such file or directory',                      a: 'No such file or directory'},
         
     | 
| 
      
 19 
     | 
    
         
            +
                    5  => {r: false, c: 'NO_PERMS',                    m: 'Insufficient permission to read or write',       a: 'Insufficient permissions'},
         
     | 
| 
      
 20 
     | 
    
         
            +
                    6  => {r: false, c: 'NOT_DIR',                     m: 'Target is not a directory',                      a: 'Target must be a directory'},
         
     | 
| 
      
 21 
     | 
    
         
            +
                    7  => {r: false, c: 'IS_DIR',                      m: 'File is a directory - expected regular file',    a: 'Expected regular file'},
         
     | 
| 
      
 22 
     | 
    
         
            +
                    8  => {r: false, c: 'USAGE',                       m: 'Incorrect usage of scp command',                 a: 'Incorrect usage of Aspera scp command'},
         
     | 
| 
      
 23 
     | 
    
         
            +
                    9  => {r: false, c: 'LIC_DUP',                     m: 'Duplicate license',                              a: 'Duplicate license'},
         
     | 
| 
      
 24 
     | 
    
         
            +
                    10 => {r: false, c: 'LIC_RATE_EXCEEDED',           m: 'Rate exceeds the cap imposed by license',        a: 'Rate exceeds cap imposed by license'},
         
     | 
| 
      
 25 
     | 
    
         
            +
                    11 => {r: false, c: 'INTERNAL_ERROR',              m: 'Internal error (unexpected error)',              a: 'Internal error'},
         
     | 
| 
      
 26 
     | 
    
         
            +
                    12 => {r: true,  c: 'TRANSFER_ERROR',              m: 'Error establishing control connection',
         
     | 
| 
      
 27 
     | 
    
         
            +
                                                                            a: 'Error establishing SSH connection (check SSH port and firewall)'},
         
     | 
| 
      
 28 
     | 
    
         
            +
                    13 => {r: true,  c: 'TRANSFER_TIMEOUT',            m: 'Timeout establishing control connection',
         
     | 
| 
      
 29 
     | 
    
         
            +
                                                                            a: 'Timeout establishing SSH connection (check SSH port and firewall)'},
         
     | 
| 
      
 30 
     | 
    
         
            +
                    14 => {r: true,  c: 'CONNECTION_ERROR',            m: 'Error establishing data connection',
         
     | 
| 
      
 31 
     | 
    
         
            +
                                                                            a: 'Error establishing UDP connection (check UDP port and firewall)'},
         
     | 
| 
      
 32 
     | 
    
         
            +
                    15 => {r: true,  c: 'CONNECTION_TIMEOUT',          m: 'Timeout establishing data connection',
         
     | 
| 
      
 33 
     | 
    
         
            +
                                                                            a: 'Timeout establishing UDP connection (check UDP port and firewall)'},
         
     | 
| 
      
 34 
     | 
    
         
            +
                    16 => {r: true,  c: 'CONNECTION_LOST',             m: 'Connection lost',                                a: 'Connection lost'},
         
     | 
| 
      
 35 
     | 
    
         
            +
                    17 => {r: true,  c: 'RCVR_SEND_ERROR',             m: 'Receiver fails to send feedback',                a: 'Network failure (receiver can\'t send feedback)'},
         
     | 
| 
      
 36 
     | 
    
         
            +
                    18 => {r: true,  c: 'RCVR_RECV_ERROR',             m: 'Receiver fails to receive data packets',         a: 'Network failure (receiver can\'t receive UDP data)'},
         
     | 
| 
      
 37 
     | 
    
         
            +
                    19 => {r: false, c: 'AUTH',                        m: 'Authentication failure',                         a: 'Authentication failure'},
         
     | 
| 
      
 38 
     | 
    
         
            +
                    20 => {r: false, c: 'NOTHING',                     m: 'Nothing to transfer',                            a: 'Nothing to transfer'},
         
     | 
| 
      
 39 
     | 
    
         
            +
                    21 => {r: false, c: 'NOT_REGULAR',                 m: 'Not a regular file (special file)',              a: 'Not a regular file'},
         
     | 
| 
      
 40 
     | 
    
         
            +
                    22 => {r: false, c: 'FILE_TABLE_OVR',              m: 'File table overflow',                            a: 'File table overflow'},
         
     | 
| 
      
 41 
     | 
    
         
            +
                    23 => {r: true,  c: 'TOO_MANY_FILES',              m: 'Too many files open',                            a: 'Too many files open'},
         
     | 
| 
      
 42 
     | 
    
         
            +
                    24 => {r: false, c: 'FILE_TOO_BIG',                m: 'File too big for file system',                   a: 'File too big for filesystem'},
         
     | 
| 
      
 43 
     | 
    
         
            +
                    25 => {r: false, c: 'NO_SPACE_LEFT',               m: 'No space left on disk',                          a: 'No space left on disk'},
         
     | 
| 
      
 44 
     | 
    
         
            +
                    26 => {r: false, c: 'READ_ONLY_FS',                m: 'Read only file system',                          a: 'Read only filesystem'},
         
     | 
| 
      
 45 
     | 
    
         
            +
                    27 => {r: false, c: 'SOME_FILE_ERRS',              m: 'Some individual files failed',                   a: 'One or more files failed'},
         
     | 
| 
      
 46 
     | 
    
         
            +
                    28 => {r: false, c: 'USER_CANCEL',                 m: 'Cancelled by user',                              a: 'Cancelled by user'},
         
     | 
| 
      
 47 
     | 
    
         
            +
                    29 => {r: false, c: 'LIC_NOLIC',                   m: 'License not found or unable to access',          a: 'Unable to access license info'},
         
     | 
| 
      
 48 
     | 
    
         
            +
                    30 => {r: false, c: 'LIC_EXPIRED',                 m: 'License expired',                                a: 'License expired'},
         
     | 
| 
      
 49 
     | 
    
         
            +
                    31 => {r: false, c: 'SOCK_SETUP',                  m: 'Unable to setup socket (create, bind, etc ...)', a: 'Unable to set up socket'},
         
     | 
| 
      
 50 
     | 
    
         
            +
                    32 => {r: true,  c: 'OUT_OF_MEMORY',               m: 'Out of memory, unable to allocate',              a: 'Out of memory'},
         
     | 
| 
      
 51 
     | 
    
         
            +
                    33 => {r: true,  c: 'THREAD_SPAWN',                m: 'Can\'t spawn thread',                            a: 'Unable to spawn thread'},
         
     | 
| 
      
 52 
     | 
    
         
            +
                    34 => {r: false, c: 'UNAUTHORIZED',                m: 'Unauthorized by external auth server',           a: 'Unauthorized'},
         
     | 
| 
      
 53 
     | 
    
         
            +
                    35 => {r: true,  c: 'DISK_READ',                   m: 'Error reading source file from disk',            a: 'Disk read error'},
         
     | 
| 
      
 54 
     | 
    
         
            +
                    36 => {r: true,  c: 'DISK_WRITE',                  m: 'Error writing to disk',                          a: 'Disk write error'},
         
     | 
| 
      
 55 
     | 
    
         
            +
                    37 => {r: true,  c: 'AUTHORIZATION',               m: 'Used interchangeably with ERR_UNAUTHORIZED',     a: 'Authorization failure'},
         
     | 
| 
      
 56 
     | 
    
         
            +
                    38 => {r: false, c: 'LIC_ILLEGAL',                 m: 'Operation not permitted by license',             a: 'Operation not permitted by license'},
         
     | 
| 
      
 57 
     | 
    
         
            +
                    39 => {r: true,  c: 'PEER_ABORTED_SESSION',        m: 'Remote peer terminated session',                 a: 'Peer aborted session'},
         
     | 
| 
      
 58 
     | 
    
         
            +
                    40 => {r: true,  c: 'DATA_TRANSFER_TIMEOUT',       m: 'Transfer stalled, timed out',                    a: 'Data transfer stalled, timed out'},
         
     | 
| 
      
 59 
     | 
    
         
            +
                    41 => {r: false, c: 'BAD_PATH',                    m: 'Path violates docroot containment',              a: 'File location is outside \'docroot\' hierarchy'},
         
     | 
| 
      
 60 
     | 
    
         
            +
                    42 => {r: false, c: 'ALREADY_EXISTS',              m: 'File or directory already exists',               a: 'File or directory already exists'},
         
     | 
| 
      
 61 
     | 
    
         
            +
                    43 => {r: false, c: 'STAT_FAILS',                  m: 'Cannot stat file',                               a: 'Cannot collect details about file or directory'},
         
     | 
| 
      
 62 
     | 
    
         
            +
                    44 => {r: true,  c: 'PMTU_BRTT_ERROR',             m: 'UDP session initiation fatal error',             a: 'UDP session initiation fatal error'},
         
     | 
| 
      
 63 
     | 
    
         
            +
                    45 => {r: true,  c: 'BWMEAS_ERROR',                m: 'Bandwidth measurement fatal error',              a: 'Bandwidth measurement fatal error'},
         
     | 
| 
      
 64 
     | 
    
         
            +
                    46 => {r: false, c: 'VLINK_ERROR',                 m: 'Virtual link error',                             a: 'Virtual link error'},
         
     | 
| 
      
 65 
     | 
    
         
            +
                    47 => {r: false, c: 'CONNECTION_ERROR_HTTP',       m: 'Error establishing HTTP connection',
         
     | 
| 
      
 66 
     | 
    
         
            +
                                                                        a: 'Error establishing HTTP connection (check HTTP port and firewall)'},
         
     | 
| 
      
 67 
     | 
    
         
            +
                    48 => {r: false, c: 'FILE_ENCRYPTION_ERROR',       m: 'File encryption error, e.g. corrupt file',
         
     | 
| 
      
 68 
     | 
    
         
            +
                                                                        a: 'File encryption/decryption error, e.g. corrupt file'},
         
     | 
| 
      
 69 
     | 
    
         
            +
                    49 => {r: false, c: 'FILE_DECRYPTION_PASS',        m: 'File encryption/decryption error, e.g. corrupt file', a: 'File decryption error, bad passphrase'},
         
     | 
| 
      
 70 
     | 
    
         
            +
                    50 => {r: false, c: 'BAD_CONFIGURATION',           m: 'Aspera.conf contains invalid data and was rejected',  a: 'Invalid configuration'},
         
     | 
| 
      
 71 
     | 
    
         
            +
                    51 => {r: false, c: 'INSECURE_CONNECTION',         m: 'Remote-host key check failure',                  a: 'Remote host is not who we expected'},
         
     | 
| 
      
 72 
     | 
    
         
            +
                    52 => {r: false, c: 'START_VALIDATION_FAILED',     m: 'File start validation failed',                   a: 'File start validation failed'},
         
     | 
| 
      
 73 
     | 
    
         
            +
                    53 => {r: false, c: 'STOP_VALIDATION_FAILED',      m: 'File stop validation failed',                    a: 'File stop validation failed'},
         
     | 
| 
      
 74 
     | 
    
         
            +
                    54 => {r: false, c: 'THRESHOLD_VALIDATION_FAILED', m: 'File threshold validation failed',               a: 'File threshold validation failed'},
         
     | 
| 
      
 75 
     | 
    
         
            +
                    55 => {r: false, c: 'FILEPATH_TOO_LONG',           m: 'File path/name too long for underlying file system', a: 'File path exceeds underlying file system limit'},
         
     | 
| 
      
 76 
     | 
    
         
            +
                    56 => {r: false, c: 'ILLEGAL_CHARS_IN_PATH',       m: 'Windows path contains illegal characters',
         
     | 
| 
      
 77 
     | 
    
         
            +
                                                                            a: 'Path being written to Windows file system contains illegal characters'},
         
     | 
| 
      
 78 
     | 
    
         
            +
                    57 => {r: false, c: 'CHUNK_MUST_MATCH_ALIGNMENT',  m: 'Chunk size/start must be aligned with storage',  a: 'Chunk size/start must be aligned with storage'},
         
     | 
| 
      
 79 
     | 
    
         
            +
                    58 => {r: false, c: 'VALIDATION_SESSION_ABORT',    m: 'Session aborted to due to validation error',     a: 'Session aborted to due validation error'},
         
     | 
| 
      
 80 
     | 
    
         
            +
                    59 => {r: false, c: 'REMOTE_STORAGE_ERROR',        m: 'Remote storage errored',                         a: 'Remote storage errored'},
         
     | 
| 
      
 81 
     | 
    
         
            +
                    60 => {r: false, c: 'LUA_SCRIPT_ABORTED_SESSION',  m: 'Session aborted due to Lua script abort',        a: 'Session aborted due to Lua script abort'},
         
     | 
| 
      
 82 
     | 
    
         
            +
                    61 => {r: true,  c: 'SSEAR_RETRYABLE',             m: 'Transfer failed because of a retryable Encryption at Rest error',
         
     | 
| 
      
 83 
     | 
    
         
            +
                                                                            a: 'Transfer failed because of a retryable Encryption at Rest error'},
         
     | 
| 
      
 84 
     | 
    
         
            +
                    62 => {r: false, c: 'SSEAR_FATAL',                 m: 'Transfer failed because of a fatal Encryption at Rest error',
         
     | 
| 
      
 85 
     | 
    
         
            +
                                                                            a: 'Transfer failed because of a fatal Encryption at Rest error'},
         
     | 
| 
      
 86 
     | 
    
         
            +
                    63 => {r: false, c: 'LINK_LOOP',                   m: 'Path refers to a symbolic link loop',            a: 'Path refers to a symbolic link loop'},
         
     | 
| 
      
 87 
     | 
    
         
            +
                    64 => {r: false, c: 'CANNOT_RENAME_PARTIAL_FILES', m: 'Can\'t rename a partial file',                   a: 'Can\'t rename a partial file.'},
         
     | 
| 
      
 88 
     | 
    
         
            +
                    65 => {r: false, c: 'CIPHER_NON_COMPAT_FIPS',      m: 'Can\'t use this cipher with FIPS mode enabled',  a: 'Can\'t use this cipher with FIPS mode enabled'},
         
     | 
| 
      
 89 
     | 
    
         
            +
                    66 => {r: false, c: 'PEER_REQUIRES_FIPS',          m: 'Peer rejects cipher due to FIPS mode enabled on peer',
         
     | 
| 
      
 90 
     | 
    
         
            +
                                                                            a: 'Peer rejects cipher due to FIPS mode enabled on peer'}
         
     | 
| 
      
 91 
     | 
    
         
            +
                  }.freeze
         
     | 
| 
      
 92 
     | 
    
         
            +
                  # rubocop:enable Layout/FirstHashElementLineBreak
         
     | 
| 
       9 
93 
     | 
    
         
             
                  # cspell: disable
         
     | 
| 
       10 
94 
     | 
    
         
             
                  OPERATIONS = %w[
         
     | 
| 
       11 
95 
     | 
    
         
             
                    NOP
         
     | 
| 
         @@ -187,7 +271,8 @@ module Aspera 
     | 
|
| 
       187 
271 
     | 
    
         
             
                    ExtraCreatePolicy
         
     | 
| 
       188 
272 
     | 
    
         
             
                  ]
         
     | 
| 
       189 
273 
     | 
    
         
             
                  # Management port start message
         
     | 
| 
       190 
     | 
    
         
            -
                   
     | 
| 
      
 274 
     | 
    
         
            +
                  PROT_VERSION = '2'
         
     | 
| 
      
 275 
     | 
    
         
            +
                  MGT_HEADER = "FASPMGR #{PROT_VERSION}"
         
     | 
| 
       191 
276 
     | 
    
         
             
                  # empty line is separator to end event information
         
     | 
| 
       192 
277 
     | 
    
         
             
                  MGT_FRAME_SEPARATOR = ''
         
     | 
| 
       193 
278 
     | 
    
         
             
                  # fields description for JSON generation
         
     | 
| 
         @@ -204,33 +289,44 @@ module Aspera 
     | 
|
| 
       204 
289 
     | 
    
         
             
                  # cspell: enable
         
     | 
| 
       205 
290 
     | 
    
         | 
| 
       206 
291 
     | 
    
         
             
                  class << self
         
     | 
| 
       207 
     | 
    
         
            -
                    #  
     | 
| 
       208 
     | 
    
         
            -
                    def  
     | 
| 
       209 
     | 
    
         
            -
                       
     | 
| 
       210 
     | 
    
         
            -
             
     | 
| 
       211 
     | 
    
         
            -
             
     | 
| 
       212 
     | 
    
         
            -
             
     | 
| 
       213 
     | 
    
         
            -
             
     | 
| 
       214 
     | 
    
         
            -
                                 else e.capital_to_snake
         
     | 
| 
       215 
     | 
    
         
            -
                                 end
         
     | 
| 
       216 
     | 
    
         
            -
                               h[new_name] =
         
     | 
| 
       217 
     | 
    
         
            -
                                 if INTEGER_FIELDS.include?(e) then event[e].to_i
         
     | 
| 
       218 
     | 
    
         
            -
                                 elsif BOOLEAN_FIELDS.include?(e) then event[e].eql?(BOOLEAN_TRUE)
         
     | 
| 
       219 
     | 
    
         
            -
                                 else
         
     | 
| 
       220 
     | 
    
         
            -
                                   event[e]
         
     | 
| 
       221 
     | 
    
         
            -
                                 end
         
     | 
| 
       222 
     | 
    
         
            -
                             end
         
     | 
| 
      
 292 
     | 
    
         
            +
                    # translate native event name to snake case
         
     | 
| 
      
 293 
     | 
    
         
            +
                    def field_native_to_snake(name)
         
     | 
| 
      
 294 
     | 
    
         
            +
                      case name
         
     | 
| 
      
 295 
     | 
    
         
            +
                      when 'Elapsedusec' then 'elapsed_usec'
         
     | 
| 
      
 296 
     | 
    
         
            +
                      when 'Bytescont' then 'bytes_cont'
         
     | 
| 
      
 297 
     | 
    
         
            +
                      else name.capital_to_snake
         
     | 
| 
      
 298 
     | 
    
         
            +
                      end
         
     | 
| 
       223 
299 
     | 
    
         
             
                    end
         
     | 
| 
       224 
300 
     | 
    
         | 
| 
       225 
     | 
    
         
            -
                    #  
     | 
| 
       226 
     | 
    
         
            -
                    # @param  
     | 
| 
      
 301 
     | 
    
         
            +
                    # translate snake case event name to native
         
     | 
| 
      
 302 
     | 
    
         
            +
                    # @param name [String] Field name
         
     | 
| 
      
 303 
     | 
    
         
            +
                    def field_snake_to_native(name)
         
     | 
| 
      
 304 
     | 
    
         
            +
                      field = name.delete('_')
         
     | 
| 
      
 305 
     | 
    
         
            +
                      result = PARAMETERS.find{ |w| w.casecmp?(field)}
         
     | 
| 
      
 306 
     | 
    
         
            +
                      raise "No such field: #{name}" if result.nil?
         
     | 
| 
      
 307 
     | 
    
         
            +
                      result
         
     | 
| 
      
 308 
     | 
    
         
            +
                    end
         
     | 
| 
      
 309 
     | 
    
         
            +
             
     | 
| 
      
 310 
     | 
    
         
            +
                    # Translates mgt port event into (enhanced) typed event
         
     | 
| 
      
 311 
     | 
    
         
            +
                    def event_native_to_snake(event)
         
     | 
| 
      
 312 
     | 
    
         
            +
                      event.each_with_object({}) do |(key, value), h|
         
     | 
| 
      
 313 
     | 
    
         
            +
                        h[field_native_to_snake(key)] =
         
     | 
| 
      
 314 
     | 
    
         
            +
                          if INTEGER_FIELDS.include?(key) then value.to_i
         
     | 
| 
      
 315 
     | 
    
         
            +
                          elsif BOOLEAN_FIELDS.include?(key) then value.eql?(BOOLEAN_TRUE)
         
     | 
| 
      
 316 
     | 
    
         
            +
                          else
         
     | 
| 
      
 317 
     | 
    
         
            +
                            value
         
     | 
| 
      
 318 
     | 
    
         
            +
                          end
         
     | 
| 
      
 319 
     | 
    
         
            +
                      end
         
     | 
| 
      
 320 
     | 
    
         
            +
                    end
         
     | 
| 
      
 321 
     | 
    
         
            +
             
     | 
| 
      
 322 
     | 
    
         
            +
                    # Build command to send on management port
         
     | 
| 
      
 323 
     | 
    
         
            +
                    # @param data [Hash] e.g. {'type'=>'START','source'=>_path_,'destination'=>_path_}
         
     | 
| 
      
 324 
     | 
    
         
            +
                    # @return [String] frame to send on management port
         
     | 
| 
       227 
325 
     | 
    
         
             
                    def command_to_stream(data)
         
     | 
| 
       228 
     | 
    
         
            -
                      # TODO: translate enhanced to capitalized ?
         
     | 
| 
       229 
326 
     | 
    
         
             
                      data
         
     | 
| 
       230 
     | 
    
         
            -
                        . 
     | 
| 
       231 
     | 
    
         
            -
                        .map{ |k| "#{k.capitalize}: #{data[k]}"}
         
     | 
| 
      
 327 
     | 
    
         
            +
                        .map{ |key, value| "#{field_snake_to_native(key)}: #{value}"}
         
     | 
| 
       232 
328 
     | 
    
         
             
                        .unshift(MGT_HEADER)
         
     | 
| 
       233 
     | 
    
         
            -
                        .push( 
     | 
| 
      
 329 
     | 
    
         
            +
                        .push(MGT_FRAME_SEPARATOR, '')
         
     | 
| 
       234 
330 
     | 
    
         
             
                        .join("\n")
         
     | 
| 
       235 
331 
     | 
    
         
             
                    end
         
     | 
| 
       236 
332 
     | 
    
         
             
                  end
         
     | 
    
        data/lib/aspera/assert.rb
    CHANGED
    
    | 
         @@ -5,6 +5,10 @@ module Aspera 
     | 
|
| 
       5 
5 
     | 
    
         
             
              class Error < StandardError
         
     | 
| 
       6 
6 
     | 
    
         
             
              end
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
      
 8 
     | 
    
         
            +
              # Any problem with parameter values
         
     | 
| 
      
 9 
     | 
    
         
            +
              class ParameterError < Error
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
       8 
12 
     | 
    
         
             
              # Error that shall not happen, else it's a bug
         
     | 
| 
       9 
13 
     | 
    
         
             
              class InternalError < Error
         
     | 
| 
       10 
14 
     | 
    
         
             
              end
         
     | 
| 
         @@ -12,8 +16,10 @@ module Aspera 
     | 
|
| 
       12 
16 
     | 
    
         
             
              # An expected condition was not met
         
     | 
| 
       13 
17 
     | 
    
         
             
              class AssertError < Error
         
     | 
| 
       14 
18 
     | 
    
         
             
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
       15 
20 
     | 
    
         
             
              class << self
         
     | 
| 
       16 
     | 
    
         
            -
                #  
     | 
| 
      
 21 
     | 
    
         
            +
                # Replaces `raise` in assertion
         
     | 
| 
      
 22 
     | 
    
         
            +
                # Allows sending exception, or just error log, when type is `:error`
         
     | 
| 
       17 
23 
     | 
    
         
             
                # @param type [Exception,Symbol] Send to log if symbol, else raise exception
         
     | 
| 
       18 
24 
     | 
    
         
             
                # @param message [String] Message for error.
         
     | 
| 
       19 
25 
     | 
    
         
             
                def report_error(type, message)
         
     | 
| 
         @@ -28,7 +34,7 @@ module Aspera 
     | 
|
| 
       28 
34 
     | 
    
         
             
                # @param assertion [Bool]       Must be true
         
     | 
| 
       29 
35 
     | 
    
         
             
                # @param info      [String,nil] Fixed message in case assert fails, else use `block`
         
     | 
| 
       30 
36 
     | 
    
         
             
                # @param type      [Exception,Symbol] Exception to raise, or Symbol for Log.log
         
     | 
| 
       31 
     | 
    
         
            -
                # @param block     [Proc]       Produces a string that  
     | 
| 
      
 37 
     | 
    
         
            +
                # @param block     [Proc]       Produces a string that describes the problem for complex messages
         
     | 
| 
       32 
38 
     | 
    
         
             
                # The block is executed in the context of the Aspera module
         
     | 
| 
       33 
39 
     | 
    
         
             
                def assert(assertion, info = nil, type: AssertError)
         
     | 
| 
       34 
40 
     | 
    
         
             
                  raise InternalError, 'bad assert: both info and block given' unless info.nil? || !block_given?
         
     | 
| 
         @@ -41,19 +47,19 @@ module Aspera 
     | 
|
| 
       41 
47 
     | 
    
         
             
                end
         
     | 
| 
       42 
48 
     | 
    
         | 
| 
       43 
49 
     | 
    
         
             
                # Assert that value has the given type
         
     | 
| 
       44 
     | 
    
         
            -
                # @param value   [Object] 
     | 
| 
       45 
     | 
    
         
            -
                # @param classes [Class, Array] 
     | 
| 
      
 50 
     | 
    
         
            +
                # @param value   [Object]           The value to check
         
     | 
| 
      
 51 
     | 
    
         
            +
                # @param classes [Class, Array]     The expected type(s)
         
     | 
| 
       46 
52 
     | 
    
         
             
                # @param type    [Exception,Symbol] Exception to raise, or Symbol for Log.log
         
     | 
| 
       47 
     | 
    
         
            -
                # @param block   [Proc] 
     | 
| 
      
 53 
     | 
    
         
            +
                # @param block   [Proc]             Additional description in front of message
         
     | 
| 
       48 
54 
     | 
    
         
             
                def assert_type(value, *classes, type: AssertError)
         
     | 
| 
       49 
55 
     | 
    
         
             
                  assert(classes.any?{ |k| value.is_a?(k)}, type: type){"#{"#{yield}: " if block_given?}expecting #{classes.join(', ')}, but have #{value.inspect}"}
         
     | 
| 
       50 
56 
     | 
    
         
             
                end
         
     | 
| 
       51 
57 
     | 
    
         | 
| 
       52 
58 
     | 
    
         
             
                # Assert that value is one of the given values
         
     | 
| 
       53 
     | 
    
         
            -
                # @param value  [any] 
     | 
| 
       54 
     | 
    
         
            -
                # @param values [Array]  
     | 
| 
      
 59 
     | 
    
         
            +
                # @param value  [any]              Value to check
         
     | 
| 
      
 60 
     | 
    
         
            +
                # @param values [Array]            Accepted values
         
     | 
| 
       55 
61 
     | 
    
         
             
                # @param type   [Exception,Symbol] Exception to raise, or Symbol for Log.log
         
     | 
| 
       56 
     | 
    
         
            -
                # @param block  [Proc] 
     | 
| 
      
 62 
     | 
    
         
            +
                # @param block  [Proc]             Additional description in front of message
         
     | 
| 
       57 
63 
     | 
    
         
             
                def assert_values(value, values, type: AssertError)
         
     | 
| 
       58 
64 
     | 
    
         
             
                  assert(values.include?(value), type: type) do
         
     | 
| 
       59 
65 
     | 
    
         
             
                    val_list = values.inspect
         
     | 
| 
         @@ -13,7 +13,7 @@ require 'singleton' 
     | 
|
| 
       13 
13 
     | 
    
         | 
| 
       14 
14 
     | 
    
         
             
            module Aspera
         
     | 
| 
       15 
15 
     | 
    
         
             
              module Cli
         
     | 
| 
       16 
     | 
    
         
            -
                #  
     | 
| 
      
 16 
     | 
    
         
            +
                # Command line extended values
         
     | 
| 
       17 
17 
     | 
    
         
             
                class ExtendedValue
         
     | 
| 
       18 
18 
     | 
    
         
             
                  include Singleton
         
     | 
| 
       19 
19 
     | 
    
         | 
| 
         @@ -21,15 +21,15 @@ module Aspera 
     | 
|
| 
       21 
21 
     | 
    
         
             
                  MARKER_END = ':'
         
     | 
| 
       22 
22 
     | 
    
         
             
                  MARKER_IN_END = '@'
         
     | 
| 
       23 
23 
     | 
    
         | 
| 
       24 
     | 
    
         
            -
                  #  
     | 
| 
       25 
     | 
    
         
            -
                  # extend includes processing of other handlers in itself
         
     | 
| 
       26 
     | 
    
         
            -
                  # val keeps the value intact
         
     | 
| 
      
 24 
     | 
    
         
            +
                  # Special handlers stop processing of handlers on right
         
     | 
| 
      
 25 
     | 
    
         
            +
                  # :extend includes processing of other handlers in itself
         
     | 
| 
      
 26 
     | 
    
         
            +
                  # :val keeps the value intact
         
     | 
| 
       27 
27 
     | 
    
         
             
                  SPECIAL_HANDLERS = %i[extend val].freeze
         
     | 
| 
       28 
28 
     | 
    
         | 
| 
       29 
29 
     | 
    
         
             
                  private_constant :MARKER_START, :MARKER_END, :MARKER_IN_END, :SPECIAL_HANDLERS
         
     | 
| 
       30 
30 
     | 
    
         | 
| 
       31 
31 
     | 
    
         
             
                  class << self
         
     | 
| 
       32 
     | 
    
         
            -
                    #  
     | 
| 
      
 32 
     | 
    
         
            +
                    # Decode comma separated table text
         
     | 
| 
       33 
33 
     | 
    
         
             
                    def decode_csvt(value)
         
     | 
| 
       34 
34 
     | 
    
         
             
                      col_titles = nil
         
     | 
| 
       35 
35 
     | 
    
         
             
                      hash_array = []
         
     | 
| 
         @@ -53,8 +53,8 @@ module Aspera 
     | 
|
| 
       53 
53 
     | 
    
         
             
                  private
         
     | 
| 
       54 
54 
     | 
    
         | 
| 
       55 
55 
     | 
    
         
             
                  def initialize
         
     | 
| 
       56 
     | 
    
         
            -
                    #  
     | 
| 
       57 
     | 
    
         
            -
                    #  
     | 
| 
      
 56 
     | 
    
         
            +
                    # Base handlers
         
     | 
| 
      
 57 
     | 
    
         
            +
                    # Other handlers can be set using set_handler, e.g. `preset` is reader in config plugin
         
     | 
| 
       58 
58 
     | 
    
         
             
                    @handlers = {
         
     | 
| 
       59 
59 
     | 
    
         
             
                      val:    lambda{ |i| i},
         
     | 
| 
       60 
60 
     | 
    
         
             
                      base64: lambda{ |i| Base64.decode64(i)},
         
     | 
| 
         @@ -107,28 +107,28 @@ module Aspera 
     | 
|
| 
       107 
107 
     | 
    
         
             
                  public
         
     | 
| 
       108 
108 
     | 
    
         | 
| 
       109 
109 
     | 
    
         
             
                  def default_decoder=(value)
         
     | 
| 
       110 
     | 
    
         
            -
                    Log.log.debug{" 
     | 
| 
      
 110 
     | 
    
         
            +
                    Log.log.debug{"Setting default decoder to (#{value.class}) #{value}"}
         
     | 
| 
       111 
111 
     | 
    
         
             
                    Aspera.assert(value.nil? || @handlers.key?(value))
         
     | 
| 
       112 
112 
     | 
    
         
             
                    @default_decoder = value
         
     | 
| 
       113 
113 
     | 
    
         
             
                  end
         
     | 
| 
       114 
114 
     | 
    
         | 
| 
       115 
115 
     | 
    
         
             
                  def modifiers; @handlers.keys; end
         
     | 
| 
       116 
116 
     | 
    
         | 
| 
       117 
     | 
    
         
            -
                  #  
     | 
| 
      
 117 
     | 
    
         
            +
                  # Add a new handler
         
     | 
| 
       118 
118 
     | 
    
         
             
                  def set_handler(name, method)
         
     | 
| 
       119 
119 
     | 
    
         
             
                    Log.log.debug{"setting handler for #{name}"}
         
     | 
| 
       120 
120 
     | 
    
         
             
                    Aspera.assert_type(name, Symbol){'name'}
         
     | 
| 
       121 
121 
     | 
    
         
             
                    @handlers[name] = method
         
     | 
| 
       122 
122 
     | 
    
         
             
                  end
         
     | 
| 
       123 
123 
     | 
    
         | 
| 
       124 
     | 
    
         
            -
                  #  
     | 
| 
       125 
     | 
    
         
            -
                  #  
     | 
| 
      
 124 
     | 
    
         
            +
                  # Parse an string value to extended value, if it is a String using supported extended value modifiers
         
     | 
| 
      
 125 
     | 
    
         
            +
                  # Other value types are returned as is
         
     | 
| 
       126 
126 
     | 
    
         
             
                  # @param value [String] the value to parse
         
     | 
| 
       127 
127 
     | 
    
         
             
                  # @param expect [Class,Array] one or a list of expected types
         
     | 
| 
       128 
128 
     | 
    
         
             
                  def evaluate(value)
         
     | 
| 
       129 
129 
     | 
    
         
             
                    return value unless value.is_a?(String)
         
     | 
| 
       130 
130 
     | 
    
         
             
                    regex = Regexp.new("^#{handler_regex_string}(.*)$", Regexp::MULTILINE)
         
     | 
| 
       131 
     | 
    
         
            -
                    #  
     | 
| 
      
 131 
     | 
    
         
            +
                    # First determine decoders, in reversed order
         
     | 
| 
       132 
132 
     | 
    
         
             
                    handlers_reversed = []
         
     | 
| 
       133 
133 
     | 
    
         
             
                    while (m = value.match(regex))
         
     | 
| 
       134 
134 
     | 
    
         
             
                      handler = m[1].to_sym
         
     | 
| 
         @@ -143,14 +143,14 @@ module Aspera 
     | 
|
| 
       143 
143 
     | 
    
         
             
                    return value
         
     | 
| 
       144 
144 
     | 
    
         
             
                  end
         
     | 
| 
       145 
145 
     | 
    
         | 
| 
       146 
     | 
    
         
            -
                  #  
     | 
| 
       147 
     | 
    
         
            -
                  #  
     | 
| 
      
 146 
     | 
    
         
            +
                  # Parse string value as extended value
         
     | 
| 
      
 147 
     | 
    
         
            +
                  # Use default decoder if none is specified
         
     | 
| 
       148 
148 
     | 
    
         
             
                  def evaluate_with_default(value)
         
     | 
| 
       149 
149 
     | 
    
         
             
                    value = [MARKER_START, @default_decoder, MARKER_END, value].join if value.is_a?(String) && value.match(/^#{handler_regex_string}.*$/).nil? && !@default_decoder.nil?
         
     | 
| 
       150 
150 
     | 
    
         
             
                    return evaluate(value)
         
     | 
| 
       151 
151 
     | 
    
         
             
                  end
         
     | 
| 
       152 
152 
     | 
    
         | 
| 
       153 
     | 
    
         
            -
                  #  
     | 
| 
      
 153 
     | 
    
         
            +
                  # Find inner extended values
         
     | 
| 
       154 
154 
     | 
    
         
             
                  def evaluate_all(value)
         
     | 
| 
       155 
155 
     | 
    
         
             
                    regex = Regexp.new("^(.*)#{handler_regex_string}([^#{MARKER_IN_END}]*)#{MARKER_IN_END}(.*)$", Regexp::MULTILINE)
         
     | 
| 
       156 
156 
     | 
    
         
             
                    while (m = value.match(regex))
         
     | 
    
        data/lib/aspera/cli/formatter.rb
    CHANGED
    
    | 
         @@ -68,7 +68,7 @@ module Aspera 
     | 
|
| 
       68 
68 
     | 
    
         
             
                      value.bold
         
     | 
| 
       69 
69 
     | 
    
         
             
                    end
         
     | 
| 
       70 
70 
     | 
    
         | 
| 
       71 
     | 
    
         
            -
                    # replace empty values with a readable version
         
     | 
| 
      
 71 
     | 
    
         
            +
                    # replace empty values with a readable version on terminal
         
     | 
| 
       72 
72 
     | 
    
         
             
                    def enhance_display_values_hash(input_hash)
         
     | 
| 
       73 
73 
     | 
    
         
             
                      stack = [input_hash]
         
     | 
| 
       74 
74 
     | 
    
         
             
                      until stack.empty?
         
     | 
| 
         @@ -79,6 +79,8 @@ module Aspera 
     | 
|
| 
       79 
79 
     | 
    
         
             
                            current[key] = special_format('null')
         
     | 
| 
       80 
80 
     | 
    
         
             
                          when String
         
     | 
| 
       81 
81 
     | 
    
         
             
                            current[key] = special_format('empty string') if value.empty?
         
     | 
| 
      
 82 
     | 
    
         
            +
                          when Proc
         
     | 
| 
      
 83 
     | 
    
         
            +
                            current[key] = special_format('lambda')
         
     | 
| 
       82 
84 
     | 
    
         
             
                          when Array
         
     | 
| 
       83 
85 
     | 
    
         
             
                            if value.empty?
         
     | 
| 
       84 
86 
     | 
    
         
             
                              current[key] = special_format('empty list')
         
     | 
| 
         @@ -225,8 +227,8 @@ module Aspera 
     | 
|
| 
       225 
227 
     | 
    
         
             
                    end
         
     | 
| 
       226 
228 
     | 
    
         
             
                  end
         
     | 
| 
       227 
229 
     | 
    
         | 
| 
       228 
     | 
    
         
            -
                  def display_status(status, ** 
     | 
| 
       229 
     | 
    
         
            -
                    display_message(:info, status, ** 
     | 
| 
      
 230 
     | 
    
         
            +
                  def display_status(status, **kwargs)
         
     | 
| 
      
 231 
     | 
    
         
            +
                    display_message(:info, status, **kwargs)
         
     | 
| 
       230 
232 
     | 
    
         
             
                  end
         
     | 
| 
       231 
233 
     | 
    
         | 
| 
       232 
234 
     | 
    
         
             
                  def display_item_count(number, total)
         
     | 
| 
         @@ -314,7 +316,7 @@ module Aspera 
     | 
|
| 
       314 
316 
     | 
    
         
             
                    when :table, :csv
         
     | 
| 
       315 
317 
     | 
    
         
             
                      case type
         
     | 
| 
       316 
318 
     | 
    
         
             
                      when :single_object
         
     | 
| 
       317 
     | 
    
         
            -
                        # :single_object is a Hash, where key= 
     | 
| 
      
 319 
     | 
    
         
            +
                        # :single_object is a Hash, where key=column name
         
     | 
| 
       318 
320 
     | 
    
         
             
                        Aspera.assert_type(data, Hash)
         
     | 
| 
       319 
321 
     | 
    
         
             
                        if data.empty?
         
     | 
| 
       320 
322 
     | 
    
         
             
                          display_message(:data, self.class.special_format('empty dict'))
         
     | 
| 
         @@ -323,7 +325,7 @@ module Aspera 
     | 
|
| 
       323 
325 
     | 
    
         
             
                          display_table([data], compute_fields([data], fields), single: true)
         
     | 
| 
       324 
326 
     | 
    
         
             
                        end
         
     | 
| 
       325 
327 
     | 
    
         
             
                      when :object_list
         
     | 
| 
       326 
     | 
    
         
            -
                        # :object_list is an Array of Hash, where key= 
     | 
| 
      
 328 
     | 
    
         
            +
                        # :object_list is an Array of Hash, where key=column name
         
     | 
| 
       327 
329 
     | 
    
         
             
                        Aspera.assert_type(data, Array)
         
     | 
| 
       328 
330 
     | 
    
         
             
                        Aspera.assert(data.all?(Hash)){"expecting Array of Hash: #{data.inspect}"}
         
     | 
| 
       329 
331 
     | 
    
         
             
                        data = data.map{ |obj| self.class.flatten_hash(obj)} if @options[:flat_hash]
         
     | 
    
        data/lib/aspera/cli/hints.rb
    CHANGED
    
    | 
         @@ -100,6 +100,14 @@ module Aspera 
     | 
|
| 
       100 
100 
     | 
    
         
             
                      remediation: [
         
     | 
| 
       101 
101 
     | 
    
         
             
                        'home not created in Windows?'
         
     | 
| 
       102 
102 
     | 
    
         
             
                      ]
         
     | 
| 
      
 103 
     | 
    
         
            +
                    },
         
     | 
| 
      
 104 
     | 
    
         
            +
                    {
         
     | 
| 
      
 105 
     | 
    
         
            +
                      exception:   Aspera::RestCallError,
         
     | 
| 
      
 106 
     | 
    
         
            +
                      match:       /Server is not configured for this request/,
         
     | 
| 
      
 107 
     | 
    
         
            +
                      remediation: [
         
     | 
| 
      
 108 
     | 
    
         
            +
                        'Transfer user shall have those parameters in aspera.conf set to: token',
         
     | 
| 
      
 109 
     | 
    
         
            +
                        'authorization_transfer_in_value authorization_transfer_out_value'
         
     | 
| 
      
 110 
     | 
    
         
            +
                      ]
         
     | 
| 
       103 
111 
     | 
    
         
             
                    }
         
     | 
| 
       104 
112 
     | 
    
         
             
                  ]
         
     | 
| 
       105 
113 
     | 
    
         
             
                  private_constant :ERROR_HINTS
         
     | 
    
        data/lib/aspera/cli/info.rb
    CHANGED
    
    | 
         @@ -3,16 +3,16 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            module Aspera
         
     | 
| 
       4 
4 
     | 
    
         
             
              module Cli
         
     | 
| 
       5 
5 
     | 
    
         
             
                module Info
         
     | 
| 
       6 
     | 
    
         
            -
                  #  
     | 
| 
      
 6 
     | 
    
         
            +
                  # Name of command line tool, also used as foldername where config is stored
         
     | 
| 
       7 
7 
     | 
    
         
             
                  CMD_NAME = 'ascli'
         
     | 
| 
       8 
     | 
    
         
            -
                  #  
     | 
| 
      
 8 
     | 
    
         
            +
                  # Name of the containing gem, same as in <gem name>.gemspec
         
     | 
| 
       9 
9 
     | 
    
         
             
                  GEM_NAME = 'aspera-cli'
         
     | 
| 
       10 
10 
     | 
    
         
             
                  DOC_URL  = "https://www.rubydoc.info/gems/#{GEM_NAME}"
         
     | 
| 
       11 
11 
     | 
    
         
             
                  GEM_URL  = "https://rubygems.org/gems/#{GEM_NAME}"
         
     | 
| 
       12 
12 
     | 
    
         
             
                  SRC_URL  = 'https://github.com/IBM/aspera-cli'
         
     | 
| 
       13 
13 
     | 
    
         
             
                  CONTAINER = 'docker.io/martinlaurent/ascli'
         
     | 
| 
       14 
     | 
    
         
            -
                  #  
     | 
| 
       15 
     | 
    
         
            -
                  #  
     | 
| 
      
 14 
     | 
    
         
            +
                  # Set this to warn in advance when minimum required ruby version will increase
         
     | 
| 
      
 15 
     | 
    
         
            +
                  # See also required_ruby_version in gemspec file
         
     | 
| 
       16 
16 
     | 
    
         
             
                  RUBY_FUTURE_MINIMUM_VERSION = '3.2'
         
     | 
| 
       17 
17 
     | 
    
         
             
                end
         
     | 
| 
       18 
18 
     | 
    
         
             
              end
         
     |