aspera-cli 4.4.0 → 4.7.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.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2095 -1503
  3. data/bin/ascli +2 -1
  4. data/bin/asession +4 -5
  5. data/docs/test_env.conf +3 -0
  6. data/examples/aoc.rb +4 -3
  7. data/examples/faspex4.rb +25 -25
  8. data/examples/proxy.pac +1 -1
  9. data/examples/transfer.rb +17 -17
  10. data/lib/aspera/aoc.rb +238 -185
  11. data/lib/aspera/ascmd.rb +93 -83
  12. data/lib/aspera/ats_api.rb +11 -10
  13. data/lib/aspera/cli/basic_auth_plugin.rb +13 -14
  14. data/lib/aspera/cli/extended_value.rb +42 -33
  15. data/lib/aspera/cli/formater.rb +142 -108
  16. data/lib/aspera/cli/info.rb +17 -0
  17. data/lib/aspera/cli/listener/line_dump.rb +3 -2
  18. data/lib/aspera/cli/listener/logger.rb +2 -1
  19. data/lib/aspera/cli/listener/progress.rb +16 -18
  20. data/lib/aspera/cli/listener/progress_multi.rb +18 -21
  21. data/lib/aspera/cli/main.rb +173 -149
  22. data/lib/aspera/cli/manager.rb +163 -168
  23. data/lib/aspera/cli/plugin.rb +43 -31
  24. data/lib/aspera/cli/plugins/alee.rb +6 -6
  25. data/lib/aspera/cli/plugins/aoc.rb +405 -370
  26. data/lib/aspera/cli/plugins/ats.rb +86 -79
  27. data/lib/aspera/cli/plugins/bss.rb +14 -16
  28. data/lib/aspera/cli/plugins/config.rb +580 -362
  29. data/lib/aspera/cli/plugins/console.rb +23 -19
  30. data/lib/aspera/cli/plugins/cos.rb +18 -18
  31. data/lib/aspera/cli/plugins/faspex.rb +201 -158
  32. data/lib/aspera/cli/plugins/faspex5.rb +80 -57
  33. data/lib/aspera/cli/plugins/node.rb +183 -166
  34. data/lib/aspera/cli/plugins/orchestrator.rb +71 -67
  35. data/lib/aspera/cli/plugins/preview.rb +92 -96
  36. data/lib/aspera/cli/plugins/server.rb +79 -75
  37. data/lib/aspera/cli/plugins/shares.rb +35 -19
  38. data/lib/aspera/cli/plugins/sync.rb +20 -22
  39. data/lib/aspera/cli/transfer_agent.rb +76 -113
  40. data/lib/aspera/cli/version.rb +2 -1
  41. data/lib/aspera/colors.rb +35 -27
  42. data/lib/aspera/command_line_builder.rb +48 -34
  43. data/lib/aspera/cos_node.rb +29 -21
  44. data/lib/aspera/data_repository.rb +3 -2
  45. data/lib/aspera/environment.rb +50 -45
  46. data/lib/aspera/fasp/{manager.rb → agent_base.rb} +28 -25
  47. data/lib/aspera/fasp/{connect.rb → agent_connect.rb} +52 -43
  48. data/lib/aspera/fasp/{local.rb → agent_direct.rb} +58 -72
  49. data/lib/aspera/fasp/{http_gw.rb → agent_httpgw.rb} +37 -43
  50. data/lib/aspera/fasp/{node.rb → agent_node.rb} +35 -16
  51. data/lib/aspera/fasp/agent_trsdk.rb +104 -0
  52. data/lib/aspera/fasp/error.rb +2 -1
  53. data/lib/aspera/fasp/error_info.rb +68 -52
  54. data/lib/aspera/fasp/installation.rb +152 -124
  55. data/lib/aspera/fasp/listener.rb +1 -0
  56. data/lib/aspera/fasp/parameters.rb +87 -92
  57. data/lib/aspera/fasp/parameters.yaml +305 -249
  58. data/lib/aspera/fasp/resume_policy.rb +11 -14
  59. data/lib/aspera/fasp/transfer_spec.rb +26 -0
  60. data/lib/aspera/fasp/uri.rb +22 -21
  61. data/lib/aspera/faspex_gw.rb +55 -89
  62. data/lib/aspera/hash_ext.rb +4 -3
  63. data/lib/aspera/id_generator.rb +8 -7
  64. data/lib/aspera/keychain/encrypted_hash.rb +121 -0
  65. data/lib/aspera/keychain/macos_security.rb +90 -0
  66. data/lib/aspera/log.rb +55 -37
  67. data/lib/aspera/nagios.rb +13 -12
  68. data/lib/aspera/node.rb +30 -25
  69. data/lib/aspera/oauth.rb +175 -226
  70. data/lib/aspera/open_application.rb +4 -3
  71. data/lib/aspera/persistency_action_once.rb +6 -6
  72. data/lib/aspera/persistency_folder.rb +5 -9
  73. data/lib/aspera/preview/file_types.rb +6 -5
  74. data/lib/aspera/preview/generator.rb +25 -24
  75. data/lib/aspera/preview/options.rb +16 -14
  76. data/lib/aspera/preview/utils.rb +98 -98
  77. data/lib/aspera/{proxy_auto_config.erb.js → proxy_auto_config.js} +23 -31
  78. data/lib/aspera/proxy_auto_config.rb +111 -20
  79. data/lib/aspera/rest.rb +154 -135
  80. data/lib/aspera/rest_call_error.rb +2 -2
  81. data/lib/aspera/rest_error_analyzer.rb +23 -25
  82. data/lib/aspera/rest_errors_aspera.rb +15 -14
  83. data/lib/aspera/ssh.rb +12 -10
  84. data/lib/aspera/sync.rb +42 -41
  85. data/lib/aspera/temp_file_manager.rb +18 -14
  86. data/lib/aspera/timer_limiter.rb +2 -1
  87. data/lib/aspera/uri_reader.rb +7 -5
  88. data/lib/aspera/web_auth.rb +79 -76
  89. metadata +116 -29
  90. data/docs/Makefile +0 -66
  91. data/docs/README.erb.md +0 -3973
  92. data/docs/README.md +0 -13
  93. data/docs/diagrams.txt +0 -49
  94. data/docs/doc_tools.rb +0 -58
  95. data/lib/aspera/api_detector.rb +0 -60
  96. data/lib/aspera/cli/plugins/shares2.rb +0 -114
  97. data/lib/aspera/secrets.rb +0 -20
@@ -1,7 +1,10 @@
1
+ # frozen_string_literal: true
1
2
  require 'aspera/cli/basic_auth_plugin'
2
3
  require 'aspera/nagios'
3
4
  require 'aspera/hash_ext'
4
5
  require 'aspera/id_generator'
6
+ require 'aspera/node'
7
+ require 'aspera/fasp/transfer_spec'
5
8
  require 'base64'
6
9
  require 'zlib'
7
10
 
@@ -9,38 +12,46 @@ module Aspera
9
12
  module Cli
10
13
  module Plugins
11
14
  class Node < BasicAuthPlugin
15
+ class << self
16
+ def detect(base_url)
17
+ api=Rest.new({ base_url: base_url})
18
+ result=api.call({ operation: 'GET', subpath: 'ping'})
19
+ if result[:http].body.eql?('')
20
+ return { product: :node, version: 'unknown'}
21
+ end
22
+ return nil
23
+ end
24
+ end
12
25
  SAMPLE_SOAP_CALL='<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:typ="urn:Aspera:XML:FASPSessionNET:2009/11:Types"><soapenv:Header></soapenv:Header><soapenv:Body><typ:GetSessionInfoRequest><SessionFilter><SessionStatus>running</SessionStatus></SessionFilter></typ:GetSessionInfoRequest></soapenv:Body></soapenv:Envelope>'
13
26
  private_constant :SAMPLE_SOAP_CALL
27
+
14
28
  def initialize(env)
15
29
  super(env)
16
30
  # this is added to some requests , for instance to add tags (COS)
17
31
  @add_request_param = env[:add_request_param] || {}
18
- unless env[:skip_basic_auth_options]
19
- self.options.add_opt_simple(:validator,"identifier of validator (optional for central)")
20
- self.options.add_opt_simple(:asperabrowserurl,"URL for simple aspera web ui")
21
- self.options.add_opt_simple(:name,"sync name")
22
- self.options.add_opt_list(:token_type,[:aspera,:basic,:hybrid],'Type of token used for transfers')
23
- self.options.set_option(:asperabrowserurl,'https://asperabrowser.mybluemix.net')
24
- self.options.set_option(:token_type,:aspera)
25
- self.options.parse_options!
26
- end
32
+ options.add_opt_simple(:validator,'identifier of validator (optional for central)')
33
+ options.add_opt_simple(:asperabrowserurl,'URL for simple aspera web ui')
34
+ options.add_opt_simple(:sync_name,'sync name')
35
+ options.add_opt_list(:token_type,[:aspera,:basic,:hybrid],'Type of token used for transfers')
36
+ options.set_option(:asperabrowserurl,'https://asperabrowser.mybluemix.net')
37
+ options.set_option(:token_type,:aspera)
38
+ options.parse_options!
27
39
  return if env[:man_only]
40
+ @api_node=
28
41
  if env.has_key?(:node_api)
29
- @api_node=env[:node_api]
42
+ env[:node_api]
43
+ elsif options.get_option(:password,:mandatory).start_with?('Bearer ')
44
+ # info is provided like node_info of aoc
45
+ Rest.new({
46
+ base_url: options.get_option(:url,:mandatory),
47
+ headers: {
48
+ 'Authorization' => options.get_option(:password,:mandatory),
49
+ 'X-Aspera-AccessKey' => options.get_option(:username,:mandatory)
50
+ }
51
+ })
30
52
  else
31
- if self.options.get_option(:password,:mandatory).start_with?('Bearer ')
32
- # info is provided like node_info of aoc
33
- @api_node=Rest.new({
34
- base_url: self.options.get_option(:url,:mandatory),
35
- headers: {
36
- 'Authorization' => self.options.get_option(:password,:mandatory),
37
- 'X-Aspera-AccessKey' => self.options.get_option(:username,:mandatory),
38
- }
39
- })
40
- else
41
- # this is normal case
42
- @api_node=basic_auth_api
43
- end
53
+ # this is normal case
54
+ basic_auth_api
44
55
  end
45
56
  end
46
57
 
@@ -51,14 +62,13 @@ module Aspera
51
62
  # key/value is defined in main in hash_table
52
63
  def c_textify_bool_list_result(list,name_list)
53
64
  list.each_index do |i|
54
- if name_list.include?(list[i]['key'])
55
- list[i]['value'].each do |item|
56
- list.push({'key'=>item['name'],'value'=>item['value']})
57
- end
58
- list.delete_at(i)
59
- # continue at same index because we delete current one
60
- redo
65
+ next unless name_list.include?(list[i]['key'])
66
+ list[i]['value'].each do |item|
67
+ list.push({'key'=>item['name'],'value'=>item['value']})
61
68
  end
69
+ list.delete_at(i)
70
+ # continue at same index because we delete current one
71
+ redo
62
72
  end
63
73
  end
64
74
 
@@ -68,11 +78,11 @@ module Aspera
68
78
  case result[:type]
69
79
  when :object_list
70
80
  result[:data].each do |item|
71
- item[column].replace(item[column][path_prefix.length..-1]) if item[column].start_with?(path_prefix)
81
+ item[column]=item[column][path_prefix.length..-1] if item[column].start_with?(path_prefix)
72
82
  end
73
83
  when :single_object
74
84
  item=result[:data]
75
- item[column].replace(item[column][path_prefix.length..-1]) if item[column].start_with?(path_prefix)
85
+ item[column]=item[column][path_prefix.length..-1] if item[column].start_with?(path_prefix)
76
86
  end
77
87
  end
78
88
  return result
@@ -80,12 +90,12 @@ module Aspera
80
90
 
81
91
  # translates paths results into CLI result, and removes prefix
82
92
  def c_result_translate_rem_prefix(resp,type,success_msg,path_prefix)
83
- resres={:data=>[],:type=>:object_list,:fields=>[type,'result']}
93
+ resres={ data: [], type: :object_list, fields: [type,'result']}
84
94
  JSON.parse(resp[:http].body)['paths'].each do |p|
85
95
  result=success_msg
86
96
  if p.has_key?('error')
87
97
  Log.log.error("#{p['error']['user_message']} : #{p['path']}")
88
- result="ERROR: "+p['error']['user_message']
98
+ result='ERROR: '+p['error']['user_message']
89
99
  end
90
100
  resres[:data].push({type=>p['path'],'result'=>result})
91
101
  end
@@ -94,16 +104,16 @@ module Aspera
94
104
 
95
105
  # get path arguments from command line, and add prefix
96
106
  def get_next_arg_add_prefix(path_prefix,name,number=:single)
97
- thepath=self.options.get_next_argument(name,number)
107
+ thepath=options.get_next_argument(name,number)
98
108
  return thepath if path_prefix.nil?
99
109
  return File.join(path_prefix,thepath) if thepath.is_a?(String)
100
110
  return thepath.map {|p| File.join(path_prefix,p)} if thepath.is_a?(Array)
101
- raise StandardError,"expect: nil, String or Array"
111
+ raise StandardError,'expect: nil, String or Array'
102
112
  end
103
113
 
104
- SIMPLE_ACTIONS=[:health,:events, :space, :info, :license, :mkdir, :mklink, :mkfile, :rename, :delete, :search ]
114
+ SIMPLE_ACTIONS=[:health,:events, :space, :info, :license, :mkdir, :mklink, :mkfile, :rename, :delete, :search]
105
115
 
106
- COMMON_ACTIONS=[:browse, :upload, :download, :api_details ].concat(SIMPLE_ACTIONS)
116
+ COMMON_ACTIONS=[:browse, :upload, :download, :api_details].concat(SIMPLE_ACTIONS)
107
117
 
108
118
  # common API to node and Shares
109
119
  # prefix_path is used to list remote sources in Faspex
@@ -115,137 +125,146 @@ module Aspera
115
125
  info=@api_node.read('info')[:data]
116
126
  nagios.add_ok('node api','accessible')
117
127
  nagios.check_time_offset(info['current_time'],'node api')
118
- nagios.check_product_version( 'node api','entsrv', info['version'])
119
- rescue => e
128
+ nagios.check_product_version('node api','entsrv', info['version'])
129
+ rescue StandardError => e
120
130
  nagios.add_critical('node api',e.to_s)
121
131
  end
122
132
  begin
123
- @api_node.call({:operation=>'POST',:subpath=>'services/soap/Transfer-201210',:headers=>{'Content-Type'=>'text/xml;charset=UTF-8','SOAPAction'=>'FASPSessionNET-200911#GetSessionInfo'},:text_body_params=>SAMPLE_SOAP_CALL})[:http].body
133
+ @api_node.call({ operation: 'POST', subpath: 'services/soap/Transfer-201210',
134
+ headers: {'Content-Type'=>'text/xml;charset=UTF-8','SOAPAction'=>'FASPSessionNET-200911#GetSessionInfo'}, text_body_params: SAMPLE_SOAP_CALL})[:http].body
124
135
  nagios.add_ok('central','accessible by node')
125
- rescue => e
136
+ rescue StandardError => e
126
137
  nagios.add_critical('central',e.to_s)
127
138
  end
128
139
  return nagios.result
129
140
  when :events
130
- events=@api_node.read('events',self.options.get_option(:value,:optional))[:data]
131
- return { :type=>:object_list, :data => events}
141
+ events=@api_node.read('events',options.get_option(:value,:optional))[:data]
142
+ return { type: :object_list, data: events}
132
143
  when :info
133
144
  node_info=@api_node.read('info')[:data]
134
- return { :type=>:single_object, :data => node_info, :textify => lambda { |table_data| c_textify_bool_list_result(table_data,['capabilities','settings'])}}
145
+ return { type: :single_object, data: node_info, textify: lambda { |table_data| c_textify_bool_list_result(table_data,['capabilities','settings'])}}
135
146
  when :license # requires: asnodeadmin -mu <node user> --acl-add=internal --internal
136
147
  node_license=@api_node.read('license')[:data]
137
- if node_license['failure'].is_a?(String) and node_license['failure'].include?('ACL')
138
- Log.log.error("server must have: asnodeadmin -mu <node user> --acl-add=internal --internal")
148
+ if node_license['failure'].is_a?(String) && node_license['failure'].include?('ACL')
149
+ Log.log.error('server must have: asnodeadmin -mu <node user> --acl-add=internal --internal')
139
150
  end
140
- return { :type=>:single_object, :data => node_license}
151
+ return { type: :single_object, data: node_license}
141
152
  when :delete
142
- paths_to_delete = get_next_arg_add_prefix(prefix_path,"file list",:multiple)
143
- resp=@api_node.create('files/delete',{:paths=>paths_to_delete.map{|i| {'path'=>i.start_with?('/') ? i : '/'+i} }})
153
+ paths_to_delete = get_next_arg_add_prefix(prefix_path,'file list',:multiple)
154
+ resp=@api_node.create('files/delete',{ paths: paths_to_delete.map{|i| {'path'=>i.start_with?('/') ? i : '/'+i} }})
144
155
  return c_result_translate_rem_prefix(resp,'file','deleted',prefix_path)
145
156
  when :search
146
- search_root = get_next_arg_add_prefix(prefix_path,"search root")
157
+ search_root = get_next_arg_add_prefix(prefix_path,'search root')
147
158
  parameters={'path'=>search_root}
148
- other_options=self.options.get_option(:value,:optional)
159
+ other_options=options.get_option(:value,:optional)
149
160
  parameters.merge!(other_options) unless other_options.nil?
150
161
  resp=@api_node.create('files/search',parameters)
151
- result={ :type=>:object_list, :data => resp[:data]['items']}
162
+ result={ type: :object_list, data: resp[:data]['items']}
152
163
  return Main.result_empty if result[:data].empty?
153
- result[:fields]=result[:data].first.keys.select{|i|!['basename','permissions'].include?(i)}
164
+ result[:fields]=result[:data].first.keys.reject{|i|['basename','permissions'].include?(i)}
154
165
  self.format.display_status("Items: #{resp[:data]['item_count']}/#{resp[:data]['total_count']}")
155
166
  self.format.display_status("params: #{resp[:data]['parameters'].keys.map{|k|"#{k}:#{resp[:data]['parameters'][k]}"}.join(',')}")
156
167
  return c_result_remove_prefix_path(result,'path',prefix_path)
157
168
  when :space
158
169
  # TODO: could be a list of path
159
- path_list=get_next_arg_add_prefix(prefix_path,"folder path or ext.val. list")
170
+ path_list=get_next_arg_add_prefix(prefix_path,'folder path or ext.val. list')
160
171
  path_list=[path_list] unless path_list.is_a?(Array)
161
- resp=@api_node.create('space',{ "paths" => path_list.map {|i| {:path=>i} } } )
162
- result={:data=>resp[:data]['paths'],:type=>:object_list}
172
+ resp=@api_node.create('space',{ 'paths' => path_list.map {|i| { path: i} } })
173
+ result={ data: resp[:data]['paths'], type: :object_list}
163
174
  #return c_result_translate_rem_prefix(resp,'folder','created',prefix_path)
164
175
  return c_result_remove_prefix_path(result,'path',prefix_path)
165
176
  when :mkdir
166
- path_list=get_next_arg_add_prefix(prefix_path,"folder path or ext.val. list")
177
+ path_list=get_next_arg_add_prefix(prefix_path,'folder path or ext.val. list')
167
178
  path_list=[path_list] unless path_list.is_a?(Array)
168
- #TODO
169
- #resp=@api_node.create('space',{ "paths" => path_list.map {|i| {:type=>:directory,:path=>i} } } )
170
- resp=@api_node.create('files/create',{ "paths" => [{ :type => :directory, :path => path_list } ] } )
179
+ #TODO: a command for that ?
180
+ #resp=@api_node.create('space',{ "paths" => path_list.map {|i| { type: :directory, path: i} } } )
181
+ resp=@api_node.create('files/create',{ 'paths' => [{ type: :directory, path: path_list }] })
171
182
  return c_result_translate_rem_prefix(resp,'folder','created',prefix_path)
172
183
  when :mklink
173
- target=get_next_arg_add_prefix(prefix_path,"target")
174
- path_list=get_next_arg_add_prefix(prefix_path,"link path")
175
- resp=@api_node.create('files/create',{ "paths" => [{ :type => :symbolic_link, :path => path_list, :target => {:path => target} } ] } )
184
+ target=get_next_arg_add_prefix(prefix_path,'target')
185
+ path_list=get_next_arg_add_prefix(prefix_path,'link path')
186
+ resp=@api_node.create('files/create',{ 'paths' => [{ type: :symbolic_link, path: path_list, target: { path: target} }] })
176
187
  return c_result_translate_rem_prefix(resp,'folder','created',prefix_path)
177
188
  when :mkfile
178
- path_list=get_next_arg_add_prefix(prefix_path,"file path")
179
- contents64=Base64.strict_encode64(self.options.get_next_argument("contents"))
180
- resp=@api_node.create('files/create',{ "paths" => [{ :type => :file, :path => path_list, :contents => contents64 } ] } )
189
+ path_list=get_next_arg_add_prefix(prefix_path,'file path')
190
+ contents64=Base64.strict_encode64(options.get_next_argument('contents'))
191
+ resp=@api_node.create('files/create',{ 'paths' => [{ type: :file, path: path_list, contents: contents64 }] })
181
192
  return c_result_translate_rem_prefix(resp,'folder','created',prefix_path)
182
193
  when :rename
183
- path_base=get_next_arg_add_prefix(prefix_path,"path_base")
184
- path_src=get_next_arg_add_prefix(prefix_path,"path_src")
185
- path_dst=get_next_arg_add_prefix(prefix_path,"path_dst")
186
- resp=@api_node.create('files/rename',{ "paths" => [{ "path" => path_base, "source" => path_src, "destination" => path_dst } ] } )
194
+ path_base=get_next_arg_add_prefix(prefix_path,'path_base')
195
+ path_src=get_next_arg_add_prefix(prefix_path,'path_src')
196
+ path_dst=get_next_arg_add_prefix(prefix_path,'path_dst')
197
+ resp=@api_node.create('files/rename',{ 'paths' => [{ 'path' => path_base, 'source' => path_src, 'destination' => path_dst }] })
187
198
  return c_result_translate_rem_prefix(resp,'entry','moved',prefix_path)
188
199
  when :browse
189
- thepath=get_next_arg_add_prefix(prefix_path,"path")
190
- query={ :path => thepath}
191
- additional_query=self.options.get_option(:query,:optional)
200
+ thepath=get_next_arg_add_prefix(prefix_path,'path')
201
+ query={ path: thepath}
202
+ additional_query=options.get_option(:query,:optional)
192
203
  query.merge!(additional_query) unless additional_query.nil?
193
204
  send_result=@api_node.create('files/browse', query)[:data]
194
205
  #example: send_result={'items'=>[{'file'=>"filename1","permissions"=>[{'name'=>'read'},{'name'=>'write'}]}]}
195
206
  # if there is no items
196
207
  case send_result['self']['type']
197
208
  when 'directory','container' # directory: node, container: shares
198
- result={ :data => send_result['items'] , :type => :object_list, :textify => lambda { |table_data| c_textify_browse(table_data) } }
209
+ result={ data: send_result['items'], type: :object_list, textify: lambda { |table_data| c_textify_browse(table_data) } }
199
210
  self.format.display_status("Items: #{send_result['item_count']}/#{send_result['total_count']}")
200
211
  else # 'file','symbolic_link'
201
- result={ :data => send_result['self'] , :type => :single_object}
202
- #result={ :data => [send_result['self']] , :type => :object_list, :textify => lambda { |table_data| c_textify_browse(table_data) } }
212
+ result={ data: send_result['self'], type: :single_object}
213
+ #result={ data: [send_result['self']] , type: :object_list, textify: lambda { |table_data| c_textify_browse(table_data) } }
203
214
  #raise "unknown type: #{send_result['self']['type']}"
204
215
  end
205
216
  return c_result_remove_prefix_path(result,'path',prefix_path)
206
217
  when :upload,:download
207
- token_type=self.options.get_option(:token_type,:optional)
218
+ token_type=options.get_option(:token_type,:optional)
208
219
  # nil if Shares 1.x
209
220
  token_type=:aspera if token_type.nil?
210
221
  case token_type
211
222
  when :aspera,:hybrid
212
- transfer_paths=case command
213
- when :upload;[ { :destination => self.transfer.destination_folder('send') } ]
214
- when :download;self.transfer.ts_source_paths
223
+ transfer_paths=
224
+ case command
225
+ when :upload then[{ destination: transfer.destination_folder('send') }]
226
+ when :download then transfer.ts_source_paths
215
227
  end
216
228
  # only one request, so only one answer
217
- transfer_spec=@api_node.create("files/#{command}_setup",{:transfer_requests => [ { transfer_request: {
229
+ transfer_spec=@api_node.create("files/#{command}_setup",{ transfer_requests: [{ transfer_request: {
218
230
  paths: transfer_paths
219
- }.deep_merge(@add_request_param) } ] } )[:data]['transfer_specs'].first['transfer_spec']
231
+ }.deep_merge(@add_request_param) }] })[:data]['transfer_specs'].first['transfer_spec']
220
232
  # delete this part, as the returned value contains only destination, and not sources
221
233
  transfer_spec.delete('paths') if command.eql?(:upload)
222
234
  when :basic
223
- raise "shall have auth" unless @api_node.params[:auth].is_a?(Hash)
224
- raise "shall be basic auth" unless @api_node.params[:auth][:type].eql?(:basic)
235
+ raise 'shall have auth' unless @api_node.params[:auth].is_a?(Hash)
236
+ raise 'shall be basic auth' unless @api_node.params[:auth][:type].eql?(:basic)
237
+ ts_direction=
238
+ case command
239
+ when :upload then Fasp::TransferSpec::DIRECTION_SEND
240
+ when :download then Fasp::TransferSpec::DIRECTION_RECEIVE
241
+ else raise 'Error: need upload or download'
242
+ end
225
243
  transfer_spec={
226
- 'remote_host'=>URI.parse(@api_node.params[:base_url]).host,
227
- 'remote_user'=>Aspera::Node::ACCESS_KEY_TRANSFER_USER,
228
- 'ssh_port'=>Aspera::Node::SSH_PORT_DEFAULT,
229
- 'direction'=>case command;when :upload;'send';when :download;'recv';else raise "Error";end
230
- }
244
+ 'remote_host' =>URI.parse(@api_node.params[:base_url]).host,
245
+ 'remote_user' =>Aspera::Fasp::TransferSpec::ACCESS_KEY_TRANSFER_USER,
246
+ 'ssh_port' =>Aspera::Fasp::TransferSpec::SSH_PORT,
247
+ 'direction' =>ts_direction,
248
+ 'destination_root'=>transfer.destination_folder(ts_direction)
249
+ }.deep_merge(@add_request_param)
231
250
  else raise "ERROR: token_type #{tt}"
232
251
  end
233
252
  if [:basic,:hybrid].include?(token_type)
234
253
  Aspera::Node.set_ak_basic_token(transfer_spec,@api_node.params[:auth][:username],@api_node.params[:auth][:password])
235
254
  end
236
- return Main.result_transfer(self.transfer.start(transfer_spec,{:src=>:node_gen3}))
255
+ return Main.result_transfer(transfer.start(transfer_spec,{ src: :node_gen3}))
237
256
  when :api_details
238
- return { :type=>:single_object, :data => @api_node.params }
257
+ return { type: :single_object, data: @api_node.params }
239
258
  end
240
259
  end
241
260
 
242
261
  def execute_async
243
- command=self.options.get_next_command([:list,:delete,:files,:show,:counters,:bandwidth])
262
+ command=options.get_next_command([:list,:delete,:files,:show,:counters,:bandwidth])
244
263
  unless command.eql?(:list)
245
- asyncname=self.options.get_option(:name,:optional)
264
+ asyncname=options.get_option(:sync_name,:optional)
246
265
  if asyncname.nil?
247
- asyncid=self.options.get_option(:id,:mandatory)
248
- if asyncid.eql?('ALL') and [:show,:delete].include?(command)
266
+ asyncid=instance_identifier()
267
+ if asyncid.eql?('ALL') && [:show,:delete].include?(command)
249
268
  asyncids=@api_node.read('async/list')[:data]['sync_ids']
250
269
  else
251
270
  Integer(asyncid) # must be integer
@@ -264,42 +283,39 @@ module Aspera
264
283
  case command
265
284
  when :list
266
285
  resp=@api_node.read('async/list')[:data]['sync_ids']
267
- return { :type => :value_list, :data => resp, :name=>'id' }
286
+ return { type: :value_list, data: resp, name: 'id' }
268
287
  when :show
269
288
  resp=@api_node.create('async/summary',pdata)[:data]['sync_summaries']
270
289
  return Main.result_empty if resp.empty?
271
- if asyncid.eql?('ALL')
272
- return { :type => :object_list, :data => resp, :fields => ['snid','name','local_dir','remote_dir'] }
273
- else
274
- return { :type => :single_object, :data => resp.first }
275
- end
290
+ return { type: :object_list, data: resp, fields: ['snid','name','local_dir','remote_dir'] } if asyncid.eql?('ALL')
291
+ return { type: :single_object, data: resp.first }
276
292
  when :delete
277
293
  resp=@api_node.create('async/delete',pdata)[:data]
278
- return { :type => :single_object, :data => resp, :name=>'id' }
294
+ return { type: :single_object, data: resp, name: 'id' }
279
295
  when :bandwidth
280
- pdata['seconds']=100 # TODO: as parameter with --value
296
+ pdata['seconds']=100 # TODO: as parameter with --value
281
297
  resp=@api_node.create('async/bandwidth',pdata)[:data]
282
298
  data=resp['bandwidth_data']
283
299
  return Main.result_empty if data.empty?
284
300
  data=data.first[asyncid]['data']
285
- return { :type => :object_list, :data => data, :name=>'id' }
301
+ return { type: :object_list, data: data, name: 'id' }
286
302
  when :files
287
303
  # count int
288
304
  # filename str
289
305
  # skip int
290
306
  # status int
291
- filter=self.options.get_option(:value,:optional)
307
+ filter=options.get_option(:value,:optional)
292
308
  pdata.merge!(filter) unless filter.nil?
293
309
  resp=@api_node.create('async/files',pdata)[:data]
294
310
  data=resp['sync_files']
295
311
  data=data.first[asyncid] unless data.empty?
296
312
  iteration_data=[]
297
313
  skip_ids_persistency=nil
298
- if self.options.get_option(:once_only,:mandatory)
314
+ if options.get_option(:once_only,:mandatory)
299
315
  skip_ids_persistency=PersistencyActionOnce.new(
300
316
  manager: @agents[:persistency],
301
317
  data: iteration_data,
302
- id: IdGenerator.from_list(['sync_files',self.options.get_option(:url,:mandatory),self.options.get_option(:username,:mandatory),asyncid]))
318
+ id: IdGenerator.from_list(['sync_files',options.get_option(:url,:mandatory),options.get_option(:username,:mandatory),asyncid]))
303
319
  unless iteration_data.first.nil?
304
320
  data.select!{|l| l['fnid'].to_i>iteration_data.first}
305
321
  end
@@ -307,92 +323,92 @@ module Aspera
307
323
  end
308
324
  return Main.result_empty if data.empty?
309
325
  skip_ids_persistency.save unless skip_ids_persistency.nil?
310
- return { :type => :object_list, :data => data, :name=>'id' }
326
+ return { type: :object_list, data: data, name: 'id' }
311
327
  when :counters
312
- resp=@api_node.create('async/counters',pdata)[:data]["sync_counters"].first[asyncid].last
328
+ resp=@api_node.create('async/counters',pdata)[:data]['sync_counters'].first[asyncid].last
313
329
  return Main.result_empty if resp.nil?
314
- return { :type => :single_object, :data => resp }
330
+ return { type: :single_object, data: resp }
315
331
  end
316
332
  end
317
333
 
318
- ACTIONS=[ :postprocess,:stream, :transfer, :cleanup, :forward, :access_key, :watch_folder, :service, :async, :central, :asperabrowser, :basic_token ].concat(COMMON_ACTIONS)
334
+ ACTIONS=[:postprocess,:stream, :transfer, :cleanup, :forward, :access_key, :watch_folder, :service, :async, :central, :asperabrowser, :basic_token].concat(COMMON_ACTIONS)
319
335
 
320
336
  def execute_action(command=nil,prefix_path=nil)
321
- command||=self.options.get_next_command(ACTIONS)
337
+ command||=options.get_next_command(ACTIONS)
322
338
  case command
323
- when *COMMON_ACTIONS; return execute_simple_common(command,prefix_path)
324
- when :async; return execute_async()
339
+ when *COMMON_ACTIONS then return execute_simple_common(command,prefix_path)
340
+ when :async then return execute_async()
325
341
  when :stream
326
- command=self.options.get_next_command([ :list, :create, :show, :modify, :cancel ])
342
+ command=options.get_next_command([:list, :create, :show, :modify, :cancel])
327
343
  case command
328
344
  when :list
329
- resp=@api_node.read('ops/transfers',self.options.get_option(:value,:optional))
330
- return { :type => :object_list, :data => resp[:data], :fields=>['id','status'] } # TODO
345
+ resp=@api_node.read('ops/transfers',options.get_option(:value,:optional))
346
+ return { type: :object_list, data: resp[:data], fields: ['id','status'] } # TODO: useful?
331
347
  when :create
332
- resp=@api_node.create('streams',self.options.get_option(:value,:mandatory))
333
- return { :type => :single_object, :data => resp[:data] }
348
+ resp=@api_node.create('streams',options.get_option(:value,:mandatory))
349
+ return { type: :single_object, data: resp[:data] }
334
350
  when :show
335
- trid=self.options.get_next_argument("transfer id")
351
+ trid=options.get_next_argument('transfer id')
336
352
  resp=@api_node.read('ops/transfers/'+trid)
337
- return { :type=>:other_struct, :data => resp[:data] }
353
+ return { type: :other_struct, data: resp[:data] }
338
354
  when :modify
339
- trid=self.options.get_next_argument("transfer id")
340
- resp=@api_node.update('streams/'+trid,self.options.get_option(:value,:mandatory))
341
- return { :type=>:other_struct, :data => resp[:data] }
355
+ trid=options.get_next_argument('transfer id')
356
+ resp=@api_node.update('streams/'+trid,options.get_option(:value,:mandatory))
357
+ return { type: :other_struct, data: resp[:data] }
342
358
  when :cancel
343
- trid=self.options.get_next_argument("transfer id")
359
+ trid=options.get_next_argument('transfer id')
344
360
  resp=@api_node.cancel('streams/'+trid)
345
- return { :type=>:other_struct, :data => resp[:data] }
361
+ return { type: :other_struct, data: resp[:data] }
346
362
  else
347
- raise "error"
363
+ raise 'error'
348
364
  end
349
365
  when :transfer
350
- command=self.options.get_next_command([ :list, :cancel, :show ])
366
+ command=options.get_next_command([:list, :cancel, :show])
351
367
  res_class_path='ops/transfers'
352
368
  if [:cancel, :show].include?(command)
353
- one_res_id=self.options.get_option(:id,:mandatory)
369
+ one_res_id=instance_identifier()
354
370
  one_res_path="#{res_class_path}/#{one_res_id}"
355
371
  end
356
372
  case command
357
373
  when :list
358
- # could use ? :subpath=>'transfers'
359
- resp=@api_node.read(res_class_path,self.options.get_option(:value,:optional))
360
- return { :type => :object_list, :data => resp[:data], :fields=>['id','status','start_spec.direction','start_spec.remote_user','start_spec.remote_host','start_spec.destination_path']}
374
+ # could use ? subpath: 'transfers'
375
+ resp=@api_node.read(res_class_path,options.get_option(:value,:optional))
376
+ return { type: :object_list, data: resp[:data],
377
+ fields: ['id','status','start_spec.direction','start_spec.remote_user','start_spec.remote_host','start_spec.destination_path']}
361
378
  when :cancel
362
379
  resp=@api_node.cancel(one_res_path)
363
- return { :type=>:other_struct, :data => resp[:data] }
380
+ return { type: :other_struct, data: resp[:data] }
364
381
  when :show
365
382
  resp=@api_node.read(one_res_path)
366
- return { :type=>:other_struct, :data => resp[:data] }
383
+ return { type: :other_struct, data: resp[:data] }
367
384
  else
368
- raise "error"
385
+ raise 'error'
369
386
  end
370
387
  when :access_key
371
- return self.entity_action(@api_node,'access_keys',nil,:id,'self')
388
+ return entity_action(@api_node,'access_keys',id_default: 'self')
372
389
  when :service
373
- command=self.options.get_next_command([ :list, :create, :delete])
390
+ command=options.get_next_command([:list, :create, :delete])
374
391
  if [:delete].include?(command)
375
- svcid=self.options.get_option(:id,:mandatory)
392
+ svcid=instance_identifier()
376
393
  end
377
394
  case command
378
395
  when :list
379
396
  resp=@api_node.read('rund/services')
380
- return { :type=>:object_list, :data => resp[:data]["services"] }
397
+ return { type: :object_list, data: resp[:data]['services'] }
381
398
  when :create
382
399
  # @json:'{"type":"WATCHFOLDERD","run_as":{"user":"user1"}}'
383
- params=self.options.get_next_argument("Run creation data (structure)")
400
+ params=options.get_next_argument('Run creation data (structure)')
384
401
  resp=@api_node.create('rund/services',params)
385
402
  return Main.result_status("#{resp[:data]['id']} created")
386
403
  when :delete
387
- resp=@api_node.delete("rund/services/#{svcid}")
404
+ @api_node.delete("rund/services/#{svcid}")
388
405
  return Main.result_status("#{svcid} deleted")
389
406
  end
390
407
  when :watch_folder
391
408
  res_class_path='v3/watchfolders'
392
- #return entity_action(@api_node,'v3/watchfolders',nil,:id)
393
- command=self.options.get_next_command([ :create, :list, :show, :modify, :delete, :state])
409
+ command=options.get_next_command([:create, :list, :show, :modify, :delete, :state])
394
410
  if [:show,:modify,:delete,:state].include?(command)
395
- one_res_id=self.options.get_option(:id,:mandatory)
411
+ one_res_id=instance_identifier()
396
412
  one_res_path="#{res_class_path}/#{one_res_id}"
397
413
  end
398
414
  # hum, to avoid: Unable to convert 2016_09_14 configuration
@@ -400,46 +416,47 @@ module Aspera
400
416
  @api_node.params[:headers]['X-aspera-WF-version']='2017_10_23'
401
417
  case command
402
418
  when :create
403
- resp=@api_node.create(res_class_path,self.options.get_option(:value,:mandatory))
419
+ resp=@api_node.create(res_class_path,options.get_option(:value,:mandatory))
404
420
  return Main.result_status("#{resp[:data]['id']} created")
405
421
  when :list
406
- resp=@api_node.read(res_class_path,self.options.get_option(:value,:optional))
407
- return { :type=>:value_list, :data => resp[:data]['ids'], :name=>'id' }
422
+ resp=@api_node.read(res_class_path,options.get_option(:value,:optional))
423
+ return { type: :value_list, data: resp[:data]['ids'], name: 'id' }
408
424
  when :show
409
- return {:type=>:single_object, :data=>@api_node.read(one_res_path)[:data]}
425
+ return { type: :single_object, data: @api_node.read(one_res_path)[:data]}
410
426
  when :modify
411
- @api_node.update(one_res_path,self.options.get_option(:value,:mandatory))
427
+ @api_node.update(one_res_path,options.get_option(:value,:mandatory))
412
428
  return Main.result_status("#{one_res_id} updated")
413
429
  when :delete
414
430
  @api_node.delete(one_res_path)
415
431
  return Main.result_status("#{one_res_id} deleted")
416
432
  when :state
417
- return { :type=>:single_object, :data => @api_node.read("#{one_res_path}/state")[:data] }
433
+ return { type: :single_object, data: @api_node.read("#{one_res_path}/state")[:data] }
418
434
  end
419
435
  when :central
420
- command=self.options.get_next_command([ :session,:file])
421
- validator_id=self.options.get_option(:validator)
422
- validation={"validator_id"=>validator_id} unless validator_id.nil?
423
- request_data=self.options.get_option(:value,:optional)
436
+ command=options.get_next_command([:session,:file])
437
+ validator_id=options.get_option(:validator)
438
+ validation={'validator_id'=>validator_id} unless validator_id.nil?
439
+ request_data=options.get_option(:value,:optional)
424
440
  request_data||={}
425
441
  case command
426
442
  when :session
427
- command=self.options.get_next_command([ :list])
443
+ command=options.get_next_command([:list])
428
444
  case command
429
445
  when :list
430
- request_data.deep_merge!({"validation"=>validation}) unless validation.nil?
446
+ request_data.deep_merge!({'validation'=>validation}) unless validation.nil?
431
447
  resp=@api_node.create('services/rest/transfers/v1/sessions',request_data)
432
- return {:type=>:object_list,:data=>resp[:data]["session_info_result"]["session_info"],:fields=>["session_uuid","status","transport","direction","bytes_transferred"]}
448
+ return { type: :object_list, data: resp[:data]['session_info_result']['session_info'],
449
+ fields: ['session_uuid','status','transport','direction','bytes_transferred']}
433
450
  end
434
451
  when :file
435
- command=self.options.get_next_command([ :list, :modify])
452
+ command=options.get_next_command([:list, :modify])
436
453
  case command
437
454
  when :list
438
455
  request_data.deep_merge!({'validation'=>validation}) unless validation.nil?
439
456
  resp=@api_node.create('services/rest/transfers/v1/files',request_data)[:data]
440
457
  resp=JSON.parse(resp) if resp.is_a?(String)
441
458
  Log.dump(:resp,resp)
442
- return {:type=>:object_list,:data=>resp['file_transfer_info_result']['file_transfer_info'],:fields=>["session_uuid","file_id","status","path"]}
459
+ return { type: :object_list, data: resp['file_transfer_info_result']['file_transfer_info'], fields: ['session_uuid','file_id','status','path']}
443
460
  when :modify
444
461
  request_data.deep_merge!(validation) unless validation.nil?
445
462
  @api_node.update('services/rest/transfers/v1/files',request_data)
@@ -448,18 +465,18 @@ module Aspera
448
465
  end
449
466
  when :asperabrowser
450
467
  browse_params={
451
- 'nodeUser' => self.options.get_option(:username,:mandatory),
452
- 'nodePW' => self.options.get_option(:password,:mandatory),
453
- 'nodeURL' => self.options.get_option(:url,:mandatory)
468
+ 'nodeUser' => options.get_option(:username,:mandatory),
469
+ 'nodePW' => options.get_option(:password,:mandatory),
470
+ 'nodeURL' => options.get_option(:url,:mandatory)
454
471
  }
455
472
  # encode parameters so that it looks good in url
456
473
  encoded_params=Base64.strict_encode64(Zlib::Deflate.deflate(JSON.generate(browse_params))).gsub(/=+$/, '').tr('+/', '-_').reverse
457
- OpenApplication.instance.uri(self.options.get_option(:asperabrowserurl)+'?goto='+encoded_params)
474
+ OpenApplication.instance.uri(options.get_option(:asperabrowserurl)+'?goto='+encoded_params)
458
475
  return Main.result_status('done')
459
476
  when :basic_token
460
- return Main.result_status("Basic "+Base64.strict_encode64("#{self.options.get_option(:username,:mandatory)}:#{self.options.get_option(:password,:mandatory)}"))
477
+ return Main.result_status('Basic '+Base64.strict_encode64("#{options.get_option(:username,:mandatory)}:#{options.get_option(:password,:mandatory)}"))
461
478
  end # case command
462
- raise "ERROR: shall not reach this line"
479
+ raise 'ERROR: shall not reach this line'
463
480
  end # execute_action
464
481
  end # Main
465
482
  end # Plugin