aspera-cli 4.10.0 → 4.12.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/BUGS.md +19 -0
- data/CHANGELOG.md +528 -0
- data/CONTRIBUTING.md +143 -0
- data/README.md +977 -589
- data/bin/ascli +4 -4
- data/bin/asession +12 -12
- data/docs/test_env.conf +29 -19
- data/examples/aoc.rb +6 -6
- data/examples/dascli +18 -16
- data/examples/faspex4.rb +15 -15
- data/examples/node.rb +12 -12
- data/examples/proxy.pac +2 -2
- data/examples/server.rb +12 -12
- data/lib/aspera/aoc.rb +344 -272
- data/lib/aspera/ascmd.rb +56 -54
- data/lib/aspera/ats_api.rb +4 -4
- data/lib/aspera/cli/basic_auth_plugin.rb +15 -12
- data/lib/aspera/cli/extended_value.rb +9 -9
- data/lib/aspera/cli/{formater.rb → formatter.rb} +69 -69
- data/lib/aspera/cli/listener/line_dump.rb +1 -1
- data/lib/aspera/cli/listener/logger.rb +1 -1
- data/lib/aspera/cli/listener/progress.rb +5 -6
- data/lib/aspera/cli/listener/progress_multi.rb +16 -21
- data/lib/aspera/cli/main.rb +72 -73
- data/lib/aspera/cli/manager.rb +112 -112
- data/lib/aspera/cli/plugin.rb +68 -48
- data/lib/aspera/cli/plugins/alee.rb +4 -4
- data/lib/aspera/cli/plugins/aoc.rb +322 -720
- data/lib/aspera/cli/plugins/ats.rb +50 -52
- data/lib/aspera/cli/plugins/bss.rb +10 -10
- data/lib/aspera/cli/plugins/config.rb +514 -410
- data/lib/aspera/cli/plugins/console.rb +12 -12
- data/lib/aspera/cli/plugins/cos.rb +18 -20
- data/lib/aspera/cli/plugins/faspex.rb +134 -136
- data/lib/aspera/cli/plugins/faspex5.rb +235 -70
- data/lib/aspera/cli/plugins/node.rb +378 -309
- data/lib/aspera/cli/plugins/orchestrator.rb +52 -49
- data/lib/aspera/cli/plugins/preview.rb +129 -120
- data/lib/aspera/cli/plugins/server.rb +137 -83
- data/lib/aspera/cli/plugins/shares.rb +77 -52
- data/lib/aspera/cli/plugins/sync.rb +13 -33
- data/lib/aspera/cli/transfer_agent.rb +61 -61
- data/lib/aspera/cli/version.rb +2 -1
- data/lib/aspera/colors.rb +3 -3
- data/lib/aspera/command_line_builder.rb +78 -74
- data/lib/aspera/cos_node.rb +31 -29
- data/lib/aspera/data_repository.rb +1 -1
- data/lib/aspera/environment.rb +30 -28
- data/lib/aspera/fasp/agent_base.rb +17 -15
- data/lib/aspera/fasp/agent_connect.rb +34 -32
- data/lib/aspera/fasp/agent_direct.rb +70 -73
- data/lib/aspera/fasp/agent_httpgw.rb +79 -74
- data/lib/aspera/fasp/agent_node.rb +26 -26
- data/lib/aspera/fasp/agent_trsdk.rb +20 -20
- data/lib/aspera/fasp/error.rb +3 -2
- data/lib/aspera/fasp/error_info.rb +11 -8
- data/lib/aspera/fasp/installation.rb +80 -80
- data/lib/aspera/fasp/listener.rb +2 -2
- data/lib/aspera/fasp/parameters.rb +103 -92
- data/lib/aspera/fasp/parameters.yaml +313 -214
- data/lib/aspera/fasp/resume_policy.rb +10 -10
- data/lib/aspera/fasp/transfer_spec.rb +22 -2
- data/lib/aspera/fasp/uri.rb +7 -7
- data/lib/aspera/faspex_gw.rb +80 -159
- data/lib/aspera/faspex_postproc.rb +77 -0
- data/lib/aspera/hash_ext.rb +3 -3
- data/lib/aspera/id_generator.rb +5 -5
- data/lib/aspera/keychain/encrypted_hash.rb +23 -28
- data/lib/aspera/keychain/macos_security.rb +21 -20
- data/lib/aspera/log.rb +13 -13
- data/lib/aspera/nagios.rb +24 -23
- data/lib/aspera/node.rb +217 -38
- data/lib/aspera/oauth.rb +78 -74
- data/lib/aspera/open_application.rb +19 -11
- data/lib/aspera/persistency_action_once.rb +4 -4
- data/lib/aspera/persistency_folder.rb +13 -13
- data/lib/aspera/preview/file_types.rb +8 -8
- data/lib/aspera/preview/generator.rb +67 -67
- data/lib/aspera/preview/utils.rb +27 -27
- data/lib/aspera/proxy_auto_config.js +63 -63
- data/lib/aspera/proxy_auto_config.rb +19 -19
- data/lib/aspera/rest.rb +65 -67
- data/lib/aspera/rest_call_error.rb +2 -1
- data/lib/aspera/rest_error_analyzer.rb +22 -21
- data/lib/aspera/rest_errors_aspera.rb +16 -16
- data/lib/aspera/secret_hider.rb +17 -14
- data/lib/aspera/ssh.rb +15 -14
- data/lib/aspera/sync.rb +177 -62
- data/lib/aspera/temp_file_manager.rb +2 -2
- data/lib/aspera/uri_reader.rb +4 -4
- data/lib/aspera/web_auth.rb +13 -64
- data/lib/aspera/web_server_simple.rb +76 -0
- data.tar.gz.sig +0 -0
- metadata +11 -6
- metadata.gz.sig +0 -0
@@ -1,98 +1,150 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'aspera/cli/basic_auth_plugin'
|
4
|
+
require 'aspera/cli/plugins/sync'
|
4
5
|
require 'aspera/ascmd'
|
5
6
|
require 'aspera/fasp/transfer_spec'
|
6
7
|
require 'aspera/ssh'
|
7
8
|
require 'aspera/nagios'
|
8
9
|
require 'tempfile'
|
10
|
+
require 'open3'
|
9
11
|
|
10
12
|
module Aspera
|
11
13
|
module Cli
|
12
14
|
module Plugins
|
13
15
|
# implement basic remote access with FASP/SSH
|
14
|
-
class Server < BasicAuthPlugin
|
16
|
+
class Server < Aspera::Cli::BasicAuthPlugin
|
17
|
+
SSH_SCHEME = 'ssh'
|
18
|
+
URI_SCHEMES = %w[https local].push(SSH_SCHEME).freeze
|
19
|
+
ASCMD_ALIASES = {
|
20
|
+
browse: :ls,
|
21
|
+
delete: :rm,
|
22
|
+
rename: :mv
|
23
|
+
}.freeze
|
24
|
+
TRANSFER_COMMANDS = %i[sync upload download].freeze
|
25
|
+
|
26
|
+
private_constant :SSH_SCHEME, :URI_SCHEMES, :ASCMD_ALIASES, :TRANSFER_COMMANDS
|
27
|
+
|
15
28
|
class LocalExecutor
|
16
|
-
def execute(cmd,
|
17
|
-
|
18
|
-
|
29
|
+
def execute(cmd, line)
|
30
|
+
# concatenate arguments, enclose in double quotes
|
31
|
+
cmd = cmd.map{|v|%Q("#{v}")}.join(' ') if cmd.is_a?(Array)
|
32
|
+
Log.log.debug{"Executing: #{cmd} with '#{line}'"}
|
33
|
+
stdout_str, stderr_str, status = Open3.capture3(cmd, stdin_data: line, binmode: true)
|
34
|
+
Log.log.debug(">> #{status} -> #{stderr_str}")
|
35
|
+
raise "command #{cmd} failed with code #{status.exitstatus} #{stderr_str}" unless status.success?
|
36
|
+
return stdout_str
|
19
37
|
end
|
20
38
|
end
|
21
39
|
|
22
40
|
def initialize(env)
|
23
41
|
super(env)
|
24
|
-
options.add_opt_simple(:ssh_keys,'SSH key path list (Array or single)')
|
25
|
-
options.add_opt_simple(:ssh_options,'SSH options (Hash)')
|
26
|
-
options.set_option(:ssh_keys,[])
|
27
|
-
options.set_option(:ssh_options,{})
|
42
|
+
options.add_opt_simple(:ssh_keys, 'SSH key path list (Array or single)')
|
43
|
+
options.add_opt_simple(:ssh_options, 'SSH options (Hash)')
|
28
44
|
options.parse_options!
|
45
|
+
@ssh_opts = nil
|
29
46
|
end
|
30
47
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
48
|
+
# Read command line options
|
49
|
+
# @return [Hash] transfer specification
|
50
|
+
def options_to_base_transfer_spec
|
51
|
+
url = options.get_option(:url, is_type: :mandatory)
|
52
|
+
server_transfer_spec = {}
|
53
|
+
server_uri = URI.parse(url)
|
54
|
+
Log.log.debug{"URI : #{server_uri}, port=#{server_uri.port}, scheme:#{server_uri.scheme}"}
|
55
|
+
server_transfer_spec['remote_host'] = server_uri.hostname
|
56
|
+
unless URI_SCHEMES.include?(server_uri.scheme)
|
57
|
+
Log.log.warn{"Scheme [#{server_uri.scheme}] not supported in #{url}, use one of: #{URI_SCHEMES.join(', ')}. Defaulting to #{SSH_SCHEME}."}
|
58
|
+
server_uri.scheme = SSH_SCHEME
|
59
|
+
end
|
60
|
+
if server_uri.scheme.eql?('local')
|
61
|
+
# Using local execution (mostly for testing)
|
62
|
+
return server_transfer_spec
|
63
|
+
elsif transfer.option_transfer_spec['token'].is_a?(String) && server_uri.scheme.eql?('https')
|
47
64
|
server_transfer_spec['wss_enabled'] = true
|
48
65
|
server_transfer_spec['wss_port'] = server_uri.port
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
server_transfer_spec['
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
66
|
+
# Using WSS
|
67
|
+
return server_transfer_spec
|
68
|
+
end
|
69
|
+
if !server_uri.scheme.eql?(SSH_SCHEME)
|
70
|
+
Log.log.warn('URL scheme is https but no token was provided in transfer spec.')
|
71
|
+
Log.log.warn("If you want to access the server, not using WSS for session, then use a URL with scheme \"#{SSH_SCHEME}\" and proper SSH port")
|
72
|
+
assumed_url = "#{SSH_SCHEME}://#{server_transfer_spec['remote_host']}:#{Aspera::Fasp::TransferSpec::SSH_PORT}"
|
73
|
+
Log.log.warn{"Assuming proper URL is: #{assumed_url}"}
|
74
|
+
server_uri = URI.parse(assumed_url)
|
75
|
+
end
|
76
|
+
# Scheme is SSH
|
77
|
+
if options.get_option(:username).nil?
|
78
|
+
options.set_option(:username, Aspera::Fasp::TransferSpec::ACCESS_KEY_TRANSFER_USER)
|
79
|
+
Log.log.info{"No username provided: Assuming default transfer user: #{Aspera::Fasp::TransferSpec::ACCESS_KEY_TRANSFER_USER}"}
|
80
|
+
end
|
81
|
+
server_transfer_spec['remote_user'] = options.get_option(:username, is_type: :mandatory)
|
82
|
+
ssh_args = options.get_option(:ssh_options)
|
83
|
+
ssh_args = {} if ssh_args.nil?
|
84
|
+
raise 'expecting a Hash for ssh_options' unless ssh_args.is_a?(Hash)
|
85
|
+
@ssh_opts = ssh_args.symbolize_keys
|
86
|
+
if !server_uri.port.nil?
|
87
|
+
@ssh_opts[:port] = server_uri.port
|
88
|
+
server_transfer_spec['ssh_port'] = server_uri.port
|
89
|
+
end
|
90
|
+
cred_set = false
|
91
|
+
password = options.get_option(:password)
|
92
|
+
if !password.nil?
|
93
|
+
@ssh_opts[:password] = password
|
94
|
+
server_transfer_spec['remote_password'] = password
|
95
|
+
cred_set = true
|
96
|
+
end
|
97
|
+
ssh_key_list = options.get_option(:ssh_keys)
|
98
|
+
if !ssh_key_list.nil?
|
99
|
+
raise 'Expecting single value or array for ssh_keys' unless ssh_key_list.is_a?(Array) || ssh_key_list.is_a?(String)
|
100
|
+
ssh_key_list = [ssh_key_list] if ssh_key_list.is_a?(String)
|
101
|
+
ssh_key_list.map!{|p|File.expand_path(p)}
|
102
|
+
Log.log.debug{"SSH keys=#{ssh_key_list}"}
|
103
|
+
if !ssh_key_list.empty?
|
104
|
+
@ssh_opts[:keys] = ssh_key_list
|
105
|
+
server_transfer_spec['EX_ssh_key_paths'] = ssh_key_list
|
106
|
+
ssh_key_list.each do |k|
|
107
|
+
Log.log.warn{"No such key file: #{k}"} unless File.exist?(k)
|
83
108
|
end
|
109
|
+
cred_set = true
|
84
110
|
end
|
85
|
-
# if user provided transfer spec has a token, we will use by pass keys
|
86
|
-
cred_set = true if transfer.option_transfer_spec['token'].is_a?(String)
|
87
|
-
raise 'either password, key , or transfer spec token must be provided' if !cred_set
|
88
|
-
shell_executor = Ssh.new(server_transfer_spec['remote_host'],server_transfer_spec['remote_user'],ssh_options)
|
89
111
|
end
|
112
|
+
# if user provided transfer spec has a token, we will use bypass keys
|
113
|
+
cred_set = true if transfer.option_transfer_spec['token'].is_a?(String)
|
114
|
+
raise 'Either password, key , or transfer spec token must be provided' if !cred_set
|
115
|
+
return server_transfer_spec
|
116
|
+
end
|
117
|
+
|
118
|
+
def execute_transfer(command, transfer_spec)
|
119
|
+
case command
|
120
|
+
when :upload, :download
|
121
|
+
Fasp::TransferSpec.action_to_direction(transfer_spec, command)
|
122
|
+
return Main.result_transfer(transfer.start(transfer_spec))
|
123
|
+
when :sync
|
124
|
+
sync_plugin = Sync.new(@agents, transfer_spec: transfer_spec)
|
125
|
+
return sync_plugin.execute_action
|
126
|
+
end
|
127
|
+
end
|
90
128
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
129
|
+
# actions without ascmd
|
130
|
+
BASE_ACTIONS = %i[health].concat(TRANSFER_COMMANDS).freeze
|
131
|
+
# all actions
|
132
|
+
ACTIONS = [BASE_ACTIONS, Aspera::AsCmd::OPERATIONS, ASCMD_ALIASES.keys].flatten.freeze
|
133
|
+
|
134
|
+
def execute_action
|
135
|
+
server_transfer_spec = options_to_base_transfer_spec
|
136
|
+
ascmd_executor = if !@ssh_opts.nil?
|
137
|
+
Ssh.new(server_transfer_spec['remote_host'], server_transfer_spec['remote_user'], @ssh_opts)
|
138
|
+
elsif server_transfer_spec.key?('wss_enabled')
|
139
|
+
nil
|
140
|
+
else
|
141
|
+
LocalExecutor.new
|
142
|
+
end
|
143
|
+
# the set of available commands depends on SSH executor availability (i.e. no WSS)
|
144
|
+
available_commands = ascmd_executor.nil? ? BASE_ACTIONS : ACTIONS
|
145
|
+
# get command and translate aliases
|
146
|
+
command = options.get_next_command(available_commands)
|
147
|
+
command = ASCMD_ALIASES[command] if ASCMD_ALIASES.key?(command)
|
96
148
|
case command
|
97
149
|
when :health
|
98
150
|
nagios = Nagios.new
|
@@ -107,35 +159,37 @@ module Aspera
|
|
107
159
|
'direction' => 'send',
|
108
160
|
'cookie' => 'aspera.sync', # hide in console
|
109
161
|
'resume_policy' => 'none',
|
110
|
-
'paths' => [{'source' => filepath,'destination' => '.fasping'}]
|
162
|
+
'paths' => [{'source' => filepath, 'destination' => '.fasping'}]
|
111
163
|
})
|
112
|
-
statuses = transfer.start(probe_ts
|
164
|
+
statuses = transfer.start(probe_ts)
|
113
165
|
file.unlink
|
114
166
|
if TransferAgent.session_status(statuses).eql?(:success)
|
115
|
-
nagios.add_ok('transfer','ok')
|
167
|
+
nagios.add_ok('transfer', 'ok')
|
116
168
|
else
|
117
|
-
nagios.add_critical('transfer',statuses.reject{|i|i.eql?(:success)}.first.to_s)
|
169
|
+
nagios.add_critical('transfer', statuses.reject{|i|i.eql?(:success)}.first.to_s)
|
118
170
|
end
|
119
171
|
else raise 'ERROR'
|
120
172
|
end
|
121
173
|
return nagios.result
|
122
|
-
when
|
123
|
-
return
|
124
|
-
when :download
|
125
|
-
return Main.result_transfer(transfer.start(server_transfer_spec.merge('direction' => Fasp::TransferSpec::DIRECTION_RECEIVE),{src: :direct}))
|
174
|
+
when *TRANSFER_COMMANDS
|
175
|
+
return execute_transfer(command, server_transfer_spec)
|
126
176
|
when *Aspera::AsCmd::OPERATIONS
|
127
|
-
args = options.get_next_argument('ascmd command arguments',expected: :multiple,mandatory: false)
|
128
|
-
ascmd = Aspera::AsCmd.new(
|
177
|
+
args = options.get_next_argument('ascmd command arguments', expected: :multiple, mandatory: false)
|
178
|
+
ascmd = Aspera::AsCmd.new(ascmd_executor)
|
129
179
|
begin
|
130
|
-
result = ascmd.send(:execute_single,command,args)
|
180
|
+
result = ascmd.send(:execute_single, command, args)
|
131
181
|
case command
|
132
|
-
when :mkdir
|
133
|
-
|
134
|
-
when :
|
135
|
-
|
182
|
+
when :mkdir, :mv, :cp, :rm
|
183
|
+
return Main.result_success
|
184
|
+
when :ls
|
185
|
+
return {type: :object_list, data: result.map(&:stringify_keys), fields: %w[zmode zuid zgid size mtime name]}
|
186
|
+
when :df
|
187
|
+
return {type: :object_list, data: result.map(&:stringify_keys)}
|
188
|
+
when :du, :md5sum, :info
|
189
|
+
return {type: :single_object, data: result.stringify_keys}
|
136
190
|
end
|
137
191
|
rescue Aspera::AsCmd::Error => e
|
138
|
-
raise CliBadArgument,e.extended_message
|
192
|
+
raise CliBadArgument, e.extended_message
|
139
193
|
end
|
140
194
|
else raise 'internal error: unexpected action'
|
141
195
|
end
|
@@ -5,13 +5,15 @@ require 'aspera/cli/plugins/node'
|
|
5
5
|
module Aspera
|
6
6
|
module Cli
|
7
7
|
module Plugins
|
8
|
-
|
8
|
+
# Plugin for Aspera Shares v1
|
9
|
+
class Shares < Aspera::Cli::BasicAuthPlugin
|
9
10
|
class << self
|
10
11
|
def detect(base_url)
|
11
12
|
api = Rest.new({base_url: base_url})
|
12
13
|
# Shares
|
13
14
|
begin
|
14
15
|
# shall fail: shares requires auth, but we check error message
|
16
|
+
# TODO: use ping instead ?
|
15
17
|
api.read('node_api/app')
|
16
18
|
rescue RestCallError => e
|
17
19
|
if e.response.code.to_s.eql?('401') && e.response.body.eql?('{"error":{"user_message":"API user authentication failed"}}')
|
@@ -22,12 +24,15 @@ module Aspera
|
|
22
24
|
end
|
23
25
|
end
|
24
26
|
|
25
|
-
|
26
|
-
|
27
|
-
|
27
|
+
def initialize(env)
|
28
|
+
super(env)
|
29
|
+
options.add_opt_list(:type, %i[any local ldap saml], 'Type of user/group for operations')
|
30
|
+
options.set_option(:type, :any)
|
31
|
+
options.parse_options!
|
32
|
+
end
|
28
33
|
|
29
|
-
SAML_IMPORT_MANDATORY
|
30
|
-
SAML_IMPORT_ALLOWED=
|
34
|
+
SAML_IMPORT_MANDATORY = %w[id name_id].freeze
|
35
|
+
SAML_IMPORT_ALLOWED = %w[email given_name surname].concat(SAML_IMPORT_MANDATORY).freeze
|
31
36
|
|
32
37
|
ACTIONS = %i[health repository admin].freeze
|
33
38
|
|
@@ -37,72 +42,92 @@ module Aspera
|
|
37
42
|
when :health
|
38
43
|
nagios = Nagios.new
|
39
44
|
begin
|
40
|
-
Rest
|
41
|
-
new(base_url: options.get_option(:url,is_type: :mandatory)+'/node_api')
|
42
|
-
call(
|
45
|
+
Rest
|
46
|
+
.new(base_url: options.get_option(:url, is_type: :mandatory) + '/node_api')
|
47
|
+
.call(
|
43
48
|
operation: 'GET',
|
44
49
|
subpath: 'ping',
|
45
50
|
headers: {'content-type': 'application/json'},
|
46
51
|
return_error: true)
|
47
|
-
nagios.add_ok('shares api','accessible')
|
52
|
+
nagios.add_ok('shares api', 'accessible')
|
48
53
|
rescue StandardError => e
|
49
|
-
nagios.add_critical('node api',e.to_s)
|
54
|
+
nagios.add_critical('node api', e.to_s)
|
50
55
|
end
|
51
56
|
return nagios.result
|
52
57
|
when :repository
|
53
58
|
api_shares_node = basic_auth_api('node_api')
|
54
|
-
|
55
|
-
|
56
|
-
when *Node::COMMON_ACTIONS then Node.new(@agents.merge(skip_basic_auth_options: true,node_api: api_shares_node)).execute_action(command)
|
57
|
-
else raise "INTERNAL ERROR, unknown command: [#{command}]"
|
58
|
-
end
|
59
|
+
repo_command = options.get_next_command(Node::COMMANDS_SHARES)
|
60
|
+
return Node.new(@agents.merge(skip_basic_auth_options: true, node_api: api_shares_node)).execute_action(repo_command)
|
59
61
|
when :admin
|
60
62
|
api_shares_admin = basic_auth_api('api/v1')
|
61
|
-
|
62
|
-
case
|
63
|
-
when :
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
63
|
+
admin_command = options.get_next_command(%i[user group share node])
|
64
|
+
case admin_command
|
65
|
+
when :node
|
66
|
+
return entity_action(api_shares_admin, 'data/nodes')
|
67
|
+
when :user, :group
|
68
|
+
entity_type = admin_command
|
69
|
+
entities_location = options.get_option(:type, is_type: :mandatory)
|
70
|
+
entities_path = "data/#{entities_location}_#{entity_type}s"
|
71
|
+
entity_action = nil
|
72
|
+
case entities_location
|
73
|
+
when :any
|
74
|
+
entities_path = "data/#{entity_type}s"
|
75
|
+
entity_action = %i[list show delete share_permissions app_authorizations].freeze
|
76
|
+
when :local
|
77
|
+
entity_action = %i[list show create modify delete].freeze
|
78
|
+
when :ldap
|
79
|
+
entity_action = %i[add].freeze
|
80
|
+
when :saml
|
81
|
+
entity_action = %i[import].freeze
|
82
|
+
end
|
83
|
+
entity_command = options.get_next_command(entity_action)
|
84
|
+
entity_path = "#{entities_path}/#{instance_identifier}" if %i[app_authorizations share_permissions].include?(entity_command)
|
85
|
+
case entity_command
|
86
|
+
when :list, :show, :create, :delete, :modify
|
87
|
+
display_fields = entity_type.eql?(:user) ? %w[id username first_name last_name email] : nil
|
88
|
+
display_fields.push(:directory_user) if entity_type.eql?(:user) && entities_location.eql?(:any)
|
89
|
+
return entity_command(entity_command, api_shares_admin, entities_path, display_fields: display_fields)
|
69
90
|
when :app_authorizations
|
70
|
-
|
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
|
71
98
|
when :share_permissions
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
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
|
105
|
+
when :import
|
106
|
+
parameters = options.get_option(:value, is_type: :mandatory)
|
107
|
+
return do_bulk_operation(parameters, 'created') do |entity_parameters|
|
108
|
+
entity_parameters = entity_parameters.transform_keys{|k|k.gsub(/\s+/, '_').downcase}
|
109
|
+
raise 'expecting Hash' unless entity_parameters.is_a?(Hash)
|
110
|
+
SAML_IMPORT_MANDATORY.each{|p|raise "missing mandatory field: #{p}" if entity_parameters[p].nil?}
|
111
|
+
entity_parameters.each_key do |p|
|
83
112
|
raise "unsupported field: #{p}, use: #{SAML_IMPORT_ALLOWED.join(',')}" unless SAML_IMPORT_ALLOWED.include?(p)
|
84
113
|
end
|
85
|
-
api_shares_admin.create(
|
114
|
+
api_shares_admin.create("#{entities_path}/import", entity_parameters)[:data]
|
86
115
|
end
|
87
|
-
when :
|
116
|
+
when :add
|
88
117
|
parameters = options.get_option(:value)
|
89
|
-
return do_bulk_operation(parameters,'created') do |
|
90
|
-
raise
|
91
|
-
api_shares_admin.create(
|
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)
|
120
|
+
api_shares_admin.create(entities_path, {entity_type=>entity_name})[:data]
|
92
121
|
end
|
93
122
|
end
|
94
123
|
when :share
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
#share_name = options.get_next_argument('share name')
|
103
|
-
#share_id = all_shares.find{|s| s['name'].eql?(share_name)}['id']
|
104
|
-
#raise "NOT IMPLEMENTED: #{share_name} #{share_id}"
|
105
|
-
return {type: :object_list,data: api_shares_admin.read("data/shares/#{share_id}/user_permissions")[:data]}
|
124
|
+
share_command = options.get_next_command(%i[user_permissions group_permissions].concat(Plugin::ALL_OPS))
|
125
|
+
case share_command
|
126
|
+
when *Plugin::ALL_OPS
|
127
|
+
return entity_command(share_command, api_shares_admin, 'data/shares')
|
128
|
+
# return {type: :object_list, data: all_shares, fields: %w[id name status status_message]}
|
129
|
+
when :user_permissions, :group_permissions
|
130
|
+
return entity_action(api_shares_admin, "data/shares/#{instance_identifier}/#{share_command}")
|
106
131
|
end
|
107
132
|
end
|
108
133
|
end
|
@@ -9,13 +9,16 @@ require 'open3'
|
|
9
9
|
module Aspera
|
10
10
|
module Cli
|
11
11
|
module Plugins
|
12
|
-
#
|
13
|
-
class Sync < Plugin
|
14
|
-
def initialize(env)
|
12
|
+
# Execute Aspera Sync
|
13
|
+
class Sync < Aspera::Cli::Plugin
|
14
|
+
def initialize(env, transfer_spec: nil)
|
15
15
|
super(env)
|
16
|
-
options.add_opt_simple(:
|
17
|
-
options.add_opt_simple(:
|
16
|
+
options.add_opt_simple(:sync_info, 'Information for sync instance and sessions (Hash)')
|
17
|
+
options.add_opt_simple(:sync_session, 'Name of session to use for admin commands. default: first in parameters')
|
18
18
|
options.parse_options!
|
19
|
+
return if env[:man_only]
|
20
|
+
@params = options.get_option(:sync_info, is_type: :mandatory)
|
21
|
+
Aspera::Sync.update_parameters_with_transfer_spec(@params, transfer_spec) unless transfer_spec.nil?
|
19
22
|
end
|
20
23
|
|
21
24
|
ACTIONS = %i[start admin].freeze
|
@@ -24,38 +27,15 @@ module Aspera
|
|
24
27
|
command = options.get_next_command(ACTIONS)
|
25
28
|
case command
|
26
29
|
when :start
|
27
|
-
|
28
|
-
|
29
|
-
Log.log.debug("execute: #{env_args[:env].map{|k,v| "#{k}=\"#{v}\""}.join(' ')} \"#{async_bin}\" \"#{env_args[:args].join('" "')}\"")
|
30
|
-
res = system(env_args[:env],[async_bin,async_bin],*env_args[:args])
|
31
|
-
Log.log.debug("result=#{res}")
|
32
|
-
case res
|
33
|
-
when true then return Main.result_success
|
34
|
-
when false then raise "failed: #{$CHILD_STATUS}"
|
35
|
-
when nil then return Main.result_status("not started: #{$CHILD_STATUS}")
|
36
|
-
else raise 'internal error: unspecified case'
|
37
|
-
end
|
30
|
+
Aspera::Sync.new(@params).start
|
31
|
+
return Main.result_success
|
38
32
|
when :admin
|
39
|
-
|
40
|
-
n = options.get_option(:session_name)
|
41
|
-
cmdline = ['asyncadmin','--quiet']
|
42
|
-
session = n.nil? ? p['sessions'].first : p['sessions'].find{|s|s['name'].eql?(n)}
|
43
|
-
cmdline.push('--name=' + session['name'])
|
44
|
-
if session.has_key?('local_db_dir')
|
45
|
-
cmdline.push('--local-db-dir=' + session['local_db_dir'])
|
46
|
-
else
|
47
|
-
cmdline.push('--local-dir=' + session['local_dir'])
|
48
|
-
end
|
33
|
+
sync_admin = Aspera::SyncAdmin.new(@params, options.get_option(:sync_session))
|
49
34
|
command2 = options.get_next_command([:status])
|
50
35
|
case command2
|
51
36
|
when :status
|
52
|
-
|
53
|
-
|
54
|
-
items = stdout.split("\n").each_with_object({}){|l,m|i = l.split(/: */);m[i.first.lstrip] = i.last.lstrip;}
|
55
|
-
return {type: :single_object,data: items}
|
56
|
-
else raise 'error'
|
57
|
-
end # command
|
58
|
-
else raise 'error'
|
37
|
+
return {type: :single_object, data: sync_admin.status}
|
38
|
+
end # command2
|
59
39
|
end # command
|
60
40
|
end # execute_action
|
61
41
|
end # Sync
|