aspera-cli 4.24.1 → 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 +15 -2
- data/README.md +745 -436
- 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 +55 -70
- 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 +249 -220
- 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 +65 -53
- 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 +10 -7
- 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 +37 -9
- 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 +16 -16
- 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 +0 -0
- 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
|