aspera-cli 4.5.0 → 4.8.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 +1 -0
- data/README.md +1894 -1574
- data/bin/ascli +21 -1
- data/bin/asession +38 -34
- data/docs/test_env.conf +14 -3
- data/examples/aoc.rb +17 -15
- data/examples/dascli +26 -0
- data/examples/faspex4.rb +42 -35
- data/examples/proxy.pac +1 -1
- data/examples/transfer.rb +38 -37
- data/lib/aspera/aoc.rb +245 -205
- data/lib/aspera/ascmd.rb +111 -90
- data/lib/aspera/ats_api.rb +16 -14
- data/lib/aspera/cli/basic_auth_plugin.rb +19 -18
- data/lib/aspera/cli/extended_value.rb +50 -39
- data/lib/aspera/cli/formater.rb +161 -135
- data/lib/aspera/cli/info.rb +18 -0
- data/lib/aspera/cli/listener/line_dump.rb +4 -2
- data/lib/aspera/cli/listener/logger.rb +3 -1
- data/lib/aspera/cli/listener/progress.rb +20 -21
- data/lib/aspera/cli/listener/progress_multi.rb +29 -31
- data/lib/aspera/cli/main.rb +194 -183
- data/lib/aspera/cli/manager.rb +213 -206
- data/lib/aspera/cli/plugin.rb +71 -49
- data/lib/aspera/cli/plugins/alee.rb +8 -7
- data/lib/aspera/cli/plugins/aoc.rb +675 -558
- data/lib/aspera/cli/plugins/ats.rb +116 -109
- data/lib/aspera/cli/plugins/bss.rb +35 -34
- data/lib/aspera/cli/plugins/config.rb +722 -542
- data/lib/aspera/cli/plugins/console.rb +28 -22
- data/lib/aspera/cli/plugins/cos.rb +28 -37
- data/lib/aspera/cli/plugins/faspex.rb +281 -227
- data/lib/aspera/cli/plugins/faspex5.rb +129 -84
- data/lib/aspera/cli/plugins/node.rb +426 -232
- data/lib/aspera/cli/plugins/orchestrator.rb +106 -98
- data/lib/aspera/cli/plugins/preview.rb +196 -191
- data/lib/aspera/cli/plugins/server.rb +131 -126
- data/lib/aspera/cli/plugins/shares.rb +49 -36
- data/lib/aspera/cli/plugins/sync.rb +27 -28
- data/lib/aspera/cli/transfer_agent.rb +84 -79
- data/lib/aspera/cli/version.rb +3 -1
- data/lib/aspera/colors.rb +37 -28
- data/lib/aspera/command_line_builder.rb +84 -63
- data/lib/aspera/cos_node.rb +68 -34
- data/lib/aspera/data_repository.rb +4 -2
- data/lib/aspera/environment.rb +61 -46
- data/lib/aspera/fasp/agent_base.rb +36 -31
- data/lib/aspera/fasp/agent_connect.rb +44 -37
- data/lib/aspera/fasp/agent_direct.rb +101 -104
- data/lib/aspera/fasp/agent_httpgw.rb +91 -90
- data/lib/aspera/fasp/agent_node.rb +36 -33
- data/lib/aspera/fasp/agent_trsdk.rb +28 -31
- data/lib/aspera/fasp/error.rb +3 -1
- data/lib/aspera/fasp/error_info.rb +81 -54
- data/lib/aspera/fasp/installation.rb +171 -151
- data/lib/aspera/fasp/listener.rb +2 -0
- data/lib/aspera/fasp/parameters.rb +105 -111
- data/lib/aspera/fasp/parameters.yaml +305 -249
- data/lib/aspera/fasp/resume_policy.rb +20 -20
- data/lib/aspera/fasp/transfer_spec.rb +27 -0
- data/lib/aspera/fasp/uri.rb +31 -29
- data/lib/aspera/faspex_gw.rb +95 -118
- data/lib/aspera/hash_ext.rb +12 -13
- data/lib/aspera/id_generator.rb +11 -9
- data/lib/aspera/keychain/encrypted_hash.rb +73 -57
- data/lib/aspera/keychain/macos_security.rb +27 -29
- data/lib/aspera/log.rb +40 -39
- data/lib/aspera/nagios.rb +24 -22
- data/lib/aspera/node.rb +38 -30
- data/lib/aspera/oauth.rb +217 -248
- data/lib/aspera/open_application.rb +9 -7
- data/lib/aspera/persistency_action_once.rb +15 -14
- data/lib/aspera/persistency_folder.rb +15 -18
- data/lib/aspera/preview/file_types.rb +266 -270
- data/lib/aspera/preview/generator.rb +94 -92
- data/lib/aspera/preview/image_error.png +0 -0
- data/lib/aspera/preview/options.rb +20 -17
- data/lib/aspera/preview/utils.rb +99 -102
- data/lib/aspera/preview/video_error.png +0 -0
- data/lib/aspera/{proxy_auto_config.erb.js → proxy_auto_config.js} +23 -31
- data/lib/aspera/proxy_auto_config.rb +114 -21
- data/lib/aspera/rest.rb +144 -142
- data/lib/aspera/rest_call_error.rb +3 -2
- data/lib/aspera/rest_error_analyzer.rb +31 -31
- data/lib/aspera/rest_errors_aspera.rb +18 -16
- data/lib/aspera/secret_hider.rb +68 -0
- data/lib/aspera/ssh.rb +20 -16
- data/lib/aspera/sync.rb +57 -54
- data/lib/aspera/temp_file_manager.rb +20 -14
- data/lib/aspera/timer_limiter.rb +10 -8
- data/lib/aspera/uri_reader.rb +14 -15
- data/lib/aspera/web_auth.rb +85 -80
- data.tar.gz.sig +0 -0
- metadata +169 -40
- metadata.gz.sig +2 -0
- data/bin/dascli +0 -13
- data/docs/Makefile +0 -63
- data/docs/README.erb.md +0 -4221
- data/docs/README.md +0 -13
- data/docs/diagrams.txt +0 -49
- data/docs/doc_tools.rb +0 -58
- data/lib/aspera/cli/plugins/shares2.rb +0 -114
- data/lib/aspera/fasp/default.rb +0 -17
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'aspera/cli/basic_auth_plugin'
|
2
4
|
require 'aspera/ascmd'
|
3
|
-
require 'aspera/fasp/
|
5
|
+
require 'aspera/fasp/transfer_spec'
|
4
6
|
require 'aspera/ssh'
|
5
7
|
require 'aspera/nagios'
|
6
8
|
require 'tempfile'
|
@@ -11,23 +13,24 @@ module Aspera
|
|
11
13
|
# implement basic remote access with FASP/SSH
|
12
14
|
class Server < BasicAuthPlugin
|
13
15
|
class LocalExecutor
|
14
|
-
def execute(cmd,
|
15
|
-
|
16
|
+
def execute(cmd,_input=nil)
|
17
|
+
Log.log.debug("Executing: #{cmd}")
|
18
|
+
%x(#{cmd.join(' ')})
|
16
19
|
end
|
17
20
|
end
|
18
21
|
|
19
22
|
def initialize(env)
|
20
23
|
super(env)
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
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.add_opt_simple(:cmd_prefix,'prefix to add for as cmd execution, e.g. sudo or /opt/aspera/bin ')
|
27
|
+
options.set_option(:ssh_keys,[])
|
28
|
+
options.set_option(:ssh_options,{})
|
29
|
+
options.parse_options!
|
27
30
|
end
|
28
31
|
|
29
32
|
def key_symb_to_str_single(source)
|
30
|
-
return source.
|
33
|
+
return source.each_with_object({}){|(k,v),memo| memo[k.to_s] = v; }
|
31
34
|
end
|
32
35
|
|
33
36
|
def key_symb_to_str_list(source)
|
@@ -35,135 +38,163 @@ module Aspera
|
|
35
38
|
end
|
36
39
|
|
37
40
|
def asctl_parse(text)
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
+
# normal separator
|
42
|
+
r = /:\s*/
|
43
|
+
result = []
|
44
|
+
text.split("\n").each do |line|
|
45
|
+
# console: missing space
|
41
46
|
line.gsub!(/(SessionDataCollector)/,'\1 ')
|
42
47
|
# orchestrator
|
43
48
|
line.gsub!(/ with pid:.*/,'')
|
44
49
|
line.gsub!(/ is /,': ')
|
45
|
-
|
46
|
-
next unless
|
47
|
-
|
50
|
+
items = line.split(r)
|
51
|
+
next unless items.length.eql?(2)
|
52
|
+
state = {'process' => items.first,'state' => items.last}
|
48
53
|
# console
|
49
|
-
|
54
|
+
state['state'].gsub!(/\.+$/,'')
|
50
55
|
# console
|
51
|
-
|
56
|
+
state['process'].gsub!(/^.+::/,'')
|
52
57
|
# faspex
|
53
|
-
|
58
|
+
state['process'].gsub!(/^Faspex /,'')
|
54
59
|
# faspex
|
55
|
-
|
56
|
-
|
60
|
+
state['process'].gsub!(/ Background/,'')
|
61
|
+
state['process'].gsub!(/serving orchestrator on port /,'')
|
57
62
|
# console
|
58
|
-
r
|
63
|
+
r = /\s+/ if state['process'].eql?('Console')
|
59
64
|
# orchestrator
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
end
|
65
|
+
state['process'].gsub!(/^ -> /,'')
|
66
|
+
state['process'].gsub!(/ Process/,'')
|
67
|
+
result.push(state)
|
68
|
+
end
|
69
|
+
return result
|
70
|
+
end
|
71
|
+
|
72
|
+
def asconfigurator_parse(result)
|
73
|
+
lines = result.split("\n")
|
74
|
+
# not windows
|
75
|
+
Log.log.debug(%x(type asconfigurator))
|
76
|
+
status=lines.shift
|
77
|
+
case status
|
78
|
+
when 'success'
|
79
|
+
result = []
|
80
|
+
lines.each do |line|
|
81
|
+
Log.log.debug(line.to_s)
|
82
|
+
# normalize values
|
83
|
+
data = line.
|
84
|
+
gsub(/^"/,'').
|
85
|
+
gsub(/,""$/,',"AS_EMPTY"').
|
86
|
+
gsub(/"$/,'').
|
87
|
+
split('","').
|
88
|
+
map{|i|case i;when 'AS_NULL' then nil;when 'AS_EMPTY' then '';when 'true' then true;when 'false' then false;else i;end}
|
89
|
+
data.insert(1,'') if data.length.eql?(4)
|
90
|
+
titles=%w[level section parameter value default]
|
91
|
+
result.push(titles.each_with_object({}){|t,o|o[t]=data.shift})
|
92
|
+
end
|
93
|
+
return result
|
94
|
+
when 'failure'
|
95
|
+
raise lines.join("\n")
|
96
|
+
else raise "Unexpected: #{status}"
|
97
|
+
end
|
64
98
|
end
|
65
99
|
|
66
|
-
ACTIONS=[
|
100
|
+
ACTIONS = %i[health nodeadmin userdata configurator ctl download upload browse delete rename].concat(Aspera::AsCmd::OPERATIONS).freeze
|
67
101
|
|
68
102
|
def execute_action
|
69
|
-
server_uri=URI.parse(
|
103
|
+
server_uri = URI.parse(options.get_option(:url,is_type: :mandatory))
|
70
104
|
Log.log.debug("URI : #{server_uri}, port=#{server_uri.port}, scheme:#{server_uri.scheme}")
|
71
|
-
server_transfer_spec={'remote_host'=>server_uri.hostname}
|
72
|
-
shell_executor=nil
|
105
|
+
server_transfer_spec = {'remote_host' => server_uri.hostname}
|
106
|
+
shell_executor = nil
|
73
107
|
case server_uri.scheme
|
74
|
-
when '
|
75
|
-
|
76
|
-
|
77
|
-
|
108
|
+
when 'local'
|
109
|
+
shell_executor = LocalExecutor.new
|
110
|
+
when 'https'
|
111
|
+
raise 'ERROR: transfer spec with token required' unless transfer.option_transfer_spec['token'].is_a?(String)
|
112
|
+
server_transfer_spec['wss_enabled'] = true
|
113
|
+
server_transfer_spec['wss_port'] = server_uri.port
|
114
|
+
else # when 'ssh'
|
115
|
+
Log.log.error("Scheme #{server_uri.scheme} not supported. Assuming SSH.") if !server_uri.scheme.eql?('ssh')
|
116
|
+
if options.get_option(:username).nil?
|
117
|
+
options.set_option(:username,Aspera::Fasp::TransferSpec::ACCESS_KEY_TRANSFER_USER)
|
118
|
+
Log.log.info("Using default transfer user: #{Aspera::Fasp::TransferSpec::ACCESS_KEY_TRANSFER_USER}")
|
78
119
|
end
|
79
|
-
server_transfer_spec['remote_user']=
|
80
|
-
ssh_options=
|
120
|
+
server_transfer_spec['remote_user'] = options.get_option(:username,is_type: :mandatory)
|
121
|
+
ssh_options = options.get_option(:ssh_options)
|
81
122
|
raise 'expecting a Hash for ssh_options' unless ssh_options.is_a?(Hash)
|
82
123
|
if !server_uri.port.nil?
|
83
|
-
ssh_options[:port]=server_uri.port
|
84
|
-
server_transfer_spec['ssh_port']=server_uri.port
|
124
|
+
ssh_options[:port] = server_uri.port
|
125
|
+
server_transfer_spec['ssh_port'] = server_uri.port
|
85
126
|
end
|
86
|
-
cred_set=false
|
87
|
-
password=
|
127
|
+
cred_set = false
|
128
|
+
password = options.get_option(:password)
|
88
129
|
if !password.nil?
|
89
|
-
ssh_options[:password]=password
|
90
|
-
server_transfer_spec['remote_password']=password
|
91
|
-
cred_set=true
|
130
|
+
ssh_options[:password] = password
|
131
|
+
server_transfer_spec['remote_password'] = password
|
132
|
+
cred_set = true
|
92
133
|
end
|
93
|
-
ssh_keys=
|
134
|
+
ssh_keys = options.get_option(:ssh_keys)
|
94
135
|
if !ssh_keys.nil?
|
95
|
-
raise 'expecting single value or array for ssh_keys' unless ssh_keys.is_a?(Array)
|
96
|
-
ssh_keys=[ssh_keys] if ssh_keys.is_a?(String)
|
136
|
+
raise 'expecting single value or array for ssh_keys' unless ssh_keys.is_a?(Array) || ssh_keys.is_a?(String)
|
137
|
+
ssh_keys = [ssh_keys] if ssh_keys.is_a?(String)
|
97
138
|
ssh_keys.map!{|p|File.expand_path(p)}
|
98
139
|
Log.log.debug("ssh keys=#{ssh_keys}")
|
99
140
|
if !ssh_keys.empty?
|
100
|
-
ssh_options[:keys]=ssh_keys
|
101
|
-
server_transfer_spec['EX_ssh_key_paths']=ssh_keys
|
141
|
+
ssh_options[:keys] = ssh_keys
|
142
|
+
server_transfer_spec['EX_ssh_key_paths'] = ssh_keys
|
102
143
|
ssh_keys.each do |k|
|
103
144
|
Log.log.warn("no such key file: #{k}") unless File.exist?(k)
|
104
145
|
end
|
105
|
-
cred_set=true
|
146
|
+
cred_set = true
|
106
147
|
end
|
107
148
|
end
|
108
149
|
# if user provided transfer spec has a token, we will use by pass keys
|
109
|
-
cred_set=true if
|
150
|
+
cred_set = true if transfer.option_transfer_spec['token'].is_a?(String)
|
110
151
|
raise 'either password, key , or transfer spec token must be provided' if !cred_set
|
111
|
-
shell_executor=Ssh.new(server_transfer_spec['remote_host'],server_transfer_spec['remote_user'],ssh_options)
|
112
|
-
when 'https'
|
113
|
-
raise "ERROR: transfer spec with token required" unless self.transfer.option_transfer_spec['token'].is_a?(String)
|
114
|
-
server_transfer_spec.merge!({
|
115
|
-
'wss_enabled'=>true,
|
116
|
-
'wss_port' =>server_uri.port
|
117
|
-
})
|
118
|
-
when 'local'
|
119
|
-
shell_executor=LocalExecutor.new
|
120
|
-
else
|
121
|
-
raise CliError,'Only ssh scheme is supported in url' if !server_uri.scheme.eql?('ssh')
|
152
|
+
shell_executor = Ssh.new(server_transfer_spec['remote_host'],server_transfer_spec['remote_user'],ssh_options)
|
122
153
|
end
|
123
154
|
|
124
155
|
# get command and set aliases
|
125
|
-
command=
|
126
|
-
command
|
127
|
-
command
|
128
|
-
command
|
156
|
+
command = options.get_next_command(ACTIONS)
|
157
|
+
command = :ls if command.eql?(:browse)
|
158
|
+
command = :rm if command.eql?(:delete)
|
159
|
+
command = :mv if command.eql?(:rename)
|
129
160
|
case command
|
130
161
|
when :health
|
131
|
-
nagios=Nagios.new
|
132
|
-
command_nagios=
|
162
|
+
nagios = Nagios.new
|
163
|
+
command_nagios = options.get_next_command(%i[app_services transfer asctlstatus])
|
133
164
|
case command_nagios
|
134
165
|
when :app_services
|
135
166
|
# will not work with aspshell, requires Linux/bash
|
136
|
-
procs=shell_executor.execute('ps -A -o comm').split("\n")
|
167
|
+
procs = shell_executor.execute('ps -A -o comm').split("\n")
|
137
168
|
Log.log.debug("found: #{procs}")
|
138
|
-
[
|
169
|
+
%w[asperanoded asperaredisd].each do |name|
|
139
170
|
nagios.add_critical('general',"missing process #{name}") unless procs.include?(name)
|
140
171
|
end
|
141
172
|
nagios.add_ok('daemons','ok') if nagios.data.empty?
|
142
173
|
return nagios.result
|
143
174
|
when :transfer
|
144
175
|
file = Tempfile.new('transfer_test')
|
145
|
-
filepath=file.path
|
146
|
-
file.write(
|
176
|
+
filepath = file.path
|
177
|
+
file.write('This is a test file for transfer test')
|
147
178
|
file.close
|
148
|
-
probe_ts=server_transfer_spec.merge({
|
179
|
+
probe_ts = server_transfer_spec.merge({
|
149
180
|
'direction' => 'send',
|
150
181
|
'cookie' => 'aspera.sync', # hide in console
|
151
182
|
'resume_policy' => 'none',
|
152
|
-
'paths' => [{'source'=>filepath,'destination'=>'.fasping'}]
|
183
|
+
'paths' => [{'source' => filepath,'destination' => '.fasping'}]
|
153
184
|
})
|
154
|
-
statuses=
|
185
|
+
statuses = transfer.start(probe_ts,{src: :direct})
|
155
186
|
file.unlink
|
156
187
|
if TransferAgent.session_status(statuses).eql?(:success)
|
157
188
|
nagios.add_ok('transfer','ok')
|
158
189
|
else
|
159
|
-
nagios.add_critical('transfer',statuses.
|
190
|
+
nagios.add_critical('transfer',statuses.reject{|i|i.eql?(:success)}.first.to_s)
|
160
191
|
end
|
161
192
|
when :asctlstatus
|
162
|
-
realcmd='asctl'
|
163
|
-
prefix=
|
164
|
-
realcmd="#{prefix}#{realcmd} all:status" unless prefix.nil?
|
165
|
-
result=shell_executor.execute(realcmd.split
|
166
|
-
data=asctl_parse(result)
|
193
|
+
realcmd = 'asctl'
|
194
|
+
prefix = options.get_option(:cmd_prefix)
|
195
|
+
realcmd = "#{prefix}#{realcmd} all:status" unless prefix.nil?
|
196
|
+
result = shell_executor.execute(realcmd.split)
|
197
|
+
data = asctl_parse(result)
|
167
198
|
data.each do |i|
|
168
199
|
if i['state'].eql?('running')
|
169
200
|
nagios.add_ok(i['process'],i['state'])
|
@@ -171,69 +202,43 @@ module Aspera
|
|
171
202
|
nagios.add_critical(i['process'],i['state'])
|
172
203
|
end
|
173
204
|
end
|
174
|
-
else raise
|
205
|
+
else raise 'ERROR'
|
175
206
|
end
|
176
207
|
return nagios.result
|
177
208
|
when :nodeadmin,:userdata,:configurator,:ctl
|
178
|
-
realcmd=
|
179
|
-
prefix=
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
result=shell_executor.execute(args.unshift(realcmd))
|
209
|
+
realcmd = "as#{command}"
|
210
|
+
prefix = options.get_option(:cmd_prefix)
|
211
|
+
realcmd = "#{prefix}#{realcmd}" unless prefix.nil?
|
212
|
+
args = options.get_next_argument("#{realcmd} arguments",expected: :multiple)
|
213
|
+
args.unshift('-x') if command.eql?(:configurator)
|
214
|
+
result = shell_executor.execute(args.unshift(realcmd))
|
185
215
|
case command
|
186
216
|
when :ctl
|
187
|
-
return {:
|
217
|
+
return {type: :object_list,data: asctl_parse(result)}
|
188
218
|
when :configurator
|
189
|
-
|
190
|
-
|
191
|
-
result=lines
|
192
|
-
if lines.first.eql?('success')
|
193
|
-
lines.shift
|
194
|
-
result={}
|
195
|
-
lines.each do |line|
|
196
|
-
Log.log.debug("#{line}")
|
197
|
-
data=line.split(',').map{|i|i.gsub(/^"/,'').gsub(/"$/,'')}.map{|i|case i;when'AS_NULL';nil;when'true';true;when'false';false;else i;end}
|
198
|
-
Log.log.debug("#{data}")
|
199
|
-
section=data.shift
|
200
|
-
datapart=result[section]||={}
|
201
|
-
if section.eql?('user')
|
202
|
-
name=data.shift
|
203
|
-
datapart=datapart[name]||={}
|
204
|
-
end
|
205
|
-
datapart=datapart[data.shift]={}
|
206
|
-
datapart['default']=data.pop
|
207
|
-
datapart['value']=data.pop
|
208
|
-
end
|
209
|
-
return {:type=>:single_object,:data=>result,:fields=>['section','name','value','default'],:option_expand_last=>true}
|
210
|
-
end
|
219
|
+
result=asconfigurator_parse(result)
|
220
|
+
return {type: :object_list,data: result} # ,option_expand_last: true
|
211
221
|
end
|
212
222
|
return Main.result_status(result)
|
213
223
|
when :upload
|
214
|
-
return Main.result_transfer(
|
224
|
+
return Main.result_transfer(transfer.start(server_transfer_spec.merge('direction' => Fasp::TransferSpec::DIRECTION_SEND),{src: :direct}))
|
215
225
|
when :download
|
216
|
-
return Main.result_transfer(
|
226
|
+
return Main.result_transfer(transfer.start(server_transfer_spec.merge('direction' => Fasp::TransferSpec::DIRECTION_RECEIVE),{src: :direct}))
|
217
227
|
when *Aspera::AsCmd::OPERATIONS
|
218
|
-
args=
|
219
|
-
ascmd=Aspera::AsCmd.new(shell_executor)
|
228
|
+
args = options.get_next_argument('ascmd command arguments',expected: :multiple,mandatory: false)
|
229
|
+
ascmd = Aspera::AsCmd.new(shell_executor)
|
220
230
|
begin
|
221
|
-
result=ascmd.send(:execute_single,command,args)
|
231
|
+
result = ascmd.send(:execute_single,command,args)
|
222
232
|
case command
|
223
|
-
when :mkdir
|
224
|
-
when :
|
225
|
-
when :
|
226
|
-
when :
|
227
|
-
when :ls; return {:type=>:object_list,:data=>key_symb_to_str_list(result),:fields=>['zmode','zuid','zgid','size','mtime','name']}
|
228
|
-
when :info; return {:type=>:single_object,:data=>key_symb_to_str_single(result)}
|
229
|
-
when :df; return {:type=>:object_list,:data=>key_symb_to_str_list(result)}
|
230
|
-
when :du; return {:type=>:single_object,:data=>key_symb_to_str_single(result)}
|
231
|
-
when :md5sum; return {:type=>:single_object,:data=>key_symb_to_str_single(result)}
|
233
|
+
when :mkdir,:mv,:cp,:rm then return Main.result_success
|
234
|
+
when :ls then return {type: :object_list,data: key_symb_to_str_list(result),fields: %w[zmode zuid zgid size mtime name]}
|
235
|
+
when :df then return {type: :object_list,data: key_symb_to_str_list(result)}
|
236
|
+
when :du,:md5sum,:info then return {type: :single_object,data: key_symb_to_str_single(result)}
|
232
237
|
end
|
233
238
|
rescue Aspera::AsCmd::Error => e
|
234
239
|
raise CliBadArgument,e.extended_message
|
235
240
|
end
|
236
|
-
else raise
|
241
|
+
else raise 'internal error: unexpected action'
|
237
242
|
end
|
238
243
|
end # execute_action
|
239
244
|
end # Server
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'aspera/cli/plugins/node'
|
2
4
|
|
3
5
|
module Aspera
|
@@ -6,70 +8,81 @@ module Aspera
|
|
6
8
|
class Shares < BasicAuthPlugin
|
7
9
|
class << self
|
8
10
|
def detect(base_url)
|
9
|
-
api=Rest.new({:base_url
|
11
|
+
api = Rest.new({base_url: base_url})
|
10
12
|
# Shares
|
11
13
|
begin
|
12
14
|
# shall fail: shares requires auth, but we check error message
|
13
15
|
api.read('node_api/app')
|
14
16
|
rescue RestCallError => e
|
15
|
-
if e.response.code.to_s.eql?('401')
|
16
|
-
return {:
|
17
|
+
if e.response.code.to_s.eql?('401') && e.response.body.eql?('{"error":{"user_message":"API user authentication failed"}}')
|
18
|
+
return {version: 'unknown'}
|
17
19
|
end
|
18
|
-
rescue
|
19
20
|
end
|
20
21
|
nil
|
21
22
|
end
|
22
23
|
end
|
23
24
|
|
24
|
-
def initialize(env)
|
25
|
-
super(env)
|
26
|
-
|
27
|
-
end
|
25
|
+
# def initialize(env)
|
26
|
+
# super(env)
|
27
|
+
# end
|
28
28
|
|
29
|
-
ACTIONS=[
|
29
|
+
ACTIONS = %i[health repository admin].freeze
|
30
30
|
|
31
31
|
def execute_action
|
32
|
-
command=
|
32
|
+
command = options.get_next_command(ACTIONS)
|
33
33
|
case command
|
34
|
+
when :health
|
35
|
+
nagios = Nagios.new
|
36
|
+
begin
|
37
|
+
Rest.
|
38
|
+
new(base_url: options.get_option(:url,is_type: :mandatory)+'/node_api').
|
39
|
+
call(
|
40
|
+
operation: 'GET',
|
41
|
+
subpath: 'ping',
|
42
|
+
headers: {'content-type': 'application/json'},
|
43
|
+
return_error: true)
|
44
|
+
nagios.add_ok('shares api','accessible')
|
45
|
+
rescue StandardError => e
|
46
|
+
nagios.add_critical('node api',e.to_s)
|
47
|
+
end
|
48
|
+
return nagios.result
|
34
49
|
when :repository
|
35
|
-
api_shares_node=basic_auth_api('node_api')
|
36
|
-
command=
|
50
|
+
api_shares_node = basic_auth_api('node_api')
|
51
|
+
command = options.get_next_command(Node::COMMON_ACTIONS)
|
37
52
|
case command
|
38
|
-
when *Node::COMMON_ACTIONS
|
53
|
+
when *Node::COMMON_ACTIONS then Node.new(@agents.merge(skip_basic_auth_options: true,node_api: api_shares_node)).execute_action(command)
|
39
54
|
else raise "INTERNAL ERROR, unknown command: [#{command}]"
|
40
55
|
end
|
41
56
|
when :admin
|
42
|
-
api_shares_admin=basic_auth_api('api/v1')
|
43
|
-
command=
|
57
|
+
api_shares_admin = basic_auth_api('api/v1')
|
58
|
+
command = options.get_next_command(%i[user share])
|
44
59
|
case command
|
45
60
|
when :user
|
46
|
-
command=
|
61
|
+
command = options.get_next_command(%i[list app_authorizations share_permissions])
|
62
|
+
user_id = instance_identifier if %i[app_authorizations share_permissions].include?(command)
|
47
63
|
case command
|
48
64
|
when :list
|
49
|
-
return {:
|
50
|
-
when :
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
share_name=self.options.get_next_argument('share name')
|
58
|
-
all_shares=api_shares_admin.read('data/shares')[:data]
|
59
|
-
share_id=all_shares.select{|s| s['name'].eql?(share_name)}.first['id']
|
60
|
-
return {:type=>:single_object,:data=>api_shares_admin.create("data/shares/#{share_id}/user_permissions")[:data]}
|
61
|
-
end
|
65
|
+
return {type: :object_list,data: api_shares_admin.read('data/users')[:data],fields: %w[id username email directory_user urn]}
|
66
|
+
when :app_authorizations
|
67
|
+
return {type: :single_object,data: api_shares_admin.read("data/users/#{user_id}/app_authorizations")[:data]}
|
68
|
+
when :share_permissions
|
69
|
+
#share_name = options.get_next_argument('share name')
|
70
|
+
#all_shares = api_shares_admin.read('data/shares')[:data]
|
71
|
+
#share_id = all_shares.find{|s| s['name'].eql?(share_name)}['id']
|
72
|
+
return {type: :object_list,data: api_shares_admin.read("data/users/#{user_id}/share_permissions")[:data]}
|
62
73
|
end
|
63
74
|
when :share
|
64
|
-
command=
|
65
|
-
|
75
|
+
command = options.get_next_command(%i[list user_permissions])
|
76
|
+
share_id = instance_identifier if %i[user_permissions].include?(command)
|
77
|
+
all_shares = api_shares_admin.read('data/shares')[:data]
|
66
78
|
case command
|
67
79
|
when :list
|
68
|
-
return {:
|
69
|
-
when :
|
70
|
-
share_name=
|
71
|
-
share_id=all_shares.
|
72
|
-
raise "
|
80
|
+
return {type: :object_list,data: all_shares,fields: %w[id name status status_message]}
|
81
|
+
when :user_permissions
|
82
|
+
#share_name = options.get_next_argument('share name')
|
83
|
+
#share_id = all_shares.find{|s| s['name'].eql?(share_name)}['id']
|
84
|
+
#raise "NOT IMPLEMENTED: #{share_name} #{share_id}"
|
85
|
+
return {type: :object_list,data: api_shares_admin.read("data/shares/#{share_id}/user_permissions")[:data]}
|
73
86
|
end
|
74
87
|
end
|
75
88
|
end
|
@@ -1,3 +1,6 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'English'
|
1
4
|
require 'aspera/cli/plugin'
|
2
5
|
require 'aspera/sync'
|
3
6
|
require 'aspera/log'
|
@@ -10,53 +13,49 @@ module Aspera
|
|
10
13
|
class Sync < Plugin
|
11
14
|
def initialize(env)
|
12
15
|
super(env)
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
+
options.add_opt_simple(:parameters,'extended value for session set definition')
|
17
|
+
options.add_opt_simple(:session_name,'name of session to use for admin commands, by default first one')
|
18
|
+
options.parse_options!
|
16
19
|
end
|
17
20
|
|
18
|
-
ACTIONS=[
|
21
|
+
ACTIONS = %i[start admin].freeze
|
19
22
|
|
20
23
|
def execute_action
|
21
|
-
command=
|
24
|
+
command = options.get_next_command(ACTIONS)
|
22
25
|
case command
|
23
26
|
when :start
|
24
|
-
env_args=Aspera::Sync.new(
|
25
|
-
async_bin='async'
|
27
|
+
env_args = Aspera::Sync.new(options.get_option(:parameters,is_type: :mandatory)).compute_args
|
28
|
+
async_bin = 'async'
|
26
29
|
Log.log.debug("execute: #{env_args[:env].map{|k,v| "#{k}=\"#{v}\""}.join(' ')} \"#{async_bin}\" \"#{env_args[:args].join('" "')}\"")
|
27
|
-
res=system(env_args[:env],[async_bin,async_bin],*env_args[:args])
|
30
|
+
res = system(env_args[:env],[async_bin,async_bin],*env_args[:args])
|
28
31
|
Log.log.debug("result=#{res}")
|
29
32
|
case res
|
30
|
-
when true
|
31
|
-
when false
|
32
|
-
when nil
|
33
|
-
else raise
|
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'
|
34
37
|
end
|
35
38
|
when :admin
|
36
|
-
p=
|
37
|
-
n=
|
38
|
-
cmdline=['asyncadmin','--quiet']
|
39
|
-
|
40
|
-
|
41
|
-
else
|
42
|
-
session=p['sessions'].select{|s|s['name'].eql?(n)}.first
|
43
|
-
end
|
44
|
-
cmdline.push('--name='+session['name'])
|
39
|
+
p = options.get_option(:parameters,is_type: :mandatory)
|
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'])
|
45
44
|
if session.has_key?('local_db_dir')
|
46
|
-
cmdline.push('--local-db-dir='+session['local_db_dir'])
|
45
|
+
cmdline.push('--local-db-dir=' + session['local_db_dir'])
|
47
46
|
else
|
48
|
-
cmdline.push('--local-dir='+session['local_dir'])
|
47
|
+
cmdline.push('--local-dir=' + session['local_dir'])
|
49
48
|
end
|
50
|
-
command2=
|
49
|
+
command2 = options.get_next_command([:status])
|
51
50
|
case command2
|
52
51
|
when :status
|
53
52
|
stdout, stderr, status = Open3.capture3(*cmdline)
|
54
53
|
Log.log.debug("status=#{status}, stderr=#{stderr}")
|
55
|
-
items=stdout.split("\n").
|
56
|
-
return {:
|
57
|
-
else raise
|
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'
|
58
57
|
end # command
|
59
|
-
else raise
|
58
|
+
else raise 'error'
|
60
59
|
end # command
|
61
60
|
end # execute_action
|
62
61
|
end # Sync
|