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
 
| 
         @@ -1,10 +1,11 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            require 'aspera/cli/plugins/oauth'
         
     | 
| 
       3 
4 
     | 
    
         
             
            require 'aspera/cli/plugins/node'
         
     | 
| 
       4 
5 
     | 
    
         
             
            require 'aspera/cli/plugins/ats'
         
     | 
| 
       5 
     | 
    
         
            -
            require 'aspera/cli/basic_auth_plugin'
         
     | 
| 
       6 
6 
     | 
    
         
             
            require 'aspera/cli/transfer_agent'
         
     | 
| 
       7 
7 
     | 
    
         
             
            require 'aspera/cli/special_values'
         
     | 
| 
      
 8 
     | 
    
         
            +
            require 'aspera/cli/wizard'
         
     | 
| 
       8 
9 
     | 
    
         
             
            require 'aspera/agent/node'
         
     | 
| 
       9 
10 
     | 
    
         
             
            require 'aspera/transfer/spec'
         
     | 
| 
       10 
11 
     | 
    
         
             
            require 'aspera/api/aoc'
         
     | 
| 
         @@ -18,11 +19,9 @@ require 'date' 
     | 
|
| 
       18 
19 
     | 
    
         
             
            module Aspera
         
     | 
| 
       19 
20 
     | 
    
         
             
              module Cli
         
     | 
| 
       20 
21 
     | 
    
         
             
                module Plugins
         
     | 
| 
       21 
     | 
    
         
            -
                  class Aoc <  
     | 
| 
      
 22 
     | 
    
         
            +
                  class Aoc < Oauth
         
     | 
| 
       22 
23 
     | 
    
         
             
                    # default redirect for AoC web auth
         
     | 
| 
       23 
24 
     | 
    
         
             
                    REDIRECT_LOCALHOST = 'http://localhost:12345'
         
     | 
| 
       24 
     | 
    
         
            -
                    # OAuth methods supported
         
     | 
| 
       25 
     | 
    
         
            -
                    STD_AUTH_TYPES = %i[web jwt].freeze
         
     | 
| 
       26 
25 
     | 
    
         
             
                    # admin objects that can be manipulated
         
     | 
| 
       27 
26 
     | 
    
         
             
                    ADMIN_OBJECTS = %i[
         
     | 
| 
       28 
27 
     | 
    
         
             
                      self
         
     | 
| 
         @@ -57,7 +56,7 @@ module Aspera 
     | 
|
| 
       57 
56 
     | 
    
         
             
                    # options and parameters for Api::AoC.new
         
     | 
| 
       58 
57 
     | 
    
         
             
                    OPTIONS_NEW = %i[url auth client_id client_secret scope redirect_uri private_key passphrase username password workspace].freeze
         
     | 
| 
       59 
58 
     | 
    
         | 
| 
       60 
     | 
    
         
            -
                    private_constant :REDIRECT_LOCALHOST, : 
     | 
| 
      
 59 
     | 
    
         
            +
                    private_constant :REDIRECT_LOCALHOST, :ADMIN_OBJECTS, :PACKAGE_RECEIVED_BASE_QUERY, :OPTIONS_NEW, :PACKAGE_LIST_DEFAULT_FIELDS
         
     | 
| 
       61 
60 
     | 
    
         
             
                    class << self
         
     | 
| 
       62 
61 
     | 
    
         
             
                      def application_name
         
     | 
| 
       63 
62 
     | 
    
         
             
                        'Aspera on Cloud'
         
     | 
| 
         @@ -70,7 +69,7 @@ module Aspera 
     | 
|
| 
       70 
69 
     | 
    
         
             
                        base_url = "#{base_url}.#{Api::AoC::SAAS_DOMAIN_PROD}" unless base_url.include?('.')
         
     | 
| 
       71 
70 
     | 
    
         
             
                        # AoC is only https
         
     | 
| 
       72 
71 
     | 
    
         
             
                        return unless base_url.start_with?('https://')
         
     | 
| 
       73 
     | 
    
         
            -
                        res_http = Rest.new(base_url: base_url, redirect_max: 0).call(operation: 'GET', subpath: 'auth/ping',  
     | 
| 
      
 72 
     | 
    
         
            +
                        res_http = Rest.new(base_url: base_url, redirect_max: 0).call(operation: 'GET', subpath: 'auth/ping', exception: false)[:http]
         
     | 
| 
       74 
73 
     | 
    
         
             
                        return if res_http['Location'].nil?
         
     | 
| 
       75 
74 
     | 
    
         
             
                        redirect_uri = URI.parse(res_http['Location'])
         
     | 
| 
       76 
75 
     | 
    
         
             
                        od = Api::AoC.split_org_domain(URI.parse(base_url))
         
     | 
| 
         @@ -82,108 +81,6 @@ module Aspera 
     | 
|
| 
       82 
81 
     | 
    
         
             
                        }
         
     | 
| 
       83 
82 
     | 
    
         
             
                      end
         
     | 
| 
       84 
83 
     | 
    
         | 
| 
       85 
     | 
    
         
            -
                      # @param url [String] url to check
         
     | 
| 
       86 
     | 
    
         
            -
                      # @return [Bool] true if private key is required for the url (i.e. no passcode)
         
     | 
| 
       87 
     | 
    
         
            -
                      def private_key_required?(url)
         
     | 
| 
       88 
     | 
    
         
            -
                        # pub link do not need private key
         
     | 
| 
       89 
     | 
    
         
            -
                        return Api::AoC.link_info(url)[:token].nil?
         
     | 
| 
       90 
     | 
    
         
            -
                      end
         
     | 
| 
       91 
     | 
    
         
            -
             
     | 
| 
       92 
     | 
    
         
            -
                      # @param object [Plugin] An instance of this class
         
     | 
| 
       93 
     | 
    
         
            -
                      # @param private_key_path [String] path to private key
         
     | 
| 
       94 
     | 
    
         
            -
                      # @param pub_key_pem [String] PEM of public key
         
     | 
| 
       95 
     | 
    
         
            -
                      # @return [Hash] :preset_value, :test_args
         
     | 
| 
       96 
     | 
    
         
            -
                      def wizard(object:, private_key_path: nil, pub_key_pem: nil)
         
     | 
| 
       97 
     | 
    
         
            -
                        # set vars to look like object
         
     | 
| 
       98 
     | 
    
         
            -
                        options = object.options
         
     | 
| 
       99 
     | 
    
         
            -
                        formatter = object.formatter
         
     | 
| 
       100 
     | 
    
         
            -
                        instance_url = options.get_option(:url, mandatory: true)
         
     | 
| 
       101 
     | 
    
         
            -
                        pub_link_info = Api::AoC.link_info(instance_url)
         
     | 
| 
       102 
     | 
    
         
            -
                        if !pub_link_info[:token].nil?
         
     | 
| 
       103 
     | 
    
         
            -
                          pub_api = Rest.new(base_url: "https://#{URI.parse(pub_link_info[:url]).host}/api/v1")
         
     | 
| 
       104 
     | 
    
         
            -
                          pub_info = pub_api.read('env/url_token_check', {token: pub_link_info[:token]})
         
     | 
| 
       105 
     | 
    
         
            -
                          preset_value = {
         
     | 
| 
       106 
     | 
    
         
            -
                            link: instance_url
         
     | 
| 
       107 
     | 
    
         
            -
                          }
         
     | 
| 
       108 
     | 
    
         
            -
                          preset_value[:password] = options.get_option(:password, mandatory: true) if pub_info['password_protected']
         
     | 
| 
       109 
     | 
    
         
            -
                          return {
         
     | 
| 
       110 
     | 
    
         
            -
                            preset_value: preset_value,
         
     | 
| 
       111 
     | 
    
         
            -
                            test_args:    'organization'
         
     | 
| 
       112 
     | 
    
         
            -
                          }
         
     | 
| 
       113 
     | 
    
         
            -
                        end
         
     | 
| 
       114 
     | 
    
         
            -
                        options.declare(:use_generic_client, 'Wizard: AoC: use global or org specific jwt client id', values: :bool, default: Api::AoC.saas_url?(instance_url))
         
     | 
| 
       115 
     | 
    
         
            -
                        options.parse_options!
         
     | 
| 
       116 
     | 
    
         
            -
                        # make username mandatory for jwt, this triggers interactive input
         
     | 
| 
       117 
     | 
    
         
            -
                        wiz_username = options.get_option(:username, mandatory: true)
         
     | 
| 
       118 
     | 
    
         
            -
                        raise "Username shall be an email in AoC: #{wiz_username}" if !(wiz_username =~ /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i)
         
     | 
| 
       119 
     | 
    
         
            -
                        # Set the pub key and jwt tag in the user's profile automatically
         
     | 
| 
       120 
     | 
    
         
            -
                        auto_set_pub_key = false
         
     | 
| 
       121 
     | 
    
         
            -
                        auto_set_jwt = false
         
     | 
| 
       122 
     | 
    
         
            -
                        # use browser authentication to bootstrap
         
     | 
| 
       123 
     | 
    
         
            -
                        use_browser_authentication = false
         
     | 
| 
       124 
     | 
    
         
            -
                        if options.get_option(:use_generic_client)
         
     | 
| 
       125 
     | 
    
         
            -
                          formatter.display_status('Using global client_id.')
         
     | 
| 
       126 
     | 
    
         
            -
                          formatter.display_status('Please Login to your Aspera on Cloud instance.')
         
     | 
| 
       127 
     | 
    
         
            -
                          formatter.display_status('Navigate to: 👤 → Account Settings → Profile → Public Key')
         
     | 
| 
       128 
     | 
    
         
            -
                          formatter.display_status('Check or update the value to:'.red.blink)
         
     | 
| 
       129 
     | 
    
         
            -
                          formatter.display_status(pub_key_pem, hide_secrets: false)
         
     | 
| 
       130 
     | 
    
         
            -
                          if !options.get_option(:test_mode)
         
     | 
| 
       131 
     | 
    
         
            -
                            formatter.display_status('Once updated or validated, press enter.')
         
     | 
| 
       132 
     | 
    
         
            -
                            Environment.instance.open_uri(instance_url)
         
     | 
| 
       133 
     | 
    
         
            -
                            $stdin.gets
         
     | 
| 
       134 
     | 
    
         
            -
                          end
         
     | 
| 
       135 
     | 
    
         
            -
                        else
         
     | 
| 
       136 
     | 
    
         
            -
                          formatter.display_status('Using organization specific client_id.')
         
     | 
| 
       137 
     | 
    
         
            -
                          if options.get_option(:client_id).nil? || options.get_option(:client_secret).nil?
         
     | 
| 
       138 
     | 
    
         
            -
                            formatter.display_status('Please login to your Aspera on Cloud instance.'.red)
         
     | 
| 
       139 
     | 
    
         
            -
                            formatter.display_status('Navigate to: 𓃑  → Admin → Integrations → API Clients')
         
     | 
| 
       140 
     | 
    
         
            -
                            formatter.display_status('Check or create in integration:')
         
     | 
| 
       141 
     | 
    
         
            -
                            formatter.display_status('- name: cli')
         
     | 
| 
       142 
     | 
    
         
            -
                            formatter.display_status("- redirect uri: #{REDIRECT_LOCALHOST}")
         
     | 
| 
       143 
     | 
    
         
            -
                            formatter.display_status('- origin: localhost')
         
     | 
| 
       144 
     | 
    
         
            -
                            formatter.display_status('Use the generated client id and secret in the following prompts.'.red)
         
     | 
| 
       145 
     | 
    
         
            -
                          end
         
     | 
| 
       146 
     | 
    
         
            -
                          Environment.instance.open_uri("#{instance_url}/admin/integrations/api-clients")
         
     | 
| 
       147 
     | 
    
         
            -
                          options.get_option(:client_id, mandatory: true)
         
     | 
| 
       148 
     | 
    
         
            -
                          options.get_option(:client_secret, mandatory: true)
         
     | 
| 
       149 
     | 
    
         
            -
                          # use_browser_authentication = true
         
     | 
| 
       150 
     | 
    
         
            -
                        end
         
     | 
| 
       151 
     | 
    
         
            -
                        if use_browser_authentication
         
     | 
| 
       152 
     | 
    
         
            -
                          formatter.display_status('We will use web authentication to bootstrap.')
         
     | 
| 
       153 
     | 
    
         
            -
                          auto_set_pub_key = true
         
     | 
| 
       154 
     | 
    
         
            -
                          auto_set_jwt = true
         
     | 
| 
       155 
     | 
    
         
            -
                          Aspera.error_not_implemented
         
     | 
| 
       156 
     | 
    
         
            -
                          # aoc_api.oauth.grant_method = :web
         
     | 
| 
       157 
     | 
    
         
            -
                          # aoc_api.oauth.scope = Api::AoC::SCOPE_FILES_ADMIN
         
     | 
| 
       158 
     | 
    
         
            -
                          # aoc_api.oauth.specific_parameters[:redirect_uri] = REDIRECT_LOCALHOST
         
     | 
| 
       159 
     | 
    
         
            -
                        end
         
     | 
| 
       160 
     | 
    
         
            -
                        myself = object.aoc_api.read('self')
         
     | 
| 
       161 
     | 
    
         
            -
                        if auto_set_pub_key
         
     | 
| 
       162 
     | 
    
         
            -
                          Aspera.assert(myself['public_key'].empty?, type: Cli::Error){'Public key is already set in profile (use --override=yes)'} unless option_override
         
     | 
| 
       163 
     | 
    
         
            -
                          formatter.display_status('Updating profile with the public key.')
         
     | 
| 
       164 
     | 
    
         
            -
                          aoc_api.update("users/#{myself['id']}", {'public_key' => pub_key_pem})
         
     | 
| 
       165 
     | 
    
         
            -
                        end
         
     | 
| 
       166 
     | 
    
         
            -
                        if auto_set_jwt
         
     | 
| 
       167 
     | 
    
         
            -
                          formatter.display_status('Enabling JWT for client')
         
     | 
| 
       168 
     | 
    
         
            -
                          aoc_api.update("clients/#{options.get_option(:client_id)}", {'jwt_grant_enabled' => true, 'explicit_authorization_required' => false})
         
     | 
| 
       169 
     | 
    
         
            -
                        end
         
     | 
| 
       170 
     | 
    
         
            -
                        preset_result = {
         
     | 
| 
       171 
     | 
    
         
            -
                          url:         instance_url,
         
     | 
| 
       172 
     | 
    
         
            -
                          username:    myself['email'],
         
     | 
| 
       173 
     | 
    
         
            -
                          auth:        :jwt.to_s,
         
     | 
| 
       174 
     | 
    
         
            -
                          private_key: "@file:#{private_key_path}"
         
     | 
| 
       175 
     | 
    
         
            -
                        }
         
     | 
| 
       176 
     | 
    
         
            -
                        # set only if non nil
         
     | 
| 
       177 
     | 
    
         
            -
                        %i[client_id client_secret].each do |s|
         
     | 
| 
       178 
     | 
    
         
            -
                          o = options.get_option(s)
         
     | 
| 
       179 
     | 
    
         
            -
                          preset_result[s.to_s] = o unless o.nil?
         
     | 
| 
       180 
     | 
    
         
            -
                        end
         
     | 
| 
       181 
     | 
    
         
            -
                        return {
         
     | 
| 
       182 
     | 
    
         
            -
                          preset_value: preset_result,
         
     | 
| 
       183 
     | 
    
         
            -
                          test_args:    'user profile show'
         
     | 
| 
       184 
     | 
    
         
            -
                        }
         
     | 
| 
       185 
     | 
    
         
            -
                      end
         
     | 
| 
       186 
     | 
    
         
            -
             
     | 
| 
       187 
84 
     | 
    
         
             
                      # @param base [String] Base folder path
         
     | 
| 
       188 
85 
     | 
    
         
             
                      # @return [String] Folder path that does jot exist, with possible .<number> extension
         
     | 
| 
       189 
86 
     | 
    
         
             
                      def next_available_folder(base, always: false)
         
     | 
| 
         @@ -217,18 +114,97 @@ module Aspera 
     | 
|
| 
       217 
114 
     | 
    
         
             
                      end
         
     | 
| 
       218 
115 
     | 
    
         
             
                    end
         
     | 
| 
       219 
116 
     | 
    
         | 
| 
      
 117 
     | 
    
         
            +
                    # @param wizard  [Wizard] The wizard object
         
     | 
| 
      
 118 
     | 
    
         
            +
                    # @param app_url [Wizard] The wizard object
         
     | 
| 
      
 119 
     | 
    
         
            +
                    # @return [Hash] :preset_value, :test_args
         
     | 
| 
      
 120 
     | 
    
         
            +
                    def wizard(wizard, app_url)
         
     | 
| 
      
 121 
     | 
    
         
            +
                      pub_link_info = Api::AoC.link_info(app_url)
         
     | 
| 
      
 122 
     | 
    
         
            +
                      # public link case
         
     | 
| 
      
 123 
     | 
    
         
            +
                      if pub_link_info.key?(:token)
         
     | 
| 
      
 124 
     | 
    
         
            +
                        pub_api = Rest.new(base_url: "https://#{URI.parse(pub_link_info[:url]).host}/api/v1")
         
     | 
| 
      
 125 
     | 
    
         
            +
                        pub_info = pub_api.read('env/url_token_check', {token: pub_link_info[:token]})
         
     | 
| 
      
 126 
     | 
    
         
            +
                        preset_value = {
         
     | 
| 
      
 127 
     | 
    
         
            +
                          link: app_url
         
     | 
| 
      
 128 
     | 
    
         
            +
                        }
         
     | 
| 
      
 129 
     | 
    
         
            +
                        preset_value[:password] = options.get_option(:password, mandatory: true) if pub_info['password_protected']
         
     | 
| 
      
 130 
     | 
    
         
            +
                        return {
         
     | 
| 
      
 131 
     | 
    
         
            +
                          preset_value: preset_value,
         
     | 
| 
      
 132 
     | 
    
         
            +
                          test_args:    'organization'
         
     | 
| 
      
 133 
     | 
    
         
            +
                        }
         
     | 
| 
      
 134 
     | 
    
         
            +
                      end
         
     | 
| 
      
 135 
     | 
    
         
            +
                      options.declare(:use_generic_client, 'Wizard: AoC: use global or org specific jwt client id', values: :bool, default: Api::AoC.saas_url?(app_url))
         
     | 
| 
      
 136 
     | 
    
         
            +
                      options.parse_options!
         
     | 
| 
      
 137 
     | 
    
         
            +
                      # make username mandatory for jwt, this triggers interactive input
         
     | 
| 
      
 138 
     | 
    
         
            +
                      wiz_username = options.get_option(:username, mandatory: true)
         
     | 
| 
      
 139 
     | 
    
         
            +
                      wizard.check_email(wiz_username)
         
     | 
| 
      
 140 
     | 
    
         
            +
                      # Set the pub key and jwt tag in the user's profile automatically
         
     | 
| 
      
 141 
     | 
    
         
            +
                      auto_set_pub_key = false
         
     | 
| 
      
 142 
     | 
    
         
            +
                      auto_set_jwt = false
         
     | 
| 
      
 143 
     | 
    
         
            +
                      # use browser authentication to bootstrap
         
     | 
| 
      
 144 
     | 
    
         
            +
                      use_browser_authentication = false
         
     | 
| 
      
 145 
     | 
    
         
            +
                      private_key_path = wizard.ask_private_key(
         
     | 
| 
      
 146 
     | 
    
         
            +
                        user: wiz_username,
         
     | 
| 
      
 147 
     | 
    
         
            +
                        url: app_url,
         
     | 
| 
      
 148 
     | 
    
         
            +
                        page: '👤 → Account Settings → Profile → Public Key'
         
     | 
| 
      
 149 
     | 
    
         
            +
                      )
         
     | 
| 
      
 150 
     | 
    
         
            +
                      client_id = options.get_option(:client_id)
         
     | 
| 
      
 151 
     | 
    
         
            +
                      client_secret = options.get_option(:client_secret)
         
     | 
| 
      
 152 
     | 
    
         
            +
                      if client_id.nil? || client_secret.nil?
         
     | 
| 
      
 153 
     | 
    
         
            +
                        if options.get_option(:use_generic_client)
         
     | 
| 
      
 154 
     | 
    
         
            +
                          client_id = client_secret = nil
         
     | 
| 
      
 155 
     | 
    
         
            +
                          formatter.display_status('Using global client_id.')
         
     | 
| 
      
 156 
     | 
    
         
            +
                        else
         
     | 
| 
      
 157 
     | 
    
         
            +
                          formatter.display_status('Using organization specific client_id.')
         
     | 
| 
      
 158 
     | 
    
         
            +
                          formatter.display_status('Please login to your Aspera on Cloud instance.'.red)
         
     | 
| 
      
 159 
     | 
    
         
            +
                          formatter.display_status('Navigate to: 𓃑  → Admin → Integrations → API Clients')
         
     | 
| 
      
 160 
     | 
    
         
            +
                          formatter.display_status('Check or create in integration:')
         
     | 
| 
      
 161 
     | 
    
         
            +
                          formatter.display_status('- name: cli')
         
     | 
| 
      
 162 
     | 
    
         
            +
                          formatter.display_status("- redirect uri: #{REDIRECT_LOCALHOST}")
         
     | 
| 
      
 163 
     | 
    
         
            +
                          formatter.display_status('- origin: localhost')
         
     | 
| 
      
 164 
     | 
    
         
            +
                          formatter.display_status('Use the generated client id and secret in the following prompts.'.red)
         
     | 
| 
      
 165 
     | 
    
         
            +
                          Environment.instance.open_uri("#{app_url}/admin/integrations/api-clients")
         
     | 
| 
      
 166 
     | 
    
         
            +
                          client_id = options.get_option(:client_id, mandatory: true)
         
     | 
| 
      
 167 
     | 
    
         
            +
                          client_secret = options.get_option(:client_secret, mandatory: true)
         
     | 
| 
      
 168 
     | 
    
         
            +
                          # use_browser_authentication = true
         
     | 
| 
      
 169 
     | 
    
         
            +
                        end
         
     | 
| 
      
 170 
     | 
    
         
            +
                      end
         
     | 
| 
      
 171 
     | 
    
         
            +
                      if use_browser_authentication
         
     | 
| 
      
 172 
     | 
    
         
            +
                        formatter.display_status('We will use web authentication to bootstrap.')
         
     | 
| 
      
 173 
     | 
    
         
            +
                        auto_set_pub_key = true
         
     | 
| 
      
 174 
     | 
    
         
            +
                        auto_set_jwt = true
         
     | 
| 
      
 175 
     | 
    
         
            +
                        Aspera.error_not_implemented
         
     | 
| 
      
 176 
     | 
    
         
            +
                        # aoc_api.oauth.grant_method = :web
         
     | 
| 
      
 177 
     | 
    
         
            +
                        # aoc_api.oauth.scope = Api::AoC::SCOPE_FILES_ADMIN
         
     | 
| 
      
 178 
     | 
    
         
            +
                        # aoc_api.oauth.specific_parameters[:redirect_uri] = REDIRECT_LOCALHOST
         
     | 
| 
      
 179 
     | 
    
         
            +
                      end
         
     | 
| 
      
 180 
     | 
    
         
            +
                      myself = aoc_api.read('self')
         
     | 
| 
      
 181 
     | 
    
         
            +
                      if auto_set_pub_key
         
     | 
| 
      
 182 
     | 
    
         
            +
                        Aspera.assert(myself['public_key'].empty?, type: Cli::Error){'Public key is already set in profile (use --override=yes)'} unless option_override
         
     | 
| 
      
 183 
     | 
    
         
            +
                        formatter.display_status('Updating profile with the public key.')
         
     | 
| 
      
 184 
     | 
    
         
            +
                        aoc_api.update("users/#{myself['id']}", {'public_key' => pub_key_pem})
         
     | 
| 
      
 185 
     | 
    
         
            +
                      end
         
     | 
| 
      
 186 
     | 
    
         
            +
                      if auto_set_jwt
         
     | 
| 
      
 187 
     | 
    
         
            +
                        formatter.display_status('Enabling JWT for client')
         
     | 
| 
      
 188 
     | 
    
         
            +
                        aoc_api.update("clients/#{options.get_option(:client_id)}", {'jwt_grant_enabled' => true, 'explicit_authorization_required' => false})
         
     | 
| 
      
 189 
     | 
    
         
            +
                      end
         
     | 
| 
      
 190 
     | 
    
         
            +
                      return {
         
     | 
| 
      
 191 
     | 
    
         
            +
                        preset_value: {
         
     | 
| 
      
 192 
     | 
    
         
            +
                          url:           app_url,
         
     | 
| 
      
 193 
     | 
    
         
            +
                          username:      myself['email'],
         
     | 
| 
      
 194 
     | 
    
         
            +
                          auth:          :jwt.to_s,
         
     | 
| 
      
 195 
     | 
    
         
            +
                          private_key:   "@file:#{private_key_path}",
         
     | 
| 
      
 196 
     | 
    
         
            +
                          client_id:     client_id,
         
     | 
| 
      
 197 
     | 
    
         
            +
                          client_secret: client_secret
         
     | 
| 
      
 198 
     | 
    
         
            +
                        }.compact,
         
     | 
| 
      
 199 
     | 
    
         
            +
                        test_args:    'user profile show'
         
     | 
| 
      
 200 
     | 
    
         
            +
                      }
         
     | 
| 
      
 201 
     | 
    
         
            +
                    end
         
     | 
| 
      
 202 
     | 
    
         
            +
             
     | 
| 
       220 
203 
     | 
    
         
             
                    def initialize(**_)
         
     | 
| 
       221 
204 
     | 
    
         
             
                      super
         
     | 
| 
       222 
205 
     | 
    
         
             
                      @cache_workspace_info = nil
         
     | 
| 
       223 
206 
     | 
    
         
             
                      @cache_home_node_file = nil
         
     | 
| 
       224 
207 
     | 
    
         
             
                      @cache_api_aoc = nil
         
     | 
| 
       225 
     | 
    
         
            -
                      options.declare(:auth, 'OAuth type of authentication', values: STD_AUTH_TYPES, default: :jwt)
         
     | 
| 
       226 
     | 
    
         
            -
                      options.declare(:client_id, 'OAuth API client identifier')
         
     | 
| 
       227 
     | 
    
         
            -
                      options.declare(:client_secret, 'OAuth API client secret')
         
     | 
| 
       228 
     | 
    
         
            -
                      options.declare(:scope, 'OAuth scope for AoC API calls')
         
     | 
| 
       229 
     | 
    
         
            -
                      options.declare(:redirect_uri, 'OAuth API client redirect URI')
         
     | 
| 
       230 
     | 
    
         
            -
                      options.declare(:private_key, 'OAuth JWT RSA private key PEM value (prefix file path with @file:)')
         
     | 
| 
       231 
     | 
    
         
            -
                      options.declare(:passphrase, 'RSA private key passphrase', types: String)
         
     | 
| 
       232 
208 
     | 
    
         
             
                      options.declare(:workspace, 'Name of workspace', types: [String, NilClass], default: Api::AoC::DEFAULT_WORKSPACE)
         
     | 
| 
       233 
209 
     | 
    
         
             
                      options.declare(:new_user_option, 'New user creation option for unknown package recipients', types: Hash)
         
     | 
| 
       234 
210 
     | 
    
         
             
                      options.declare(:validate_metadata, 'Validate shared inbox metadata', values: :bool, default: true)
         
     | 
| 
         @@ -239,22 +215,22 @@ module Aspera 
     | 
|
| 
       239 
215 
     | 
    
         
             
                    end
         
     | 
| 
       240 
216 
     | 
    
         | 
| 
       241 
217 
     | 
    
         
             
                    def api_from_options(aoc_base_path)
         
     | 
| 
       242 
     | 
    
         
            -
                      create_values = OPTIONS_NEW.each_with_object({
         
     | 
| 
       243 
     | 
    
         
            -
                        subpath:       aoc_base_path,
         
     | 
| 
       244 
     | 
    
         
            -
                        secret_finder: config
         
     | 
| 
       245 
     | 
    
         
            -
                      }) do |i, m|
         
     | 
| 
       246 
     | 
    
         
            -
                        m[i] = options.get_option(i) unless options.get_option(i).nil?
         
     | 
| 
       247 
     | 
    
         
            -
                      end
         
     | 
| 
       248 
     | 
    
         
            -
                      create_values[:scope] = Api::AoC::SCOPE_FILES_USER if create_values[:scope].nil?
         
     | 
| 
       249 
218 
     | 
    
         
             
                      # create an API object with the same options, but with a different subpath
         
     | 
| 
       250 
     | 
    
         
            -
                      return  
     | 
| 
       251 
     | 
    
         
            -
             
     | 
| 
       252 
     | 
    
         
            -
             
     | 
| 
       253 
     | 
    
         
            -
             
     | 
| 
       254 
     | 
    
         
            -
             
     | 
| 
       255 
     | 
    
         
            -
             
     | 
| 
      
 219 
     | 
    
         
            +
                      return new_with_options(
         
     | 
| 
      
 220 
     | 
    
         
            +
                        Api::AoC,
         
     | 
| 
      
 221 
     | 
    
         
            +
                        base: {
         
     | 
| 
      
 222 
     | 
    
         
            +
                          subpath:       aoc_base_path,
         
     | 
| 
      
 223 
     | 
    
         
            +
                          secret_finder: config
         
     | 
| 
      
 224 
     | 
    
         
            +
                        },
         
     | 
| 
      
 225 
     | 
    
         
            +
                        add: {
         
     | 
| 
      
 226 
     | 
    
         
            +
                          scope:     Api::AoC::SCOPE_FILES_USER,
         
     | 
| 
      
 227 
     | 
    
         
            +
                          workspace: nil
         
     | 
| 
      
 228 
     | 
    
         
            +
                        }
         
     | 
| 
      
 229 
     | 
    
         
            +
                      )
         
     | 
| 
       256 
230 
     | 
    
         
             
                    end
         
     | 
| 
       257 
231 
     | 
    
         | 
| 
      
 232 
     | 
    
         
            +
                    # AoC Rest object
         
     | 
| 
      
 233 
     | 
    
         
            +
                    # @return [Rest]
         
     | 
| 
       258 
234 
     | 
    
         
             
                    def aoc_api
         
     | 
| 
       259 
235 
     | 
    
         
             
                      if @cache_api_aoc.nil?
         
     | 
| 
       260 
236 
     | 
    
         
             
                        @cache_api_aoc = api_from_options(Api::AoC::API_V1)
         
     | 
| 
         @@ -300,56 +276,11 @@ module Aspera 
     | 
|
| 
       300 
276 
     | 
    
         
             
                      return "#{resource_class_path}/#{get_resource_id_from_args(resource_class_path)}"
         
     | 
| 
       301 
277 
     | 
    
         
             
                    end
         
     | 
| 
       302 
278 
     | 
    
         | 
| 
       303 
     | 
    
         
            -
                    # Call block with same query using paging and response information
         
     | 
| 
       304 
     | 
    
         
            -
                    # block must return a hash with :data and :http keys
         
     | 
| 
       305 
     | 
    
         
            -
                    # @return [Hash] {items: , total: }
         
     | 
| 
       306 
     | 
    
         
            -
                    def api_call_paging(base_query = {})
         
     | 
| 
       307 
     | 
    
         
            -
                      Aspera.assert_type(base_query, Hash){'query'}
         
     | 
| 
       308 
     | 
    
         
            -
                      Aspera.assert(block_given?)
         
     | 
| 
       309 
     | 
    
         
            -
                      # set default large page if user does not specify own parameters. AoC Caps to 1000 anyway
         
     | 
| 
       310 
     | 
    
         
            -
                      base_query['per_page'] = 1000 unless base_query.key?('per_page')
         
     | 
| 
       311 
     | 
    
         
            -
                      max_items = base_query.delete(MAX_ITEMS)
         
     | 
| 
       312 
     | 
    
         
            -
                      max_pages = base_query.delete(MAX_PAGES)
         
     | 
| 
       313 
     | 
    
         
            -
                      item_list = []
         
     | 
| 
       314 
     | 
    
         
            -
                      total_count = nil
         
     | 
| 
       315 
     | 
    
         
            -
                      current_page = base_query['page']
         
     | 
| 
       316 
     | 
    
         
            -
                      current_page = 1 if current_page.nil?
         
     | 
| 
       317 
     | 
    
         
            -
                      page_count = 0
         
     | 
| 
       318 
     | 
    
         
            -
                      loop do
         
     | 
| 
       319 
     | 
    
         
            -
                        query = base_query.clone
         
     | 
| 
       320 
     | 
    
         
            -
                        query['page'] = current_page
         
     | 
| 
       321 
     | 
    
         
            -
                        result = yield(query)
         
     | 
| 
       322 
     | 
    
         
            -
                        Aspera.assert(result[:data])
         
     | 
| 
       323 
     | 
    
         
            -
                        Aspera.assert(result[:http])
         
     | 
| 
       324 
     | 
    
         
            -
                        total_count = result[:http]['X-Total-Count']
         
     | 
| 
       325 
     | 
    
         
            -
                        page_count += 1
         
     | 
| 
       326 
     | 
    
         
            -
                        current_page += 1
         
     | 
| 
       327 
     | 
    
         
            -
                        add_items = result[:data]
         
     | 
| 
       328 
     | 
    
         
            -
                        break if add_items.empty?
         
     | 
| 
       329 
     | 
    
         
            -
                        # append new items to full list
         
     | 
| 
       330 
     | 
    
         
            -
                        item_list += add_items
         
     | 
| 
       331 
     | 
    
         
            -
                        break if !max_items.nil? && item_list.count >= max_items
         
     | 
| 
       332 
     | 
    
         
            -
                        break if !max_pages.nil? && page_count >= max_pages
         
     | 
| 
       333 
     | 
    
         
            -
                        formatter.long_operation_running("#{item_list.count} / #{total_count}") unless total_count.eql?(item_list.count.to_s)
         
     | 
| 
       334 
     | 
    
         
            -
                      end
         
     | 
| 
       335 
     | 
    
         
            -
                      formatter.long_operation_terminated
         
     | 
| 
       336 
     | 
    
         
            -
                      item_list = item_list[0..max_items - 1] if !max_items.nil? && item_list.count > max_items
         
     | 
| 
       337 
     | 
    
         
            -
                      return {items: item_list, total: total_count}
         
     | 
| 
       338 
     | 
    
         
            -
                    end
         
     | 
| 
       339 
     | 
    
         
            -
             
     | 
| 
       340 
     | 
    
         
            -
                    # read using the query and paging
         
     | 
| 
       341 
     | 
    
         
            -
                    # @return [Hash] {data: , total: }
         
     | 
| 
       342 
     | 
    
         
            -
                    def api_read_all(resource_class_path, base_query = {})
         
     | 
| 
       343 
     | 
    
         
            -
                      return api_call_paging(base_query) do |query|
         
     | 
| 
       344 
     | 
    
         
            -
                        aoc_api.call(operation: 'GET', subpath: resource_class_path, headers: {'Accept' => Rest::MIME_JSON}, query: query)
         
     | 
| 
       345 
     | 
    
         
            -
                      end
         
     | 
| 
       346 
     | 
    
         
            -
                    end
         
     | 
| 
       347 
     | 
    
         
            -
             
     | 
| 
       348 
279 
     | 
    
         
             
                    # List all entities, given additional, default and user's queries
         
     | 
| 
       349 
280 
     | 
    
         
             
                    # @param resource_class_path path to query on API
         
     | 
| 
       350 
281 
     | 
    
         
             
                    # @param fields fields to display
         
     | 
| 
       351 
282 
     | 
    
         
             
                    # @param base_query a query applied always
         
     | 
| 
       352 
     | 
    
         
            -
                    # @param default_query default query unless  
     | 
| 
      
 283 
     | 
    
         
            +
                    # @param default_query default query unless overridden by user
         
     | 
| 
       353 
284 
     | 
    
         
             
                    # @param &block (Optional) calls block with user's or default query
         
     | 
| 
       354 
285 
     | 
    
         
             
                    def result_list(resource_class_path, fields: nil, base_query: {}, default_query: {})
         
     | 
| 
       355 
286 
     | 
    
         
             
                      Aspera.assert_type(base_query, Hash)
         
     | 
| 
         @@ -357,7 +288,7 @@ module Aspera 
     | 
|
| 
       357 
288 
     | 
    
         
             
                      query = query_read_delete(default: default_query)
         
     | 
| 
       358 
289 
     | 
    
         
             
                      # caller may add specific modifications or checks to query
         
     | 
| 
       359 
290 
     | 
    
         
             
                      yield(query) if block_given?
         
     | 
| 
       360 
     | 
    
         
            -
                      result =  
     | 
| 
      
 291 
     | 
    
         
            +
                      result = aoc_api.read_with_paging(resource_class_path, query: base_query.merge(query).compact, formatter: formatter)
         
     | 
| 
       361 
292 
     | 
    
         
             
                      return Main.result_object_list(result[:items], fields: fields, total: result[:total])
         
     | 
| 
       362 
293 
     | 
    
         
             
                    end
         
     | 
| 
       363 
294 
     | 
    
         | 
| 
         @@ -382,7 +313,7 @@ module Aspera 
     | 
|
| 
       382 
313 
     | 
    
         
             
                      Aspera.assert_type(query, Hash){'query'}
         
     | 
| 
       383 
314 
     | 
    
         
             
                      PACKAGE_RECEIVED_BASE_QUERY.each{ |k, v| query[k] = v unless query.key?(k)}
         
     | 
| 
       384 
315 
     | 
    
         
             
                      resolve_dropbox_name_default_ws_id(query)
         
     | 
| 
       385 
     | 
    
         
            -
                      return  
     | 
| 
      
 316 
     | 
    
         
            +
                      return aoc_api.read_with_paging('packages', query: query.compact, formatter: formatter)
         
     | 
| 
       386 
317 
     | 
    
         
             
                    end
         
     | 
| 
       387 
318 
     | 
    
         | 
| 
       388 
319 
     | 
    
         
             
                    NODE4_EXT_COMMANDS = %i[transfer].concat(Node::COMMANDS_GEN4).freeze
         
     | 
| 
         @@ -522,8 +453,6 @@ module Aspera 
     | 
|
| 
       522 
453 
     | 
    
         
             
                        return Main.result_success
         
     | 
| 
       523 
454 
     | 
    
         
             
                      when :do
         
     | 
| 
       524 
455 
     | 
    
         
             
                        command_repo = options.get_next_command(NODE4_EXT_COMMANDS)
         
     | 
| 
       525 
     | 
    
         
            -
                        # init context
         
     | 
| 
       526 
     | 
    
         
            -
                        aoc_api.context = :files
         
     | 
| 
       527 
456 
     | 
    
         
             
                        return execute_nodegen4_command(command_repo, res_id)
         
     | 
| 
       528 
457 
     | 
    
         
             
                      else Aspera.error_unexpected_value(command)
         
     | 
| 
       529 
458 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -691,7 +620,6 @@ module Aspera 
     | 
|
| 
       691 
620 
     | 
    
         
             
                          filter = query_read_delete(default: {})
         
     | 
| 
       692 
621 
     | 
    
         
             
                          filter['limit'] ||= 100
         
     | 
| 
       693 
622 
     | 
    
         
             
                          if options.get_option(:once_only, mandatory: true)
         
     | 
| 
       694 
     | 
    
         
            -
                            aoc_api.context = :files
         
     | 
| 
       695 
623 
     | 
    
         
             
                            saved_date = []
         
     | 
| 
       696 
624 
     | 
    
         
             
                            start_date_persistency = PersistencyActionOnce.new(
         
     | 
| 
       697 
625 
     | 
    
         
             
                              manager: persistency,
         
     | 
| 
         @@ -736,7 +664,6 @@ module Aspera 
     | 
|
| 
       736 
664 
     | 
    
         
             
                          return Main.result_object_list(events)
         
     | 
| 
       737 
665 
     | 
    
         
             
                        end
         
     | 
| 
       738 
666 
     | 
    
         
             
                      when :usage_reports
         
     | 
| 
       739 
     | 
    
         
            -
                        aoc_api.context = :files
         
     | 
| 
       740 
667 
     | 
    
         
             
                        return result_list('usage_reports', base_query: workspace_id_hash)
         
     | 
| 
       741 
668 
     | 
    
         
             
                      end
         
     | 
| 
       742 
669 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -809,7 +736,7 @@ module Aspera 
     | 
|
| 
       809 
736 
     | 
    
         
             
                        }
         
     | 
| 
       810 
737 
     | 
    
         
             
                        return result_list('short_links', fields: Formatter.all_but('data'), base_query: list_params) if command.eql?(:list)
         
     | 
| 
       811 
738 
     | 
    
         
             
                        one_id = instance_identifier
         
     | 
| 
       812 
     | 
    
         
            -
                        found =  
     | 
| 
      
 739 
     | 
    
         
            +
                        found = aoc_api.read_with_paging('short_links', query: list_params, formatter: formatter)[:items].find{ |item| item['id'].eql?(one_id)}
         
     | 
| 
       813 
740 
     | 
    
         
             
                        raise Cli::BadIdentifier.new('Short link', one_id) if found.nil?
         
     | 
| 
       814 
741 
     | 
    
         
             
                        return Main.result_single_object(found, fields: Formatter.all_but('data'))
         
     | 
| 
       815 
742 
     | 
    
         
             
                      when :modify
         
     | 
| 
         @@ -876,7 +803,6 @@ module Aspera 
     | 
|
| 
       876 
803 
     | 
    
         
             
                      command = options.get_next_command(ACTIONS)
         
     | 
| 
       877 
804 
     | 
    
         
             
                      if %i[files packages].include?(command)
         
     | 
| 
       878 
805 
     | 
    
         
             
                        default_flag = ' (default)' if options.get_option(:workspace).eql?(:default)
         
     | 
| 
       879 
     | 
    
         
            -
                        aoc_api.context = command
         
     | 
| 
       880 
806 
     | 
    
         
             
                        formatter.display_status("Workspace: #{aoc_api.workspace[:name].to_s.red}#{default_flag}")
         
     | 
| 
       881 
807 
     | 
    
         
             
                        if !aoc_api.private_link.nil?
         
     | 
| 
       882 
808 
     | 
    
         
             
                          folder_name = aoc_api.node_api_from(node_id: aoc_api.home[:node_id]).read("files/#{aoc_api.home[:file_id]}")['name']
         
     | 
| 
         @@ -908,7 +834,6 @@ module Aspera 
     | 
|
| 
       908 
834 
     | 
    
         
             
                          when :list
         
     | 
| 
       909 
835 
     | 
    
         
             
                            return result_list('workspaces', fields: %w[id name])
         
     | 
| 
       910 
836 
     | 
    
         
             
                          when :current
         
     | 
| 
       911 
     | 
    
         
            -
                            aoc_api.context = :files
         
     | 
| 
       912 
837 
     | 
    
         
             
                            return Main.result_single_object(aoc_api.workspace)
         
     | 
| 
       913 
838 
     | 
    
         
             
                          end
         
     | 
| 
       914 
839 
     | 
    
         
             
                        when :profile
         
     | 
| 
         @@ -1119,9 +1044,9 @@ module Aspera 
     | 
|
| 
       1119 
1044 
     | 
    
         
             
                        when :instances
         
     | 
| 
       1120 
1045 
     | 
    
         
             
                          return entity_execute(api: aoc_api, entity: 'workflow_instances')
         
     | 
| 
       1121 
1046 
     | 
    
         
             
                        when :workflows
         
     | 
| 
       1122 
     | 
    
         
            -
                          wf_command = options.get_next_command(%i[action launch].concat( 
     | 
| 
      
 1047 
     | 
    
         
            +
                          wf_command = options.get_next_command(%i[action launch].concat(ALL_OPS))
         
     | 
| 
       1123 
1048 
     | 
    
         
             
                          case wf_command
         
     | 
| 
       1124 
     | 
    
         
            -
                          when * 
     | 
| 
      
 1049 
     | 
    
         
            +
                          when *ALL_OPS
         
     | 
| 
       1125 
1050 
     | 
    
         
             
                            return entity_execute(
         
     | 
| 
       1126 
1051 
     | 
    
         
             
                              api: automation_api,
         
     | 
| 
       1127 
1052 
     | 
    
         
             
                              entity: 'workflows',
         
     | 
| 
         @@ -1152,7 +1077,6 @@ module Aspera 
     | 
|
| 
       1152 
1077 
     | 
    
         
             
                        uri = URI.parse(parameters.delete(:url){WebServerSimple::DEFAULT_URL})
         
     | 
| 
       1153 
1078 
     | 
    
         
             
                        server = WebServerSimple.new(uri, **parameters.slice(*WebServerSimple::PARAMS))
         
     | 
| 
       1154 
1079 
     | 
    
         
             
                        Aspera.assert(parameters.except(*WebServerSimple::PARAMS).empty?)
         
     | 
| 
       1155 
     | 
    
         
            -
                        aoc_api.context = :files
         
     | 
| 
       1156 
1080 
     | 
    
         
             
                        server.mount(uri.path, Faspex4GWServlet, aoc_api, aoc_api.workspace[:id])
         
     | 
| 
       1157 
1081 
     | 
    
         
             
                        server.start
         
     | 
| 
       1158 
1082 
     | 
    
         
             
                        return Main.result_status('Gateway terminated')
         
     | 
| 
         @@ -2,6 +2,7 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            # cspell:ignore trustpolicy
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
      
 5 
     | 
    
         
            +
            require 'aspera/cli/plugins/base'
         
     | 
| 
       5 
6 
     | 
    
         
             
            require 'aspera/cli/plugins/node'
         
     | 
| 
       6 
7 
     | 
    
         
             
            require 'aspera/api/ats'
         
     | 
| 
       7 
8 
     | 
    
         
             
            require 'aspera/api/aoc'
         
     | 
| 
         @@ -13,7 +14,7 @@ module Aspera 
     | 
|
| 
       13 
14 
     | 
    
         
             
                module Plugins
         
     | 
| 
       14 
15 
     | 
    
         
             
                  # Access Aspera Transfer Service
         
     | 
| 
       15 
16 
     | 
    
         
             
                  # https://developer.ibm.com/aspera/docs/ats-api-reference/creating-ats-api-keys/
         
     | 
| 
       16 
     | 
    
         
            -
                  class Ats <  
     | 
| 
      
 17 
     | 
    
         
            +
                  class Ats < Base
         
     | 
| 
       17 
18 
     | 
    
         
             
                    # columns for list of cloud providers
         
     | 
| 
       18 
19 
     | 
    
         
             
                    CLOUD_TABLE = %w[id name].freeze
         
     | 
| 
       19 
20 
     | 
    
         
             
                    private_constant :CLOUD_TABLE
         
     | 
| 
         @@ -25,7 +26,6 @@ module Aspera 
     | 
|
| 
       25 
26 
     | 
    
         
             
                      options.declare(:instance, 'ATS instance in ibm cloud')
         
     | 
| 
       26 
27 
     | 
    
         
             
                      options.declare(:ats_key, 'ATS key identifier (ats_xxx)')
         
     | 
| 
       27 
28 
     | 
    
         
             
                      options.declare(:ats_secret, 'ATS key secret')
         
     | 
| 
       28 
     | 
    
         
            -
                      options.declare(:params, 'Parameters access key creation (@json:)')
         
     | 
| 
       29 
29 
     | 
    
         
             
                      options.declare(:cloud, 'Cloud provider')
         
     | 
| 
       30 
30 
     | 
    
         
             
                      options.declare(:region, 'Cloud region')
         
     | 
| 
       31 
31 
     | 
    
         
             
                      options.parse_options!
         
     | 
| 
         @@ -59,7 +59,7 @@ module Aspera 
     | 
|
| 
       59 
59 
     | 
    
         
             
                      access_key_id = instance_identifier unless %i[create list].include?(command)
         
     | 
| 
       60 
60 
     | 
    
         
             
                      case command
         
     | 
| 
       61 
61 
     | 
    
         
             
                      when :create
         
     | 
| 
       62 
     | 
    
         
            -
                        params =  
     | 
| 
      
 62 
     | 
    
         
            +
                        params = value_create_modify(command: command, default: {})
         
     | 
| 
       63 
63 
     | 
    
         
             
                        server_data = nil
         
     | 
| 
       64 
64 
     | 
    
         
             
                        # if transfer_server_id not provided, get it from command line options
         
     | 
| 
       65 
65 
     | 
    
         
             
                        if !params.key?('transfer_server_id')
         
     | 
| 
         @@ -92,7 +92,7 @@ module Aspera 
     | 
|
| 
       92 
92 
     | 
    
         
             
                        return Main.result_single_object(res)
         
     | 
| 
       93 
93 
     | 
    
         
             
                        # TODO : action : modify, with "PUT"
         
     | 
| 
       94 
94 
     | 
    
         
             
                      when :list
         
     | 
| 
       95 
     | 
    
         
            -
                        params =  
     | 
| 
      
 95 
     | 
    
         
            +
                        params = query_read_delete(default: {'offset' => 0, 'max_results' => 1000})
         
     | 
| 
       96 
96 
     | 
    
         
             
                        res = ats_api_pub_v1.read('access_keys', params)
         
     | 
| 
       97 
97 
     | 
    
         
             
                        return Main.result_object_list(res['data'], fields: ['name', 'id', 'created.at', 'modified.at'])
         
     | 
| 
       98 
98 
     | 
    
         
             
                      when :show
         
     |