aspera-cli 4.25.4 → 4.25.5
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 +22 -6
- data/CONTRIBUTING.md +31 -22
- data/README.md +9 -7
- data/lib/aspera/agent/direct.rb +10 -8
- data/lib/aspera/agent/factory.rb +3 -3
- data/lib/aspera/agent/node.rb +1 -1
- data/lib/aspera/api/alee.rb +1 -0
- data/lib/aspera/api/aoc.rb +10 -6
- data/lib/aspera/api/ats.rb +1 -1
- data/lib/aspera/api/cos_node.rb +1 -0
- data/lib/aspera/api/faspex.rb +17 -19
- data/lib/aspera/api/httpgw.rb +19 -3
- data/lib/aspera/api/node.rb +43 -2
- data/lib/aspera/ascp/installation.rb +9 -10
- data/lib/aspera/cli/error.rb +8 -0
- data/lib/aspera/cli/info.rb +2 -1
- data/lib/aspera/cli/main.rb +30 -12
- data/lib/aspera/cli/manager.rb +31 -28
- data/lib/aspera/cli/plugins/aoc.rb +2 -2
- data/lib/aspera/cli/plugins/base.rb +1 -88
- data/lib/aspera/cli/plugins/faspex.rb +6 -6
- data/lib/aspera/cli/plugins/faspex5.rb +41 -53
- data/lib/aspera/cli/plugins/node.rb +26 -68
- data/lib/aspera/cli/plugins/shares.rb +4 -2
- data/lib/aspera/cli/transfer_agent.rb +3 -0
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/dot_container.rb +10 -10
- data/lib/aspera/log.rb +1 -1
- data/lib/aspera/markdown.rb +1 -1
- data/lib/aspera/persistency_folder.rb +1 -1
- data/lib/aspera/rest.rb +8 -36
- data/lib/aspera/rest_list.rb +121 -0
- data/lib/aspera/sync/operations.rb +1 -1
- data/lib/aspera/transfer/parameters.rb +8 -8
- data/lib/aspera/yaml.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +4 -3
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a886cb3a02f285c84728b216f1cd906b8440db041a8240ed09ed1969d81ec6c3
|
|
4
|
+
data.tar.gz: a05a7d9fc94a5d748c52d659426a18cf567a9e303231c86d1ec2312abc3465ae
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 87988d7b4252134e772c7c5420e59471cfb89355627cb3bf49fe6f5cf19382644856dfee3494adb3db2a879fc42b77f5754f8fee995eae8ca45229fc68ccd769
|
|
7
|
+
data.tar.gz: ace70306ca85a12b17d12dcf146f280d313dcbef491576c265a5a20f70199d1c03ef3834cc62de30b20949f2cfdea39821b09b232c8bd826709f5622c7f631c3
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
<!-- markdownlint-configure-file { "no-duplicate-heading": { "siblings_only": true } } -->
|
|
4
4
|
|
|
5
|
+
## 4.25.5
|
|
6
|
+
|
|
7
|
+
Released: 2026-03-25
|
|
8
|
+
|
|
9
|
+
### New Features
|
|
10
|
+
|
|
11
|
+
* `faspex5`: When sending a package, recipients specified in fields `private_recipients`, `notified_on_upload`, `notified_on_download` and `notified_on_receipt` are now also expanded like field `recipients`.
|
|
12
|
+
|
|
13
|
+
### Issues Fixed
|
|
14
|
+
|
|
15
|
+
* `config`: Fixed `preset update` with dot-path options.
|
|
16
|
+
* `sync`: #251 in `admin` command: Fixed database path on Windows: Use `~private-asp` instead of `.private-asp`.
|
|
17
|
+
* `httpgw`: #252 HTTPGW transfer showed success even in case of error code `403`. Now raises error with message.
|
|
18
|
+
|
|
19
|
+
### Breaking Changes
|
|
20
|
+
|
|
5
21
|
## 4.25.4
|
|
6
22
|
|
|
7
23
|
Released: 2026-03-04
|
|
@@ -301,7 +317,7 @@ Released: 2025-01-21
|
|
|
301
317
|
|
|
302
318
|
* Internal: Basic REST calls now return data directly. (no more `data` key). For advanced calls, use `call`.
|
|
303
319
|
* Internal: Transfer SDK download is now a 2-step procedure: First get the YAML file from GitHub with URLs for the various platforms and versions, and then download the archive from the official IBM repository.
|
|
304
|
-
**global**: Option `format=multi` is replaced with option `multi_table=yes`.
|
|
320
|
+
* **global**: Option `format=multi` is replaced with option `multi_table=yes`.
|
|
305
321
|
* `faspex5`: Removed deprecated option `value` replaced with positional parameter.
|
|
306
322
|
|
|
307
323
|
## 4.19.0
|
|
@@ -1065,7 +1081,7 @@ Released: 2021-02-03
|
|
|
1065
1081
|
|
|
1066
1082
|
### New Features
|
|
1067
1083
|
|
|
1068
|
-
* The option `value` of command `find
|
|
1084
|
+
* The option `value` of command `find` to filter on name is mandatory.
|
|
1069
1085
|
* `find` now also reports all types (file, folder, link).
|
|
1070
1086
|
* `find` now is able to report all fields (type, size, etc...).
|
|
1071
1087
|
|
|
@@ -1095,7 +1111,7 @@ Released: 2021-02-03
|
|
|
1095
1111
|
### New Features
|
|
1096
1112
|
|
|
1097
1113
|
* Improved wizard (prepare for AoC global client id).
|
|
1098
|
-
* Preview generator: Added option :
|
|
1114
|
+
* Preview generator: Added option : `skip_format` with values `png`, `mp4`.
|
|
1099
1115
|
* Removed outdated pictures from this doc.
|
|
1100
1116
|
|
|
1101
1117
|
## 0.9.19
|
|
@@ -1163,7 +1179,7 @@ Released: 2021-02-03
|
|
|
1163
1179
|
|
|
1164
1180
|
### New Features
|
|
1165
1181
|
|
|
1166
|
-
* `faspex`: Use option `once_only` set to `yes` to enable cargo like function. id=NEW deprecated.
|
|
1182
|
+
* `faspex`: Use option `once_only` set to `yes` to enable cargo like function. `id=NEW` deprecated.
|
|
1167
1183
|
* `aoc`: Share to share transfer with command `transfer`.
|
|
1168
1184
|
|
|
1169
1185
|
## 0.9.7
|
|
@@ -1172,8 +1188,8 @@ Released: 2021-02-03
|
|
|
1172
1188
|
|
|
1173
1189
|
* Homogeneous transfer spec for `node` and [`direct`](README.md#agt_direct) transfer agents.
|
|
1174
1190
|
* Preview persistency goes to unique file by default.
|
|
1175
|
-
* Catch mxf extension in preview as video.
|
|
1176
|
-
* Faspex: Possibility to download all packages by specifying id=ALL
|
|
1191
|
+
* Catch `mxf` extension in preview as video.
|
|
1192
|
+
* Faspex: Possibility to download all packages by specifying `id=ALL`.
|
|
1177
1193
|
* Faspex: To come: Cargo-like function to download only new packages with id=NEW.
|
|
1178
1194
|
|
|
1179
1195
|
## 0.9.6
|
data/CONTRIBUTING.md
CHANGED
|
@@ -12,7 +12,7 @@ To help us diagnose and resolve the issue efficiently, please include the follow
|
|
|
12
12
|
|
|
13
13
|
- The `ascli` version you are using:
|
|
14
14
|
|
|
15
|
-
```
|
|
15
|
+
```shell
|
|
16
16
|
ascli -v
|
|
17
17
|
```
|
|
18
18
|
|
|
@@ -20,7 +20,7 @@ To help us diagnose and resolve the issue efficiently, please include the follow
|
|
|
20
20
|
|
|
21
21
|
- **Your Ruby environment details**:
|
|
22
22
|
|
|
23
|
-
```
|
|
23
|
+
```shell
|
|
24
24
|
ruby -v
|
|
25
25
|
```
|
|
26
26
|
|
|
@@ -32,7 +32,7 @@ We welcome contributions to improve the `aspera-cli` project!
|
|
|
32
32
|
|
|
33
33
|
Clone the repository to initialize the development environment:
|
|
34
34
|
|
|
35
|
-
```
|
|
35
|
+
```shell
|
|
36
36
|
git clone https://github.com/IBM/aspera-cli.git
|
|
37
37
|
cd aspera-cli
|
|
38
38
|
bundle install
|
|
@@ -91,7 +91,7 @@ You can manage your Ruby installation using your preferred tool (e.g., `rbenv`,
|
|
|
91
91
|
|
|
92
92
|
To start with a clean state and remove all installed gems:
|
|
93
93
|
|
|
94
|
-
```
|
|
94
|
+
```shell
|
|
95
95
|
bundle exec rake tools:clean_gems
|
|
96
96
|
```
|
|
97
97
|
|
|
@@ -109,9 +109,8 @@ The following environment variables and macros control specific build behaviors:
|
|
|
109
109
|
| Environment variable | Contents | Description |
|
|
110
110
|
|-----------------------------|------------| -------------------------------------------------------------|
|
|
111
111
|
| `ASPERA_CLI_TEST_CONF_URL` | URL | URL for the configuration file containing secrets for tests. |
|
|
112
|
-
| `
|
|
113
|
-
| `
|
|
114
|
-
| `LOG_LEVEL` | debug, ... | Sets the logging verbosity for `rake` tasks. |
|
|
112
|
+
| `LOG_SECRETS` | `yes`/`no` | Toggles the logging of secrets in `rake` tasks. |
|
|
113
|
+
| `LOG_LEVEL` | `debug`, ... | Sets the logging verbosity for `rake` tasks. |
|
|
115
114
|
| `ENABLE_COVERAGE` | set/unset | Enables test coverage analysis when defined. |
|
|
116
115
|
| `SIGNING_KEY` | File path | Path to the signing key used for building the gem file. |
|
|
117
116
|
| `SIGNING_KEY_PEM` | PEM Value | The PEM content of the signing key. |
|
|
@@ -121,11 +120,11 @@ These values can be set as standard environment variables or passed directly to
|
|
|
121
120
|
Setting `SIGNING_KEY_PEM` automatically generates a file at `$HOME/.gem/signing_key.pem` and sets the `SIGNING_KEY` variable accordingly.
|
|
122
121
|
|
|
123
122
|
> [!NOTE]
|
|
124
|
-
> `
|
|
123
|
+
> `ASPERA_CLI_TEST_CONF_URL` is typically defined in your shell profile for development, while others are usually for ad-hoc command-line use.
|
|
125
124
|
|
|
126
125
|
To run the CLI directly from your source directory, add the following to your shell profile (adjust the path as necessary):
|
|
127
126
|
|
|
128
|
-
```
|
|
127
|
+
```shell
|
|
129
128
|
dev_ascli=$HOME/github/aspera-cli
|
|
130
129
|
export PATH=$dev_ascli/bin:$PATH
|
|
131
130
|
export RUBYLIB=$dev_ascli/lib:$RUBYLIB
|
|
@@ -140,24 +139,28 @@ Installation instructions can be found at [IBM Plex](https://www.ibm.com/plex/).
|
|
|
140
139
|
|
|
141
140
|
On macOS, install `lualatex` and required packages via Homebrew:
|
|
142
141
|
|
|
143
|
-
```
|
|
142
|
+
```shell
|
|
144
143
|
brew install texlive
|
|
145
144
|
```
|
|
146
145
|
|
|
147
146
|
If using an alternative installation method, ensure the following packages are present:
|
|
148
147
|
|
|
149
|
-
```
|
|
148
|
+
```shell
|
|
150
149
|
tlmgr update --self
|
|
151
150
|
tlmgr install fvextra selnolig lualatex-math
|
|
152
151
|
```
|
|
153
152
|
|
|
154
|
-
-
|
|
153
|
+
- Validate URLs during generation with:
|
|
155
154
|
|
|
156
|
-
|
|
155
|
+
```shell
|
|
156
|
+
rake doc:check_links
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
- Debug the generation process: `ASPERA_CLI_DOC_DEBUG=debug`.
|
|
157
160
|
|
|
158
|
-
-
|
|
161
|
+
- Build the documentation:
|
|
159
162
|
|
|
160
|
-
```
|
|
163
|
+
```shell
|
|
161
164
|
rake doc:build
|
|
162
165
|
```
|
|
163
166
|
|
|
@@ -169,14 +172,14 @@ Detailed testing information can be found in <tests/README.md>.
|
|
|
169
172
|
|
|
170
173
|
To build an unsigned gem:
|
|
171
174
|
|
|
172
|
-
```
|
|
175
|
+
```shell
|
|
173
176
|
bundle install
|
|
174
177
|
bundle exec rake unsigned
|
|
175
178
|
```
|
|
176
179
|
|
|
177
180
|
To exclude optional gems from the installation:
|
|
178
181
|
|
|
179
|
-
```
|
|
182
|
+
```shell
|
|
180
183
|
bundle config set without optional
|
|
181
184
|
```
|
|
182
185
|
|
|
@@ -185,7 +188,7 @@ bundle config set without optional
|
|
|
185
188
|
Generating a signed gem requires a **private key**, specified via the `SIGNING_KEY` environment variable.
|
|
186
189
|
The gem is signed using the public certificate in `certs` and the **private key**.
|
|
187
190
|
|
|
188
|
-
```
|
|
191
|
+
```shell
|
|
189
192
|
bundle exec rake SIGNING_KEY=/path/to/vault/gem-private_key.pem
|
|
190
193
|
```
|
|
191
194
|
|
|
@@ -195,7 +198,7 @@ For more details, see <certs/README.md>.
|
|
|
195
198
|
|
|
196
199
|
To update the stubs:
|
|
197
200
|
|
|
198
|
-
```
|
|
201
|
+
```shell
|
|
199
202
|
bundle exec rake tools:grpc
|
|
200
203
|
```
|
|
201
204
|
|
|
@@ -211,7 +214,7 @@ Refer to the [Executable build guide](build/binary/README.md).
|
|
|
211
214
|
|
|
212
215
|
To list related `rake` tasks:
|
|
213
216
|
|
|
214
|
-
```
|
|
217
|
+
```shell
|
|
215
218
|
bundle exec rake -T ^binary:
|
|
216
219
|
```
|
|
217
220
|
|
|
@@ -234,17 +237,23 @@ Before a new release, ensure the following:
|
|
|
234
237
|
|
|
235
238
|
- **Pass all tests**:
|
|
236
239
|
|
|
237
|
-
```
|
|
240
|
+
```shell
|
|
238
241
|
bundle exec rake test:run
|
|
239
242
|
```
|
|
240
243
|
|
|
241
244
|
- **Verify container builds** (using the local gem):
|
|
242
245
|
|
|
243
|
-
```
|
|
246
|
+
```shell
|
|
244
247
|
bundle exec rake container:build'[local]'
|
|
245
248
|
bundle exec rake container:test
|
|
246
249
|
```
|
|
247
250
|
|
|
251
|
+
- **Check documentation links**:
|
|
252
|
+
|
|
253
|
+
```shell
|
|
254
|
+
bundle exec rake doc:check_links
|
|
255
|
+
```
|
|
256
|
+
|
|
248
257
|
### Automated Release Process
|
|
249
258
|
|
|
250
259
|
Releases are managed through the GitHub Actions UI via the **New Release on GitHub** workflow (`.github/workflows/release.yml`).
|
data/README.md
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
[](https://bestpractices.coreinfrastructure.org/projects/5861)
|
|
6
6
|
[](LICENSE)
|
|
7
7
|
|
|
8
|
+

|
|
9
|
+
|
|
8
10
|
**`ascli`** is the command-line interface for IBM Aspera products.
|
|
9
11
|
Use it from the terminal or in scripts to:
|
|
10
12
|
|
|
@@ -18,8 +20,8 @@ Choose what best suits you:
|
|
|
18
20
|
|
|
19
21
|
| Resource | Link |
|
|
20
22
|
| -------- | ---- |
|
|
21
|
-
| **Online manual** | [docs/README.md](docs/README.md) |
|
|
22
|
-
| **PDF manual** | In [
|
|
23
|
+
| **Online manual** | [GitHub docs/README.md](https://github.com/IBM/aspera-cli/blob/main/docs/README.md) |
|
|
24
|
+
| **PDF manual** | In [GitHub Releases](https://github.com/IBM/aspera-cli/releases) |
|
|
23
25
|
| **RubyGems** | [rubygems.org/gems/aspera-cli](https://rubygems.org/gems/aspera-cli) |
|
|
24
26
|
| **RubyDoc** | [rubydoc.info/gems/aspera-cli](https://www.rubydoc.info/gems/aspera-cli) |
|
|
25
27
|
| **Docsify** | [online](https://docsify-this.net/?basePath=https://raw.githubusercontent.com/IBM/aspera-cli/main/docs&homepage=README.md&sidebar=true&browser-tab-title=Aspera%20CLI%20Manual&hide-credits=true&maxLevel=4&externalLinkTarget=_blank&image-captions=true&dark-mode=auto) |
|
|
@@ -34,7 +36,7 @@ ascli config transferd install
|
|
|
34
36
|
```
|
|
35
37
|
|
|
36
38
|
The second command installs the **FASP** transfer engine (`ascp`).
|
|
37
|
-
For other install methods (single executable, Docker, Chocolatey, Homebrew), see the [user manual](docs/README.md#installation).
|
|
39
|
+
For other install methods (single executable, Docker, Chocolatey, Homebrew), see the [user manual](https://github.com/IBM/aspera-cli/blob/main/docs/README.md#installation).
|
|
38
40
|
|
|
39
41
|
**Quick check:**
|
|
40
42
|
|
|
@@ -44,13 +46,13 @@ ascli -v
|
|
|
44
46
|
|
|
45
47
|
## Contributing
|
|
46
48
|
|
|
47
|
-
- **Bugs & features:** [BUGS.md](BUGS.md)
|
|
48
|
-
- **How to contribute:** [CONTRIBUTING.md](CONTRIBUTING.md)
|
|
49
|
-
- **Release notes:** [CHANGELOG.md](CHANGELOG.md)
|
|
49
|
+
- **Bugs & features:** [BUGS.md](https://github.com/IBM/aspera-cli/blob/main/BUGS.md)
|
|
50
|
+
- **How to contribute:** [CONTRIBUTING.md](https://github.com/IBM/aspera-cli/blob/main/CONTRIBUTING.md)
|
|
51
|
+
- **Release notes:** [CHANGELOG.md](https://github.com/IBM/aspera-cli/blob/main/CHANGELOG.md)
|
|
50
52
|
|
|
51
53
|
Commands map to Aspera REST APIs; see the manual for options.
|
|
52
54
|
For debugging, use `--log-level=debug`.
|
|
53
55
|
|
|
54
56
|
## License
|
|
55
57
|
|
|
56
|
-
[Apache-2.0](LICENSE)
|
|
58
|
+
[Apache-2.0](https://github.com/IBM/aspera-cli/blob/main/LICENSE)
|
data/lib/aspera/agent/direct.rb
CHANGED
|
@@ -25,25 +25,27 @@ module Aspera
|
|
|
25
25
|
private_constant :LISTEN_LOCAL_ADDRESS, :SELECT_AVAILABLE_PORT
|
|
26
26
|
|
|
27
27
|
# Options: same as values in option `transfer_info`
|
|
28
|
-
#
|
|
29
|
-
#
|
|
30
|
-
# @param
|
|
31
|
-
# @param
|
|
32
|
-
# @param
|
|
33
|
-
# @param client_ssh_key [String] (
|
|
34
|
-
# @param
|
|
28
|
+
# (Args) : Options that influence `ascp` arguments.
|
|
29
|
+
#
|
|
30
|
+
# @param ascp_args [Array] (Args) Optional Additional arguments to ascp
|
|
31
|
+
# @param wss [Boolean] (Args) `true`: if both SSH and wss in ts: prefer wss
|
|
32
|
+
# @param quiet [Boolean] (Args) By default no native `ascp` progress bar
|
|
33
|
+
# @param client_ssh_key [String] (Args) Client SSH key option (from CLIENT_SSH_KEY_OPTIONS)
|
|
34
|
+
# @param trusted_certs [Array<String>] (Args) (WSS) Optional list of files with trusted certificates (stores)
|
|
35
|
+
# @param check_ignore_cb [Proc] (Args) (WSS) Callback with host,port to check if WSS connection shall ignore certificate validity
|
|
35
36
|
# @param spawn_timeout_sec [Integer] Timeout for ascp spawn
|
|
36
37
|
# @param spawn_delay_sec [Integer] Optional delay to start between sessions
|
|
37
38
|
# @param multi_incr_udp [Boolean] Optional `true`: increment UDP port for each session
|
|
38
39
|
# @param resume [Hash] Optional Resume policy
|
|
40
|
+
# @param monitor [Boolean] Set to `false` to eliminate management port
|
|
39
41
|
# @param management_cb [Proc] callback for management events
|
|
40
42
|
# @param base_options [Hash] other options for base class
|
|
41
43
|
def initialize(
|
|
42
44
|
ascp_args: nil,
|
|
43
45
|
wss: true,
|
|
44
46
|
quiet: true,
|
|
45
|
-
trusted_certs: nil,
|
|
46
47
|
client_ssh_key: nil,
|
|
48
|
+
trusted_certs: nil,
|
|
47
49
|
check_ignore_cb: nil,
|
|
48
50
|
spawn_timeout_sec: 2,
|
|
49
51
|
spawn_delay_sec: 2,
|
data/lib/aspera/agent/factory.rb
CHANGED
|
@@ -22,11 +22,11 @@ module Aspera
|
|
|
22
22
|
Dir.children(File.dirname(File.expand_path(__FILE__)))
|
|
23
23
|
.select{ |file| file.end_with?(Environment::RB_EXT)}
|
|
24
24
|
.map{ |file| File.basename(file, Environment::RB_EXT).to_sym}
|
|
25
|
-
.reject{ |item| IGNORED_ITEMS.include?(item)}.
|
|
26
|
-
|
|
25
|
+
.reject{ |item| IGNORED_ITEMS.include?(item)}.to_h do |agent_sym|
|
|
26
|
+
[agent_sym, {
|
|
27
27
|
long: agent_sym.to_s.capitalize,
|
|
28
28
|
short: agent_sym.eql?(:direct) ? :a : agent_sym.to_s[0].to_sym
|
|
29
|
-
}.freeze
|
|
29
|
+
}.freeze]
|
|
30
30
|
end.freeze
|
|
31
31
|
private_constant :IGNORED_ITEMS
|
|
32
32
|
end
|
data/lib/aspera/agent/node.rb
CHANGED
|
@@ -59,7 +59,7 @@ module Aspera
|
|
|
59
59
|
ts_tags = transfer_spec['tags']
|
|
60
60
|
ts_tags[Transfer::Spec::TAG_RESERVED]['xfer_retry'] ||= 150 if ts_tags.is_a?(Hash) && ts_tags[Transfer::Spec::TAG_RESERVED].is_a?(Hash)
|
|
61
61
|
# Optimization in case of sending to the same node
|
|
62
|
-
# TODO: probably remove this, as /etc/hosts shall be used for that
|
|
62
|
+
# TODO: probably remove this, as /etc/hosts shall be used for that on server side.
|
|
63
63
|
transfer_spec['remote_host'] = '127.0.0.1' if !transfer_spec['wss_enabled'] && transfer_spec['remote_host'].eql?(URI.parse(node_api_.base_url).host)
|
|
64
64
|
resp = node_api_.create('ops/transfers', transfer_spec)
|
|
65
65
|
@transfer_id = resp['id']
|
data/lib/aspera/api/alee.rb
CHANGED
data/lib/aspera/api/aoc.rb
CHANGED
|
@@ -7,11 +7,15 @@ require 'aspera/hash_ext'
|
|
|
7
7
|
require 'aspera/data_repository'
|
|
8
8
|
require 'aspera/transfer/spec'
|
|
9
9
|
require 'aspera/api/node'
|
|
10
|
+
require 'aspera/rest_list'
|
|
10
11
|
require 'base64'
|
|
11
12
|
|
|
12
13
|
module Aspera
|
|
13
14
|
module Api
|
|
15
|
+
# Aspera on Cloud API client
|
|
14
16
|
class AoC < Rest
|
|
17
|
+
include RestList
|
|
18
|
+
|
|
15
19
|
PRODUCT_NAME = 'Aspera on Cloud'
|
|
16
20
|
# use default workspace if it is set, else none
|
|
17
21
|
DEFAULT_WORKSPACE = ''
|
|
@@ -144,7 +148,7 @@ module Aspera
|
|
|
144
148
|
|
|
145
149
|
# Call `block` with same query using paging and response information.
|
|
146
150
|
# Block must return a 2 element `Array` with data and http response
|
|
147
|
-
# @param query [Hash]
|
|
151
|
+
# @param query [Hash] Additional query parameters
|
|
148
152
|
# @return [Hash] Items and total number of items
|
|
149
153
|
# @option return [Array<Hash>] :items The list of items
|
|
150
154
|
# @option return [Integer] :total The total number of items
|
|
@@ -153,8 +157,8 @@ module Aspera
|
|
|
153
157
|
Aspera.assert(block_given?)
|
|
154
158
|
# set default large page if user does not specify own parameters. AoC Caps to 1000 anyway
|
|
155
159
|
query['per_page'] = 1000 unless query.key?('per_page')
|
|
156
|
-
max_items = query.delete(
|
|
157
|
-
max_pages = query.delete(
|
|
160
|
+
max_items = query.delete(RestList::MAX_ITEMS)
|
|
161
|
+
max_pages = query.delete(RestList::MAX_PAGES)
|
|
158
162
|
item_list = []
|
|
159
163
|
total_count = nil
|
|
160
164
|
current_page = query['page']
|
|
@@ -209,7 +213,7 @@ module Aspera
|
|
|
209
213
|
when 'upload' then %w[mkdir write]
|
|
210
214
|
when Array
|
|
211
215
|
Aspera.assert_array_all(levels, String){'access_levels'}
|
|
212
|
-
levels.each{ |level| Aspera.
|
|
216
|
+
levels.each{ |level| Aspera.assert_values(level, Node::ACCESS_LEVELS){'access_level'}}
|
|
213
217
|
levels
|
|
214
218
|
else Aspera.error_unexpected_value(levels){"access_levels must be a list of #{Node::ACCESS_LEVELS.join(', ')} or one of edit, preview, download, upload"}
|
|
215
219
|
end
|
|
@@ -492,7 +496,7 @@ module Aspera
|
|
|
492
496
|
# in that case, the name is resolved and replaced with {type: , id: }
|
|
493
497
|
# @param package_data [Hash] The whole package creation payload
|
|
494
498
|
# @param rcpt_lst_field [String] The field in structure, i.e. recipients or bcc_recipients
|
|
495
|
-
# @param new_user_option [Hash]
|
|
499
|
+
# @param new_user_option [Hash] Additional fields for contact creation
|
|
496
500
|
# @return nil, `package_data` is modified
|
|
497
501
|
def resolve_package_recipients(package_data, rcpt_lst_field, new_user_option)
|
|
498
502
|
return unless package_data.key?(rcpt_lst_field)
|
|
@@ -510,7 +514,7 @@ module Aspera
|
|
|
510
514
|
# email: user, else dropbox
|
|
511
515
|
entity_type = short_recipient_info.include?('@') ? 'contacts' : 'dropboxes'
|
|
512
516
|
begin
|
|
513
|
-
full_recipient_info = lookup_by_name(entity_type, short_recipient_info, query: {'
|
|
517
|
+
full_recipient_info = lookup_by_name(entity_type, short_recipient_info, query: {'workspace_id' => ws_id})
|
|
514
518
|
rescue EntityNotFound
|
|
515
519
|
# dropboxes cannot be created on the fly
|
|
516
520
|
Aspera.assert_values(entity_type, 'contacts', type: Error){"No such shared inbox in workspace #{ws_id}"}
|
data/lib/aspera/api/ats.rb
CHANGED
data/lib/aspera/api/cos_node.rb
CHANGED
data/lib/aspera/api/faspex.rb
CHANGED
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
require 'aspera/rest'
|
|
4
4
|
require 'aspera/oauth/base'
|
|
5
|
+
require 'aspera/rest_list'
|
|
5
6
|
require 'digest'
|
|
6
7
|
|
|
7
8
|
module Aspera
|
|
8
|
-
#
|
|
9
|
+
# OAuth for Faspex public link
|
|
9
10
|
class FaspexPubLink < OAuth::Base
|
|
10
11
|
class << self
|
|
11
12
|
attr_accessor :additional_info
|
|
@@ -55,14 +56,14 @@ module Aspera
|
|
|
55
56
|
end
|
|
56
57
|
OAuth::Factory.instance.register_token_creator(FaspexPubLink)
|
|
57
58
|
module Api
|
|
59
|
+
# Aspera Faspex 5 API Client
|
|
58
60
|
class Faspex < Aspera::Rest
|
|
61
|
+
include RestList
|
|
62
|
+
|
|
59
63
|
# endpoint for authentication API
|
|
60
64
|
PATH_AUTH = 'auth'
|
|
61
65
|
PATH_API_V5 = 'api/v5'
|
|
62
66
|
PATH_HEALTH = 'configuration/ping'
|
|
63
|
-
private_constant :PATH_AUTH,
|
|
64
|
-
:PATH_API_V5,
|
|
65
|
-
:PATH_HEALTH
|
|
66
67
|
RECIPIENT_TYPES = %w[user workgroup external_user distribution_list shared_inbox].freeze
|
|
67
68
|
PACKAGE_TERMINATED = %w[completed failed].freeze
|
|
68
69
|
# list of supported mailbox types (to list packages)
|
|
@@ -148,6 +149,7 @@ module Aspera
|
|
|
148
149
|
def initialize(
|
|
149
150
|
url:,
|
|
150
151
|
auth:,
|
|
152
|
+
root: PATH_API_V5,
|
|
151
153
|
password: nil,
|
|
152
154
|
client_id: nil,
|
|
153
155
|
client_secret: nil,
|
|
@@ -161,23 +163,23 @@ module Aspera
|
|
|
161
163
|
super(**
|
|
162
164
|
case auth
|
|
163
165
|
when :public_link
|
|
164
|
-
# Get URL of final redirect of public link
|
|
165
|
-
|
|
166
|
-
Log.dump(:
|
|
167
|
-
#
|
|
168
|
-
encoded_context = Rest.query_to_h(URI.parse(
|
|
166
|
+
# Get URL of final redirect of provided public link
|
|
167
|
+
final_url = Rest.new(base_url: url, redirect_max: 3).call(operation: 'GET', ret: :resp).uri.to_s
|
|
168
|
+
Log.dump(:final_url, final_url, level: :trace1)
|
|
169
|
+
# Get context from query
|
|
170
|
+
encoded_context = Rest.query_to_h(URI.parse(final_url).query)['context']
|
|
169
171
|
raise ParameterError, 'Bad faspex5 public link, missing context in query' if encoded_context.nil?
|
|
170
172
|
# public link information (contains passcode and allowed usage)
|
|
171
173
|
@pub_link_context = JSON.parse(Base64.decode64(encoded_context))
|
|
172
174
|
Log.dump(:pub_link_context, @pub_link_context, level: :trace1)
|
|
173
175
|
# Get the base url, i.e. .../aspera/faspex
|
|
174
|
-
base_url =
|
|
176
|
+
base_url = final_url.gsub(%r{/public/.*}, '').gsub(/\?.*/, '')
|
|
175
177
|
# Get web UI client_id and redirect_uri
|
|
176
178
|
# TODO: change this for something more reliable
|
|
177
179
|
config = JSON.parse(Rest.new(base_url: "#{base_url}/config.js", redirect_max: 3).call(operation: 'GET').sub(/^[^=]+=/, '').gsub(/([a-z_]+):/, '"\1":').delete("\n ").tr("'", '"')).symbolize_keys
|
|
178
|
-
Log.dump(:
|
|
180
|
+
Log.dump(:config_js, config)
|
|
179
181
|
{
|
|
180
|
-
base_url: "#{base_url}/#{
|
|
182
|
+
base_url: "#{base_url}/#{root}",
|
|
181
183
|
auth: {
|
|
182
184
|
type: :oauth2,
|
|
183
185
|
base_url: "#{base_url}/#{PATH_AUTH}",
|
|
@@ -194,7 +196,7 @@ module Aspera
|
|
|
194
196
|
Aspera.assert(password, type: ParameterError){'Missing password'}
|
|
195
197
|
# the password here is the token copied directly from browser in developer mode
|
|
196
198
|
{
|
|
197
|
-
base_url: "#{url}/#{
|
|
199
|
+
base_url: "#{url}/#{root}",
|
|
198
200
|
headers: {'Authorization' => password}
|
|
199
201
|
}
|
|
200
202
|
when :web
|
|
@@ -202,7 +204,7 @@ module Aspera
|
|
|
202
204
|
Aspera.assert(redirect_uri, type: ParameterError){'Missing redirect_uri'}
|
|
203
205
|
# opens a browser and ask user to auth using web
|
|
204
206
|
{
|
|
205
|
-
base_url: "#{url}/#{
|
|
207
|
+
base_url: "#{url}/#{root}",
|
|
206
208
|
auth: {
|
|
207
209
|
type: :oauth2,
|
|
208
210
|
base_url: "#{url}/#{PATH_AUTH}",
|
|
@@ -217,7 +219,7 @@ module Aspera
|
|
|
217
219
|
Aspera.assert(client_id, type: ParameterError){'Missing client_id'}
|
|
218
220
|
Aspera.assert(private_key, type: ParameterError){'Missing private_key'}
|
|
219
221
|
{
|
|
220
|
-
base_url: "#{url}/#{
|
|
222
|
+
base_url: "#{url}/#{root}",
|
|
221
223
|
auth: {
|
|
222
224
|
type: :oauth2,
|
|
223
225
|
base_url: "#{url}/#{PATH_AUTH}",
|
|
@@ -238,10 +240,6 @@ module Aspera
|
|
|
238
240
|
end
|
|
239
241
|
)
|
|
240
242
|
end
|
|
241
|
-
|
|
242
|
-
def auth_api
|
|
243
|
-
Rest.new(**params, base_url: base_url.sub(PATH_API_V5, PATH_AUTH))
|
|
244
|
-
end
|
|
245
243
|
end
|
|
246
244
|
end
|
|
247
245
|
end
|
data/lib/aspera/api/httpgw.rb
CHANGED
|
@@ -4,13 +4,18 @@ require 'aspera/log'
|
|
|
4
4
|
require 'aspera/rest'
|
|
5
5
|
require 'aspera/transfer/faux_file'
|
|
6
6
|
require 'aspera/assert'
|
|
7
|
+
require 'net/protocol'
|
|
7
8
|
require 'securerandom'
|
|
8
9
|
require 'websocket'
|
|
9
10
|
require 'base64'
|
|
10
11
|
require 'json'
|
|
11
12
|
|
|
13
|
+
# throw exception on error, instead of error code
|
|
14
|
+
WebSocket.should_raise = true
|
|
15
|
+
|
|
12
16
|
module Aspera
|
|
13
17
|
module Api
|
|
18
|
+
# Aspera HTTP Gateway API client
|
|
14
19
|
# Start a transfer using Aspera HTTP Gateway, using web socket secure for uploads
|
|
15
20
|
# ref: https://api.ibm.com/explorer/catalog/aspera/product/ibm-aspera/api/http-gateway-api/doc/guides-toc
|
|
16
21
|
# https://developer.ibm.com/apis/catalog?search=%22aspera%20http%22
|
|
@@ -75,6 +80,15 @@ module Aspera
|
|
|
75
80
|
Log.log.trace2{"#{LOG_WS_SEND}counts: #{@shared_info[:count]}"}
|
|
76
81
|
end
|
|
77
82
|
|
|
83
|
+
# Check header ourself and give precise error message, as websocket will only throw error without details
|
|
84
|
+
# @param [String] Response Header
|
|
85
|
+
# @return [String] Response Header
|
|
86
|
+
def validated_ws_response_header(header)
|
|
87
|
+
first_line = header.split("\r\n").first
|
|
88
|
+
raise RestCallError.new({messages: ["Unexpected: #{first_line}", 'Expected: 101 Switching Protocols']}) unless first_line.split(/\s+/, 3)[1].eql?('101')
|
|
89
|
+
header
|
|
90
|
+
end
|
|
91
|
+
|
|
78
92
|
# message processing for read thread
|
|
79
93
|
def process_received_message(message)
|
|
80
94
|
Log.log.debug{"#{LOG_WS_RECV}message: [#{message}] (#{message.class})"}
|
|
@@ -153,8 +167,9 @@ module Aspera
|
|
|
153
167
|
@ws_handshake = ::WebSocket::Handshake::Client.new(url: upload_url, headers: {})
|
|
154
168
|
@ws_io.write(@ws_handshake.to_s)
|
|
155
169
|
sleep(0.1)
|
|
156
|
-
|
|
157
|
-
|
|
170
|
+
# Get whole HTTP response header, Check and process
|
|
171
|
+
# no need to check `finished?` or result of `<<` (true), as we give the whole header at once
|
|
172
|
+
@ws_handshake << validated_ws_response_header(@ws_io.readuntil("\r\n\r\n"))
|
|
158
173
|
Log.log.debug{"#{LOG_WS_SEND}handshake success"}
|
|
159
174
|
# data shared between main thread and read thread
|
|
160
175
|
@shared_info = {
|
|
@@ -232,14 +247,15 @@ module Aspera
|
|
|
232
247
|
# throttling may have skipped last one
|
|
233
248
|
@notify_cb&.call(:transfer, session_id: session_id, info: session_sent_bytes)
|
|
234
249
|
@notify_cb&.call(:session_end, session_id: session_id)
|
|
235
|
-
@notify_cb&.call(:end)
|
|
236
250
|
ws_send(ws_type: :close, data: nil)
|
|
237
251
|
Log.log.debug("Finished upload, waiting for end of #{THR_RECV} thread.")
|
|
238
252
|
@ws_read_thread.join
|
|
239
253
|
Log.log.debug{'Read thread joined'}
|
|
254
|
+
ensure
|
|
240
255
|
# session no more used
|
|
241
256
|
@ws_io = nil
|
|
242
257
|
http_session&.finish
|
|
258
|
+
@notify_cb&.call(:end)
|
|
243
259
|
end
|
|
244
260
|
|
|
245
261
|
def download(transfer_spec)
|