aspera-cli 4.13.0 → 4.15.0
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 +81 -7
- data/CONTRIBUTING.md +22 -6
- data/README.md +2038 -1080
- data/bin/ascli +18 -9
- data/bin/asession +12 -14
- data/examples/dascli +1 -1
- data/examples/proxy.pac +1 -1
- data/examples/rubyc +24 -0
- data/lib/aspera/aoc.rb +219 -159
- data/lib/aspera/ascmd.rb +25 -14
- data/lib/aspera/cli/basic_auth_plugin.rb +12 -9
- data/lib/aspera/cli/error.rb +17 -0
- data/lib/aspera/cli/extended_value.rb +47 -12
- data/lib/aspera/cli/formatter.rb +260 -179
- data/lib/aspera/cli/hints.rb +80 -0
- data/lib/aspera/cli/main.rb +104 -156
- data/lib/aspera/cli/manager.rb +259 -209
- data/lib/aspera/cli/plugin.rb +123 -63
- data/lib/aspera/cli/plugins/alee.rb +2 -3
- data/lib/aspera/cli/plugins/aoc.rb +341 -261
- data/lib/aspera/cli/plugins/ats.rb +22 -21
- data/lib/aspera/cli/plugins/bss.rb +5 -5
- data/lib/aspera/cli/plugins/config.rb +578 -627
- data/lib/aspera/cli/plugins/console.rb +44 -6
- data/lib/aspera/cli/plugins/cos.rb +15 -17
- data/lib/aspera/cli/plugins/faspex.rb +114 -100
- data/lib/aspera/cli/plugins/faspex5.rb +411 -264
- data/lib/aspera/cli/plugins/node.rb +354 -259
- data/lib/aspera/cli/plugins/orchestrator.rb +61 -29
- data/lib/aspera/cli/plugins/preview.rb +82 -90
- data/lib/aspera/cli/plugins/server.rb +79 -32
- data/lib/aspera/cli/plugins/shares.rb +55 -42
- data/lib/aspera/cli/sync_actions.rb +68 -0
- data/lib/aspera/cli/transfer_agent.rb +66 -73
- data/lib/aspera/cli/transfer_progress.rb +74 -0
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/colors.rb +12 -8
- data/lib/aspera/command_line_builder.rb +14 -11
- data/lib/aspera/cos_node.rb +3 -2
- data/lib/aspera/data/6 +0 -0
- data/lib/aspera/environment.rb +24 -9
- data/lib/aspera/fasp/agent_aspera.rb +126 -0
- data/lib/aspera/fasp/agent_base.rb +31 -77
- data/lib/aspera/fasp/agent_connect.rb +25 -21
- data/lib/aspera/fasp/agent_direct.rb +89 -103
- data/lib/aspera/fasp/agent_httpgw.rb +231 -149
- data/lib/aspera/fasp/agent_node.rb +41 -34
- data/lib/aspera/fasp/agent_trsdk.rb +75 -32
- data/lib/aspera/fasp/error_info.rb +4 -2
- data/lib/aspera/fasp/faux_file.rb +52 -0
- data/lib/aspera/fasp/installation.rb +53 -195
- data/lib/aspera/fasp/management.rb +244 -0
- data/lib/aspera/fasp/parameters.rb +71 -37
- data/lib/aspera/fasp/parameters.yaml +76 -8
- data/lib/aspera/fasp/products.rb +162 -0
- data/lib/aspera/fasp/resume_policy.rb +3 -3
- data/lib/aspera/fasp/transfer_spec.rb +7 -6
- data/lib/aspera/fasp/uri.rb +26 -24
- data/lib/aspera/faspex_gw.rb +2 -2
- data/lib/aspera/faspex_postproc.rb +2 -2
- data/lib/aspera/hash_ext.rb +14 -4
- data/lib/aspera/json_rpc.rb +49 -0
- data/lib/aspera/keychain/macos_security.rb +13 -13
- data/lib/aspera/line_logger.rb +23 -0
- data/lib/aspera/log.rb +58 -16
- data/lib/aspera/node.rb +157 -92
- data/lib/aspera/oauth.rb +37 -19
- data/lib/aspera/open_application.rb +4 -4
- data/lib/aspera/persistency_action_once.rb +1 -1
- data/lib/aspera/persistency_folder.rb +2 -2
- data/lib/aspera/preview/file_types.rb +4 -2
- data/lib/aspera/preview/generator.rb +22 -35
- data/lib/aspera/preview/options.rb +2 -0
- data/lib/aspera/preview/terminal.rb +73 -16
- data/lib/aspera/preview/utils.rb +21 -28
- data/lib/aspera/proxy_auto_config.js +2 -2
- data/lib/aspera/rest.rb +136 -68
- data/lib/aspera/rest_call_error.rb +1 -1
- data/lib/aspera/rest_error_analyzer.rb +15 -14
- data/lib/aspera/rest_errors_aspera.rb +37 -34
- data/lib/aspera/secret_hider.rb +18 -15
- data/lib/aspera/ssh.rb +5 -2
- data/lib/aspera/sync.rb +127 -119
- data/lib/aspera/temp_file_manager.rb +10 -3
- data/lib/aspera/web_auth.rb +10 -7
- data/lib/aspera/web_server_simple.rb +9 -4
- data.tar.gz.sig +0 -0
- metadata +34 -17
- metadata.gz.sig +0 -0
- data/docs/test_env.conf +0 -186
- data/lib/aspera/cli/listener/line_dump.rb +0 -19
- data/lib/aspera/cli/listener/logger.rb +0 -22
- data/lib/aspera/cli/listener/progress.rb +0 -50
- data/lib/aspera/cli/listener/progress_multi.rb +0 -84
- data/lib/aspera/cli/plugins/sync.rb +0 -44
- data/lib/aspera/data/7 +0 -0
- data/lib/aspera/fasp/listener.rb +0 -13
@@ -1,9 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# cspell:ignore ascmd zmode zuid zgid fasping
|
3
4
|
require 'aspera/cli/basic_auth_plugin'
|
4
|
-
require 'aspera/cli/
|
5
|
-
require 'aspera/ascmd'
|
5
|
+
require 'aspera/cli/sync_actions'
|
6
6
|
require 'aspera/fasp/transfer_spec'
|
7
|
+
require 'aspera/ascmd'
|
7
8
|
require 'aspera/ssh'
|
8
9
|
require 'aspera/nagios'
|
9
10
|
require 'tempfile'
|
@@ -13,19 +14,12 @@ module Aspera
|
|
13
14
|
module Cli
|
14
15
|
module Plugins
|
15
16
|
# implement basic remote access with FASP/SSH
|
16
|
-
class SyncSpecServer
|
17
|
-
def initialize(transfer_spec)
|
18
|
-
@transfer_spec = transfer_spec
|
19
|
-
end
|
20
|
-
|
21
|
-
def transfer_spec(direction, local_path, remote_path)
|
22
|
-
return @transfer_spec
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
17
|
class Server < Aspera::Cli::BasicAuthPlugin
|
18
|
+
include SyncActions
|
27
19
|
SSH_SCHEME = 'ssh'
|
28
|
-
|
20
|
+
LOCAL_SCHEME = 'local'
|
21
|
+
HTTPS_SCHEME = 'https'
|
22
|
+
URI_SCHEMES = [SSH_SCHEME, LOCAL_SCHEME, HTTPS_SCHEME].freeze
|
29
23
|
ASCMD_ALIASES = {
|
30
24
|
browse: :ls,
|
31
25
|
delete: :rm,
|
@@ -41,36 +35,88 @@ module Aspera
|
|
41
35
|
cmd = cmd.map{|v|%Q("#{v}")}.join(' ') if cmd.is_a?(Array)
|
42
36
|
Log.log.debug{"Executing: #{cmd} with '#{line}'"}
|
43
37
|
stdout_str, stderr_str, status = Open3.capture3(cmd, stdin_data: line, binmode: true)
|
44
|
-
Log.log.debug
|
38
|
+
Log.log.debug{"exec status: #{status} -> #{stderr_str}"}
|
45
39
|
raise "command #{cmd} failed with code #{status.exitstatus} #{stderr_str}" unless status.success?
|
46
40
|
return stdout_str
|
47
41
|
end
|
48
42
|
end
|
49
43
|
|
44
|
+
class << self
|
45
|
+
def application_name
|
46
|
+
'HSTS Fasp/SSH'
|
47
|
+
end
|
48
|
+
|
49
|
+
def detect(address_or_url)
|
50
|
+
urls = if address_or_url.match?(%r{^[a-z]{1,6}://})
|
51
|
+
[address_or_url]
|
52
|
+
else
|
53
|
+
[
|
54
|
+
"ssh://#{address_or_url}:33001",
|
55
|
+
"ssh://#{address_or_url}:22"
|
56
|
+
]
|
57
|
+
# wss not practical as it requires a token
|
58
|
+
end
|
59
|
+
|
60
|
+
urls.each do |base_url|
|
61
|
+
server_uri = URI.parse(base_url)
|
62
|
+
Log.log.debug{"URI=#{server_uri}, host=#{server_uri.hostname}, port=#{server_uri.port}, scheme=#{server_uri.scheme}"}
|
63
|
+
next unless server_uri.scheme.eql?(SSH_SCHEME)
|
64
|
+
begin
|
65
|
+
socket = TCPSocket.new(server_uri.hostname, server_uri.port)
|
66
|
+
socket.puts('SSH-2.0-Ascli_0.0')
|
67
|
+
version = socket.gets.chomp
|
68
|
+
if version.match?(/^SSH-2.0-/)
|
69
|
+
return {version: version.gsub(/^SSH-2.0-/, ''), url: base_url}
|
70
|
+
end
|
71
|
+
rescue StandardError => e
|
72
|
+
Log.log.debug{"detect error: #{e}"}
|
73
|
+
end
|
74
|
+
end
|
75
|
+
return nil
|
76
|
+
end
|
77
|
+
|
78
|
+
def wizard(object:, private_key_path: nil, pub_key_pem: nil)
|
79
|
+
options = object.options
|
80
|
+
return {
|
81
|
+
preset_value: {
|
82
|
+
url: options.get_option(:url, mandatory: true),
|
83
|
+
username: options.get_option(:username, mandatory: true),
|
84
|
+
password: options.get_option(:password, mandatory: true)
|
85
|
+
},
|
86
|
+
test_args: 'files br /'
|
87
|
+
}
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
50
91
|
def initialize(env)
|
51
92
|
super(env)
|
52
|
-
options.
|
53
|
-
options.
|
93
|
+
options.declare(:ssh_keys, 'SSH key path list (Array or single)')
|
94
|
+
options.declare(:passphrase, 'SSH private key passphrase')
|
95
|
+
options.declare(:ssh_options, 'SSH options', types: Hash, default: {})
|
96
|
+
SyncActions.declare_options(options)
|
54
97
|
options.parse_options!
|
55
|
-
@ssh_opts =
|
98
|
+
@ssh_opts = options.get_option(:ssh_options).symbolize_keys
|
56
99
|
end
|
57
100
|
|
58
101
|
# Read command line options
|
59
102
|
# @return [Hash] transfer specification
|
60
103
|
def options_to_base_transfer_spec
|
61
|
-
url = options.get_option(:url,
|
104
|
+
url = options.get_option(:url, mandatory: true)
|
62
105
|
server_transfer_spec = {}
|
63
106
|
server_uri = URI.parse(url)
|
64
|
-
Log.log.debug{"URI
|
107
|
+
Log.log.debug{"URI=#{server_uri}, host=#{server_uri.hostname}, port=#{server_uri.port}, scheme=#{server_uri.scheme}"}
|
65
108
|
server_transfer_spec['remote_host'] = server_uri.hostname
|
66
109
|
unless URI_SCHEMES.include?(server_uri.scheme)
|
67
110
|
Log.log.warn{"Scheme [#{server_uri.scheme}] not supported in #{url}, use one of: #{URI_SCHEMES.join(', ')}. Defaulting to #{SSH_SCHEME}."}
|
68
111
|
server_uri.scheme = SSH_SCHEME
|
69
112
|
end
|
70
|
-
if server_uri.scheme.eql?(
|
113
|
+
if server_uri.scheme.eql?(LOCAL_SCHEME)
|
71
114
|
# Using local execution (mostly for testing)
|
115
|
+
server_transfer_spec['remote_host'] = 'localhost'
|
116
|
+
# simulate SSH environment, else ascp will fail
|
117
|
+
ENV['SSH_CLIENT'] = 'local 0 0'
|
72
118
|
return server_transfer_spec
|
73
|
-
elsif transfer.option_transfer_spec['token'].is_a?(String) && server_uri.scheme.eql?(
|
119
|
+
elsif transfer.option_transfer_spec['token'].is_a?(String) && server_uri.scheme.eql?(HTTPS_SCHEME)
|
74
120
|
server_transfer_spec['wss_enabled'] = true
|
75
121
|
server_transfer_spec['wss_port'] = server_uri.port
|
76
122
|
# Using WSS
|
@@ -88,11 +134,7 @@ module Aspera
|
|
88
134
|
options.set_option(:username, Aspera::Fasp::TransferSpec::ACCESS_KEY_TRANSFER_USER)
|
89
135
|
Log.log.info{"No username provided: Assuming default transfer user: #{Aspera::Fasp::TransferSpec::ACCESS_KEY_TRANSFER_USER}"}
|
90
136
|
end
|
91
|
-
server_transfer_spec['remote_user'] = options.get_option(:username,
|
92
|
-
ssh_args = options.get_option(:ssh_options)
|
93
|
-
ssh_args = {} if ssh_args.nil?
|
94
|
-
raise 'expecting a Hash for ssh_options' unless ssh_args.is_a?(Hash)
|
95
|
-
@ssh_opts = ssh_args.symbolize_keys
|
137
|
+
server_transfer_spec['remote_user'] = options.get_option(:username, mandatory: true)
|
96
138
|
if !server_uri.port.nil?
|
97
139
|
@ssh_opts[:port] = server_uri.port
|
98
140
|
server_transfer_spec['ssh_port'] = server_uri.port
|
@@ -119,6 +161,11 @@ module Aspera
|
|
119
161
|
cred_set = true
|
120
162
|
end
|
121
163
|
end
|
164
|
+
ssh_passphrase = options.get_option(:passphrase)
|
165
|
+
if !ssh_passphrase.nil?
|
166
|
+
@ssh_opts[:passphrase] = ssh_passphrase
|
167
|
+
server_transfer_spec['ssh_private_key_passphrase'] = ssh_passphrase
|
168
|
+
end
|
122
169
|
# if user provided transfer spec has a token, we will use bypass keys
|
123
170
|
cred_set = true if transfer.option_transfer_spec['token'].is_a?(String)
|
124
171
|
raise 'Either password, key , or transfer spec token must be provided' if !cred_set
|
@@ -131,8 +178,8 @@ module Aspera
|
|
131
178
|
Fasp::TransferSpec.action_to_direction(transfer_spec, command)
|
132
179
|
return Main.result_transfer(transfer.start(transfer_spec))
|
133
180
|
when :sync
|
134
|
-
|
135
|
-
return
|
181
|
+
# lets ignore the arguments provided by execute_sync_action, we just give the transfer spec
|
182
|
+
return execute_sync_action {transfer_spec}
|
136
183
|
end
|
137
184
|
end
|
138
185
|
|
@@ -143,7 +190,7 @@ module Aspera
|
|
143
190
|
|
144
191
|
def execute_action
|
145
192
|
server_transfer_spec = options_to_base_transfer_spec
|
146
|
-
ascmd_executor = if !@ssh_opts.
|
193
|
+
ascmd_executor = if !@ssh_opts.empty?
|
147
194
|
Ssh.new(server_transfer_spec['remote_host'], server_transfer_spec['remote_user'], @ssh_opts)
|
148
195
|
elsif server_transfer_spec.key?('wss_enabled')
|
149
196
|
nil
|
@@ -184,10 +231,10 @@ module Aspera
|
|
184
231
|
when *TRANSFER_COMMANDS
|
185
232
|
return execute_transfer(command, server_transfer_spec)
|
186
233
|
when *Aspera::AsCmd::OPERATIONS
|
187
|
-
|
234
|
+
command_arguments = options.get_next_argument('ascmd command arguments', expected: :multiple, mandatory: false)
|
188
235
|
ascmd = Aspera::AsCmd.new(ascmd_executor)
|
189
236
|
begin
|
190
|
-
result = ascmd.send(:execute_single, command,
|
237
|
+
result = ascmd.send(:execute_single, command, command_arguments)
|
191
238
|
case command
|
192
239
|
when :mkdir, :mv, :cp, :rm
|
193
240
|
return Main.result_success
|
@@ -199,7 +246,7 @@ module Aspera
|
|
199
246
|
return {type: :single_object, data: result.stringify_keys}
|
200
247
|
end
|
201
248
|
rescue Aspera::AsCmd::Error => e
|
202
|
-
raise
|
249
|
+
raise Cli::BadArgument, e.extended_message
|
203
250
|
end
|
204
251
|
else raise 'internal error: unexpected action'
|
205
252
|
end
|
@@ -7,43 +7,67 @@ module Aspera
|
|
7
7
|
module Plugins
|
8
8
|
# Plugin for Aspera Shares v1
|
9
9
|
class Shares < Aspera::Cli::BasicAuthPlugin
|
10
|
+
API_BASE = 'node_api'
|
10
11
|
class << self
|
11
|
-
def detect(
|
12
|
-
|
13
|
-
|
12
|
+
def detect(address_or_url)
|
13
|
+
address_or_url = "https://#{address_or_url}" unless address_or_url.match?(%r{^[a-z]{1,6}://})
|
14
|
+
api = Rest.new(base_url: address_or_url, redirect_max: 1)
|
15
|
+
found = false
|
14
16
|
begin
|
15
17
|
# shall fail: shares requires auth, but we check error message
|
16
18
|
# TODO: use ping instead ?
|
17
|
-
api.read(
|
19
|
+
api.read("#{API_BASE}/app")
|
18
20
|
rescue RestCallError => e
|
19
21
|
if e.response.code.to_s.eql?('401') && e.response.body.eql?('{"error":{"user_message":"API user authentication failed"}}')
|
20
|
-
|
22
|
+
found = true
|
21
23
|
end
|
22
24
|
end
|
23
|
-
nil
|
25
|
+
return nil unless found
|
26
|
+
version = 'unknown'
|
27
|
+
test_page = api.call({ operation: 'GET', subpath: 'login' })
|
28
|
+
if (m = test_page[:http].body.match(/\(v(1\..*)\)/))
|
29
|
+
version = m[1]
|
30
|
+
end
|
31
|
+
return {
|
32
|
+
version: version,
|
33
|
+
url: address_or_url
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
def wizard(object:, private_key_path: nil, pub_key_pem: nil)
|
38
|
+
options = object.options
|
39
|
+
return {
|
40
|
+
preset_value: {
|
41
|
+
url: options.get_option(:url, mandatory: true),
|
42
|
+
username: options.get_option(:username, mandatory: true),
|
43
|
+
password: options.get_option(:password, mandatory: true)
|
44
|
+
},
|
45
|
+
test_args: 'files br /'
|
46
|
+
}
|
24
47
|
end
|
25
48
|
end
|
26
49
|
|
27
50
|
def initialize(env)
|
28
51
|
super(env)
|
29
|
-
options.
|
30
|
-
options.set_option(:type, :any)
|
52
|
+
options.declare(:type, 'Type of user/group for operations', values: %i[any local ldap saml], default: :any)
|
31
53
|
options.parse_options!
|
32
54
|
end
|
33
55
|
|
34
56
|
SAML_IMPORT_MANDATORY = %w[id name_id].freeze
|
35
57
|
SAML_IMPORT_ALLOWED = %w[email given_name surname].concat(SAML_IMPORT_MANDATORY).freeze
|
36
58
|
|
37
|
-
ACTIONS = %i[health
|
59
|
+
ACTIONS = %i[health files admin].freeze
|
60
|
+
# common to users and groups
|
61
|
+
USR_GRP_SETTINGS = %i[transfer_settings app_authorizations share_permissions].freeze
|
38
62
|
|
39
63
|
def execute_action
|
40
|
-
command = options.get_next_command(ACTIONS)
|
64
|
+
command = options.get_next_command(ACTIONS, aliases: {repository: :files})
|
41
65
|
case command
|
42
66
|
when :health
|
43
67
|
nagios = Nagios.new
|
44
68
|
begin
|
45
69
|
Rest
|
46
|
-
.new(base_url: options.get_option(:url,
|
70
|
+
.new(base_url: "#{options.get_option(:url, mandatory: true)}/#{API_BASE}")
|
47
71
|
.call(
|
48
72
|
operation: 'GET',
|
49
73
|
subpath: 'ping',
|
@@ -54,25 +78,28 @@ module Aspera
|
|
54
78
|
nagios.add_critical('node api', e.to_s)
|
55
79
|
end
|
56
80
|
return nagios.result
|
57
|
-
when :repository
|
58
|
-
api_shares_node = basic_auth_api(
|
81
|
+
when :repository, :files
|
82
|
+
api_shares_node = basic_auth_api(API_BASE)
|
59
83
|
repo_command = options.get_next_command(Node::COMMANDS_SHARES)
|
60
|
-
return Node.new(@agents
|
84
|
+
return Node.new(@agents, api: api_shares_node).execute_action(repo_command)
|
61
85
|
when :admin
|
62
86
|
api_shares_admin = basic_auth_api('api/v1')
|
63
|
-
admin_command = options.get_next_command(%i[user group share node])
|
87
|
+
admin_command = options.get_next_command(%i[user group share node].freeze)
|
64
88
|
case admin_command
|
65
89
|
when :node
|
66
90
|
return entity_action(api_shares_admin, 'data/nodes')
|
67
91
|
when :user, :group
|
68
92
|
entity_type = admin_command
|
69
|
-
entities_location = options.get_option(:type,
|
93
|
+
entities_location = options.get_option(:type, mandatory: true)
|
70
94
|
entities_path = "data/#{entities_location}_#{entity_type}s"
|
71
95
|
entity_action = nil
|
72
96
|
case entities_location
|
73
97
|
when :any
|
74
98
|
entities_path = "data/#{entity_type}s"
|
75
|
-
entity_action = %i[list show delete
|
99
|
+
entity_action = %i[list show delete]
|
100
|
+
entity_action.concat(USR_GRP_SETTINGS)
|
101
|
+
entity_action.push(:users) if entity_type.eql?(:group)
|
102
|
+
entity_action.freeze
|
76
103
|
when :local
|
77
104
|
entity_action = %i[list show create modify delete].freeze
|
78
105
|
when :ldap
|
@@ -80,31 +107,15 @@ module Aspera
|
|
80
107
|
when :saml
|
81
108
|
entity_action = %i[import].freeze
|
82
109
|
end
|
83
|
-
|
84
|
-
entity_path = "#{entities_path}/#{instance_identifier}" if %i[app_authorizations share_permissions].include?(
|
85
|
-
case
|
86
|
-
when
|
110
|
+
entity_verb = options.get_next_command(entity_action)
|
111
|
+
# entity_path = "#{entities_path}/#{instance_identifier}" if %i[app_authorizations share_permissions].include?(entity_verb)
|
112
|
+
case entity_verb
|
113
|
+
when *Plugin::ALL_OPS
|
87
114
|
display_fields = entity_type.eql?(:user) ? %w[id username first_name last_name email] : nil
|
88
115
|
display_fields.push(:directory_user) if entity_type.eql?(:user) && entities_location.eql?(:any)
|
89
|
-
return entity_command(
|
90
|
-
when :app_authorizations
|
91
|
-
case options.get_next_command(%i[modify show])
|
92
|
-
when :show
|
93
|
-
return {type: :single_object, data: api_shares_admin.read("#{entity_path}/app_authorizations")[:data]}
|
94
|
-
when :modify
|
95
|
-
parameters = options.get_option(:value, is_type: :mandatory)
|
96
|
-
return {type: :single_object, data: api_shares_admin.update("#{entity_path}/app_authorizations", parameters)[:data]}
|
97
|
-
end
|
98
|
-
when :share_permissions
|
99
|
-
case options.get_next_command(%i[list show])
|
100
|
-
when :list
|
101
|
-
return {type: :object_list, data: api_shares_admin.read("#{entity_path}/share_permissions")[:data]}
|
102
|
-
when :show
|
103
|
-
return {type: :single_object, data: api_shares_admin.read("#{entity_path}/share_permissions/#{instance_identifier}")[:data]}
|
104
|
-
end
|
116
|
+
return entity_command(entity_verb, api_shares_admin, entities_path, display_fields: display_fields)
|
105
117
|
when :import
|
106
|
-
|
107
|
-
return do_bulk_operation(parameters, 'created') do |entity_parameters|
|
118
|
+
return do_bulk_operation(command: entity_verb, descr: 'user information') do |entity_parameters|
|
108
119
|
entity_parameters = entity_parameters.transform_keys{|k|k.gsub(/\s+/, '_').downcase}
|
109
120
|
raise 'expecting Hash' unless entity_parameters.is_a?(Hash)
|
110
121
|
SAML_IMPORT_MANDATORY.each{|p|raise "missing mandatory field: #{p}" if entity_parameters[p].nil?}
|
@@ -114,11 +125,13 @@ module Aspera
|
|
114
125
|
api_shares_admin.create("#{entities_path}/import", entity_parameters)[:data]
|
115
126
|
end
|
116
127
|
when :add
|
117
|
-
|
118
|
-
return do_bulk_operation(parameters, 'created') do |entity_name|
|
119
|
-
raise "expecting string (name), have #{entity_name.class}" unless entity_name.is_a?(String)
|
128
|
+
return do_bulk_operation(command: entity_verb, descr: "#{entity_type} name", values: String) do |entity_name|
|
120
129
|
api_shares_admin.create(entities_path, {entity_type=>entity_name})[:data]
|
121
130
|
end
|
131
|
+
when *USR_GRP_SETTINGS
|
132
|
+
group_id = instance_identifier
|
133
|
+
entities_path = "#{entities_path}/#{group_id}/#{entity_verb}"
|
134
|
+
return entity_action(api_shares_admin, entities_path, is_singleton: !entity_verb.eql?(:share_permissions))
|
122
135
|
end
|
123
136
|
when :share
|
124
137
|
share_command = options.get_next_command(%i[user_permissions group_permissions].concat(Plugin::ALL_OPS))
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'aspera/sync'
|
4
|
+
|
5
|
+
module Aspera
|
6
|
+
module Cli
|
7
|
+
# Module for sync actions
|
8
|
+
module SyncActions
|
9
|
+
SIMPLE_ARGUMENTS_SYNC = {
|
10
|
+
direction: Aspera::Sync::DIRECTIONS,
|
11
|
+
local_dir: String,
|
12
|
+
remote_dir: String
|
13
|
+
}.stringify_keys.freeze
|
14
|
+
|
15
|
+
class << self
|
16
|
+
def declare_options(options)
|
17
|
+
options.declare(:sync_info, 'Information for sync instance and sessions', types: Hash)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def execute_sync_action(&block)
|
22
|
+
# options = Aspera::Cli::Manager.new
|
23
|
+
raise 'Internal Error: No block given' unless block
|
24
|
+
command = options.get_next_command(%i[start admin])
|
25
|
+
# try to get 3 arguments as simple arguments
|
26
|
+
case command
|
27
|
+
when :start
|
28
|
+
simple_session_args = {}
|
29
|
+
SIMPLE_ARGUMENTS_SYNC.each do |arg, check|
|
30
|
+
value = options.get_next_argument(
|
31
|
+
arg,
|
32
|
+
type: check.is_a?(Class) ? check : nil,
|
33
|
+
expected: check.is_a?(Class) ? :single : check,
|
34
|
+
mandatory: false)
|
35
|
+
break if value.nil?
|
36
|
+
simple_session_args[arg] = value.to_s
|
37
|
+
end
|
38
|
+
async_params = nil
|
39
|
+
if simple_session_args.empty?
|
40
|
+
async_params = options.get_option(:sync_info, mandatory: true)
|
41
|
+
else
|
42
|
+
raise Cli::BadArgument,
|
43
|
+
"Provide zero or 3 arguments: #{SIMPLE_ARGUMENTS_SYNC.keys.join(',')}" unless simple_session_args.keys.sort == SIMPLE_ARGUMENTS_SYNC.keys.sort
|
44
|
+
async_params = options.get_option(
|
45
|
+
:sync_info,
|
46
|
+
mandatory: false,
|
47
|
+
default: {'sessions' => [{'name' => File.basename(simple_session_args['local_dir'])}]})
|
48
|
+
raise "sync_info shall be a Hash with key 'sessions' with Array of Hash: #{async_params}" unless async_params.is_a?(Hash) &&
|
49
|
+
async_params['sessions']&.is_a?(Array) &&
|
50
|
+
async_params['sessions'].first.is_a?(Hash)
|
51
|
+
async_params['sessions'].first.merge!(simple_session_args)
|
52
|
+
end
|
53
|
+
Log.log.debug{Log.dump('async_params', async_params)}
|
54
|
+
Aspera::Sync.start(async_params, &block)
|
55
|
+
return Main.result_success
|
56
|
+
when :admin
|
57
|
+
command2 = options.get_next_command([:status])
|
58
|
+
case command2
|
59
|
+
when :status
|
60
|
+
sync_session_name = options.get_next_argument('name of sync session', mandatory: false, type: String)
|
61
|
+
async_params = options.get_option(:sync_info, mandatory: true)
|
62
|
+
return {type: :single_object, data: Aspera::Sync.admin_status(async_params, sync_session_name)}
|
63
|
+
end # command2
|
64
|
+
end # command
|
65
|
+
end # execute_action
|
66
|
+
end # SyncActions
|
67
|
+
end # Cli
|
68
|
+
end # Aspera
|