aspera-cli 4.4.0 → 4.7.0

Sign up to get free protection for your applications and to get access to all the features.
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