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,21 +1,36 @@
1
+ # frozen_string_literal: true
1
2
  require 'aspera/cli/plugins/node'
2
3
  require 'aspera/cli/plugins/ats'
3
4
  require 'aspera/cli/basic_auth_plugin'
4
5
  require 'aspera/cli/transfer_agent'
6
+ require 'aspera/fasp/agent_node'
7
+ require 'aspera/fasp/transfer_spec'
5
8
  require 'aspera/aoc'
6
9
  require 'aspera/node'
7
10
  require 'aspera/persistency_action_once'
8
11
  require 'aspera/id_generator'
9
12
  require 'securerandom'
10
- require 'resolv'
11
13
  require 'date'
12
14
 
13
15
  module Aspera
14
16
  module Cli
15
17
  module Plugins
16
18
  class Aoc < BasicAuthPlugin
19
+ class << self
20
+ def detect(base_url)
21
+ api=Rest.new({base_url: base_url})
22
+ # either in standard domain, or product name in page
23
+ if URI.parse(base_url).host.end_with?(Aspera::AoC::PROD_DOMAIN) ||
24
+ api.call({operation: 'GET', redirect_max: 1, headers: {'Accept'=>'text/html'}})[:http].body.include?(Aspera::AoC::PRODUCT_NAME)
25
+ return {product: :aoc,version: 'SaaS' }
26
+ end
27
+ return nil
28
+ end
29
+ end
17
30
  # special value for package id
18
31
  VAL_ALL='ALL'
32
+ ID_AK_ADMIN='ASPERA_ACCESS_KEY_ADMIN'
33
+
19
34
  def initialize(env)
20
35
  super(env)
21
36
  @default_workspace_id=nil
@@ -25,122 +40,108 @@ module Aspera
25
40
  @home_node_file=nil
26
41
  @api_aoc=nil
27
42
  @url_token_data=nil
28
- @user_info=nil
29
43
  @api_aoc=nil
30
- self.options.add_opt_list(:auth,Oauth.auth_types,'OAuth type of authentication')
31
- self.options.add_opt_list(:operation,[:push,:pull],'client operation for transfers')
32
- self.options.add_opt_simple(:client_id,'OAuth API client identifier in application')
33
- self.options.add_opt_simple(:client_secret,'OAuth API client passcode')
34
- self.options.add_opt_simple(:redirect_uri,'OAuth API client redirect URI')
35
- self.options.add_opt_simple(:private_key,'OAuth JWT RSA private key PEM value (prefix file path with @val:@file:)')
36
- self.options.add_opt_simple(:workspace,'name of workspace')
37
- self.options.add_opt_simple(:name,'resource name')
38
- self.options.add_opt_simple(:path,'file or folder path')
39
- self.options.add_opt_simple(:link,'public link to shared resource')
40
- self.options.add_opt_simple(:new_user_option,'new user creation option')
41
- self.options.add_opt_simple(:from_folder,'share to share source folder')
42
- self.options.add_opt_simple(:scope,'OAuth scope for AoC API calls')
43
- self.options.add_opt_boolean(:bulk,'bulk operation')
44
- self.options.add_opt_boolean(:default_ports,'use standard FASP ports or get from node api')
45
- self.options.set_option(:bulk,:no)
46
- self.options.set_option(:default_ports,:yes)
47
- self.options.set_option(:new_user_option,{'package_contact'=>true})
48
- self.options.set_option(:operation,:push)
49
- self.options.set_option(:auth,:jwt)
50
- self.options.set_option(:scope,AoC::SCOPE_FILES_USER)
51
- self.options.set_option(:private_key,'@file:'+env[:private_key_path]) if env[:private_key_path].is_a?(String)
52
- self.options.parse_options!
53
- AoC.set_use_default_ports(self.options.get_option(:default_ports))
44
+ options.add_opt_list(:auth,Oauth::STD_AUTH_TYPES,'OAuth type of authentication')
45
+ options.add_opt_list(:operation,[:push,:pull],'client operation for transfers')
46
+ options.add_opt_simple(:client_id,'OAuth API client identifier in application')
47
+ options.add_opt_simple(:client_secret,'OAuth API client passcode')
48
+ options.add_opt_simple(:redirect_uri,'OAuth API client redirect URI')
49
+ options.add_opt_simple(:private_key,'OAuth JWT RSA private key PEM value (prefix file path with @val:@file:)')
50
+ options.add_opt_simple(:workspace,'name of workspace')
51
+ options.add_opt_simple(:name,'resource name')
52
+ options.add_opt_simple(:path,'file or folder path')
53
+ options.add_opt_simple(:link,'public link to shared resource')
54
+ options.add_opt_simple(:new_user_option,'new user creation option')
55
+ options.add_opt_simple(:from_folder,'share to share source folder')
56
+ options.add_opt_simple(:scope,'OAuth scope for AoC API calls')
57
+ options.add_opt_boolean(:bulk,'bulk operation')
58
+ options.add_opt_boolean(:default_ports,'use standard FASP ports or get from node api')
59
+ options.set_option(:bulk,:no)
60
+ options.set_option(:default_ports,:yes)
61
+ options.set_option(:new_user_option,{'package_contact'=>true})
62
+ options.set_option(:operation,:push)
63
+ options.set_option(:auth,:jwt)
64
+ options.set_option(:scope,AoC::SCOPE_FILES_USER)
65
+ options.set_option(:private_key,'@file:'+env[:private_key_path]) if env[:private_key_path].is_a?(String)
66
+ options.parse_options!
67
+ AoC.use_standard_ports=options.get_option(:default_ports)
54
68
  return if env[:man_only]
55
69
  end
56
70
 
57
- def get_api
71
+ def aoc_api
58
72
  if @api_aoc.nil?
59
73
  @api_aoc=AoC.new(aoc_params(AoC::API_V1))
60
74
  # add keychain for access key secrets
61
- @api_aoc.key_chain=@agents[:secret]
75
+ @api_aoc.key_chain=@agents[:config]
62
76
  end
63
77
  return @api_aoc
64
78
  end
65
79
 
66
- # cached user information
67
- def c_user_info
68
- if @user_info.nil?
69
- # get our user's default information
70
- # self?embed[]=default_workspace&embed[]=organization
71
- @user_info=@api_aoc.read('self')[:data] rescue {
72
- 'name' => 'unknown',
73
- 'email' => 'unknown',
74
- }
75
- end
76
- return @user_info
77
- end
78
-
79
80
  # starts transfer using transfer agent
80
81
  def transfer_start(app,direction,node_file,ts_add)
81
82
  ts_add.deep_merge!(AoC.analytics_ts(app,direction,@workspace_id,@workspace_name))
82
- ts_add.deep_merge!(AoC.console_ts(app,c_user_info['name'],c_user_info['email']))
83
- return self.transfer.start(*@api_aoc.tr_spec(app,direction,node_file,ts_add))
83
+ ts_add.deep_merge!(aoc_api.console_ts(app))
84
+ return transfer.start(*aoc_api.tr_spec(app,direction,node_file,ts_add))
84
85
  end
85
86
 
86
- NODE4_COMMANDS=[ :browse, :find, :mkdir, :rename, :delete, :upload, :download, :transfer, :http_node_download, :v3, :file, :bearer_token_node, :node_info ]
87
+ NODE4_COMMANDS=[:browse, :find, :mkdir, :rename, :delete, :upload, :download, :transfer, :http_node_download, :v3, :file, :bearer_token_node, :node_info].freeze
87
88
 
88
89
  def execute_node_gen4_command(command_repo,top_node_file)
89
90
  case command_repo
90
91
  when :bearer_token_node
91
- thepath=self.options.get_next_argument('path')
92
- node_file = @api_aoc.resolve_node_file(top_node_file,thepath)
93
- node_api=@api_aoc.get_node_api(node_file[:node_info],scope: AoC::SCOPE_NODE_USER, use_secret: false)
92
+ thepath=options.get_next_argument('path')
93
+ node_file = aoc_api.resolve_node_file(top_node_file,thepath)
94
+ node_api=aoc_api.get_node_api(node_file[:node_info], use_secret: false)
94
95
  return Main.result_status(node_api.oauth_token)
95
96
  when :node_info
96
- thepath=self.options.get_next_argument('path')
97
- node_file = @api_aoc.resolve_node_file(top_node_file,thepath)
98
- node_api=@api_aoc.get_node_api(node_file[:node_info],scope: AoC::SCOPE_NODE_USER, use_secret: false)
99
- return {:type=>:single_object,:data=>{
97
+ thepath=options.get_next_argument('path')
98
+ node_file = aoc_api.resolve_node_file(top_node_file,thepath)
99
+ node_api=aoc_api.get_node_api(node_file[:node_info], use_secret: false)
100
+ return {type: :single_object,data: {
100
101
  url: node_file[:node_info]['url'],
101
102
  username: node_file[:node_info]['access_key'],
102
103
  password: node_api.oauth_token,
103
104
  root_id: node_file[:file_id]
104
105
  }}
105
106
  when :browse
106
- thepath=self.options.get_next_argument('path')
107
- node_file = @api_aoc.resolve_node_file(top_node_file,thepath)
108
- node_api=@api_aoc.get_node_api(node_file[:node_info],scope: AoC::SCOPE_NODE_USER)
107
+ thepath=options.get_next_argument('path')
108
+ node_file = aoc_api.resolve_node_file(top_node_file,thepath)
109
+ node_api=aoc_api.get_node_api(node_file[:node_info])
109
110
  file_info = node_api.read("files/#{node_file[:file_id]}")[:data]
110
111
  if file_info['type'].eql?('folder')
111
- result=node_api.read("files/#{node_file[:file_id]}/files",self.options.get_option(:value,:optional))
112
+ result=node_api.read("files/#{node_file[:file_id]}/files",options.get_option(:value,:optional))
112
113
  items=result[:data]
113
114
  self.format.display_status("Items: #{result[:data].length}/#{result[:http]['X-Total-Count']}")
114
115
  else
115
116
  items=[file_info]
116
117
  end
117
- return {:type=>:object_list,:data=>items,:fields=>['name','type','recursive_size','size','modified_time','access_level']}
118
+ return {type: :object_list,data: items,fields: ['name','type','recursive_size','size','modified_time','access_level']}
118
119
  when :find
119
- thepath=self.options.get_next_argument('path')
120
- node_file=@api_aoc.resolve_node_file(top_node_file,thepath)
121
- test_block=Aspera::Node.file_matcher(self.options.get_option(:value,:optional))
122
- return {:type=>:object_list,:data=>@api_aoc.find_files(node_file,test_block),:fields=>['path']}
120
+ thepath=options.get_next_argument('path')
121
+ node_file=aoc_api.resolve_node_file(top_node_file,thepath)
122
+ test_block=Aspera::Node.file_matcher(options.get_option(:value,:optional))
123
+ return {type: :object_list,data: aoc_api.find_files(node_file,test_block),fields: ['path']}
123
124
  when :mkdir
124
- thepath=self.options.get_next_argument('path')
125
+ thepath=options.get_next_argument('path')
125
126
  containing_folder_path = thepath.split(AoC::PATH_SEPARATOR)
126
127
  new_folder=containing_folder_path.pop
127
- node_file = @api_aoc.resolve_node_file(top_node_file,containing_folder_path.join(AoC::PATH_SEPARATOR))
128
- node_api=@api_aoc.get_node_api(node_file[:node_info],scope: AoC::SCOPE_NODE_USER)
129
- result=node_api.create("files/#{node_file[:file_id]}/files",{:name=>new_folder,:type=>:folder})[:data]
128
+ node_file = aoc_api.resolve_node_file(top_node_file,containing_folder_path.join(AoC::PATH_SEPARATOR))
129
+ node_api=aoc_api.get_node_api(node_file[:node_info])
130
+ result=node_api.create("files/#{node_file[:file_id]}/files",{name: new_folder,type: :folder})[:data]
130
131
  return Main.result_status("created: #{result['name']} (id=#{result['id']})")
131
132
  when :rename
132
- thepath=self.options.get_next_argument('source path')
133
- newname=self.options.get_next_argument('new name')
134
- node_file = @api_aoc.resolve_node_file(top_node_file,thepath)
135
- node_api=@api_aoc.get_node_api(node_file[:node_info],scope: AoC::SCOPE_NODE_USER)
136
- result=node_api.update("files/#{node_file[:file_id]}",{:name=>newname})[:data]
133
+ thepath=options.get_next_argument('source path')
134
+ newname=options.get_next_argument('new name')
135
+ node_file = aoc_api.resolve_node_file(top_node_file,thepath)
136
+ node_api=aoc_api.get_node_api(node_file[:node_info])
137
+ result=node_api.update("files/#{node_file[:file_id]}",{name: newname})[:data]
137
138
  return Main.result_status("renamed #{thepath} to #{newname}")
138
139
  when :delete
139
- thepath=self.options.get_next_argument('path')
140
+ thepath=options.get_next_argument('path')
140
141
  return do_bulk_operation(thepath,'deleted','path') do |l_path|
141
142
  raise "expecting String (path), got #{l_path.class.name} (#{l_path})" unless l_path.is_a?(String)
142
- node_file = @api_aoc.resolve_node_file(top_node_file,l_path)
143
- node_api=@api_aoc.get_node_api(node_file[:node_info],scope: AoC::SCOPE_NODE_USER)
143
+ node_file = aoc_api.resolve_node_file(top_node_file,l_path)
144
+ node_api=aoc_api.get_node_api(node_file[:node_info])
144
145
  result=node_api.delete("files/#{node_file[:file_id]}")[:data]
145
146
  {'path'=>l_path}
146
147
  end
@@ -150,20 +151,26 @@ module Aspera
150
151
  # in same workspace
151
152
  server_home_node_file=client_home_node_file=top_node_file
152
153
  # default is push
153
- case self.options.get_option(:operation,:mandatory)
154
+ case options.get_option(:operation,:mandatory)
154
155
  when :push
155
- client_tr_oper='send'
156
- client_folder=self.options.get_option(:from_folder,:mandatory)
157
- server_folder=self.transfer.destination_folder(client_tr_oper)
156
+ client_tr_oper=Fasp::TransferSpec::DIRECTION_SEND
157
+ client_folder=options.get_option(:from_folder,:mandatory)
158
+ server_folder=transfer.destination_folder(client_tr_oper)
158
159
  when :pull
159
- client_tr_oper='receive'
160
- client_folder=self.transfer.destination_folder(client_tr_oper)
161
- server_folder=self.options.get_option(:from_folder,:mandatory)
160
+ client_tr_oper=Fasp::TransferSpec::DIRECTION_RECEIVE
161
+ client_folder=transfer.destination_folder(client_tr_oper)
162
+ server_folder=options.get_option(:from_folder,:mandatory)
162
163
  end
163
- client_node_file = @api_aoc.resolve_node_file(client_home_node_file,client_folder)
164
- server_node_file = @api_aoc.resolve_node_file(server_home_node_file,server_folder)
164
+ client_node_file = aoc_api.resolve_node_file(client_home_node_file,client_folder)
165
+ server_node_file = aoc_api.resolve_node_file(server_home_node_file,server_folder)
165
166
  # force node as transfer agent
166
- @agents[:transfer].set_agent_instance(Fasp::Node.new(@api_aoc.get_node_api(client_node_file[:node_info],scope: AoC::SCOPE_NODE_USER)))
167
+ client_node_api=aoc_api.get_node_api(client_node_file[:node_info], use_secret: false)
168
+ @agents[:transfer].agent_instance=Fasp::AgentNode.new({
169
+ url: client_node_api.params[:base_url],
170
+ username: client_node_file[:node_info]['access_key'],
171
+ password: client_node_api.oauth_token,
172
+ root_id: client_node_file[:file_id]
173
+ })
167
174
  # additional node to node TS info
168
175
  add_ts={
169
176
  'remote_access_key' => server_node_file[:node_info]['access_key'],
@@ -172,11 +179,11 @@ module Aspera
172
179
  }
173
180
  return Main.result_transfer(transfer_start(AoC::FILES_APP,client_tr_oper,server_node_file,add_ts))
174
181
  when :upload
175
- node_file = @api_aoc.resolve_node_file(top_node_file,self.transfer.destination_folder('send'))
182
+ node_file = aoc_api.resolve_node_file(top_node_file,transfer.destination_folder(Fasp::TransferSpec::DIRECTION_SEND))
176
183
  add_ts={'tags'=>{'aspera'=>{'files'=>{'parentCwd'=>"#{node_file[:node_info]['id']}:#{node_file[:file_id]}"}}}}
177
- return Main.result_transfer(transfer_start(AoC::FILES_APP,'send',node_file,add_ts))
184
+ return Main.result_transfer(transfer_start(AoC::FILES_APP,Fasp::TransferSpec::DIRECTION_SEND,node_file,add_ts))
178
185
  when :download
179
- source_paths=self.transfer.ts_source_paths
186
+ source_paths=transfer.ts_source_paths
180
187
  # special case for AoC : all files must be in same folder
181
188
  source_folder=source_paths.shift['source']
182
189
  # if a single file: split into folder and path
@@ -185,13 +192,13 @@ module Aspera
185
192
  source_paths=[{'source'=>source_folder.pop}]
186
193
  source_folder=source_folder.join(AoC::PATH_SEPARATOR)
187
194
  end
188
- node_file = @api_aoc.resolve_node_file(top_node_file,source_folder)
195
+ node_file = aoc_api.resolve_node_file(top_node_file,source_folder)
189
196
  # override paths with just filename
190
197
  add_ts={'tags'=>{'aspera'=>{'files'=>{'parentCwd'=>"#{node_file[:node_info]['id']}:#{node_file[:file_id]}"}}}}
191
198
  add_ts.merge!({'paths'=>source_paths})
192
- return Main.result_transfer(transfer_start(AoC::FILES_APP,'receive',node_file,add_ts))
199
+ return Main.result_transfer(transfer_start(AoC::FILES_APP,Fasp::TransferSpec::DIRECTION_RECEIVE,node_file,add_ts))
193
200
  when :http_node_download
194
- source_paths=self.transfer.ts_source_paths
201
+ source_paths=transfer.ts_source_paths
195
202
  source_folder=source_paths.shift['source']
196
203
  if source_paths.empty?
197
204
  source_folder=source_folder.split(AoC::PATH_SEPARATOR)
@@ -200,35 +207,37 @@ module Aspera
200
207
  end
201
208
  raise CliBadArgument,'one file at a time only in HTTP mode' if source_paths.length > 1
202
209
  file_name = source_paths.first['source']
203
- node_file = @api_aoc.resolve_node_file(top_node_file,File.join(source_folder,file_name))
204
- node_api=@api_aoc.get_node_api(node_file[:node_info],scope: AoC::SCOPE_NODE_USER)
205
- node_api.call({:operation=>'GET',:subpath=>"files/#{node_file[:file_id]}/content",:save_to_file=>File.join(self.transfer.destination_folder('receive'),file_name)})
210
+ node_file = aoc_api.resolve_node_file(top_node_file,File.join(source_folder,file_name))
211
+ node_api=aoc_api.get_node_api(node_file[:node_info])
212
+ node_api.call({operation: 'GET',subpath: "files/#{node_file[:file_id]}/content",
213
+ save_to_file: File.join(transfer.destination_folder(Fasp::TransferSpec::DIRECTION_RECEIVE),file_name)})
206
214
  return Main.result_status("downloaded: #{file_name}")
207
215
  when :v3
208
216
  # Note: other common actions are unauthorized with user scope
209
- command_legacy=self.options.get_next_command(Node::SIMPLE_ACTIONS)
217
+ command_legacy=options.get_next_command(Node::SIMPLE_ACTIONS)
210
218
  # TODO: shall we support all methods here ? what if there is a link ?
211
- node_api=@api_aoc.get_node_api(top_node_file[:node_info],scope: AoC::SCOPE_NODE_USER)
219
+ node_api=aoc_api.get_node_api(top_node_file[:node_info])
212
220
  return Node.new(@agents.merge(skip_basic_auth_options: true, node_api: node_api)).execute_action(command_legacy)
213
221
  when :file
214
- file_path=self.options.get_option(:path,:optional)
215
- node_file = if !file_path.nil?
216
- @api_aoc.resolve_node_file(top_node_file,file_path) # TODO: allow follow link ?
222
+ command_node_file=options.get_next_command([:show,:permission,:modify])
223
+ file_path=options.get_option(:path,:optional)
224
+ node_file =
225
+ if !file_path.nil?
226
+ aoc_api.resolve_node_file(top_node_file,file_path) # TODO: allow follow link ?
217
227
  else
218
- {node_info: top_node_file[:node_info],file_id: self.options.get_option(:id,:mandatory)}
228
+ {node_info: top_node_file[:node_info],file_id: instance_identifier()}
219
229
  end
220
- node_api=@api_aoc.get_node_api(node_file[:node_info],scope: AoC::SCOPE_NODE_USER)
221
- command_node_file=self.options.get_next_command([:show,:permission,:modify])
230
+ node_api=aoc_api.get_node_api(node_file[:node_info])
222
231
  case command_node_file
223
232
  when :show
224
233
  items=node_api.read("files/#{node_file[:file_id]}")[:data]
225
- return {:type=>:single_object,:data=>items}
234
+ return {type: :single_object,data: items}
226
235
  when :modify
227
- update_param=self.options.get_next_argument('update data (Hash)')
236
+ update_param=options.get_next_argument('update data (Hash)')
228
237
  res=node_api.update("files/#{node_file[:file_id]}",update_param)[:data]
229
- return {:type=>:single_object,:data=>res}
238
+ return {type: :single_object,data: res}
230
239
  when :permission
231
- command_perm=self.options.get_next_command([:list,:create])
240
+ command_perm=options.get_next_command([:list,:create])
232
241
  case command_perm
233
242
  when :list
234
243
  # generic options : TODO: as arg ? option_url_query
@@ -240,11 +249,11 @@ module Aspera
240
249
  list_options['inherited']||=false
241
250
  end
242
251
  items=node_api.read('permissions',list_options)[:data]
243
- return {:type=>:object_list,:data=>items}
252
+ return {type: :object_list,data: items}
244
253
  when :create
245
254
  #create_param=self.options.get_next_argument('creation data (Hash)')
246
255
  set_workspace_info
247
- access_id="ASPERA_ACCESS_KEY_ADMIN_WS_#{@workspace_id}"
256
+ access_id="#{ID_AK_ADMIN}_WS_#{@workspace_id}"
248
257
  node_file[:node_info]
249
258
  params={
250
259
  'file_id' =>node_file[:file_id], # mandatory
@@ -254,23 +263,19 @@ module Aspera
254
263
  'tags' =>{'aspera'=>{'files'=>{'workspace'=>{
255
264
  'id' =>@workspace_id,
256
265
  'workspace_name' =>@workspace_name,
257
- 'user_name' =>c_user_info['name'],
258
- 'shared_by_user_id'=>c_user_info['id'],
259
- 'shared_by_name' =>c_user_info['name'],
260
- 'shared_by_email' =>c_user_info['email'],
266
+ 'user_name' =>aoc_api.user_info['name'],
267
+ 'shared_by_user_id'=>aoc_api.user_info['id'],
268
+ 'shared_by_name' =>aoc_api.user_info['name'],
269
+ 'shared_by_email' =>aoc_api.user_info['email'],
261
270
  'shared_with_name' =>access_id,
262
271
  'access_key' =>node_file[:node_info]['access_key'],
263
272
  'node' =>node_file[:node_info]['name']}}}}}
264
273
  item=node_api.create('permissions',params)[:data]
265
- return {:type=>:single_object,:data=>item}
274
+ return {type: :single_object,data: item}
266
275
  else raise "internal error:shall not reach here (#{command_perm})"
267
276
  end
268
- raise 'internal error:shall not reach here'
269
277
  else raise "internal error:shall not reach here (#{command_node_file})"
270
278
  end
271
- raise 'internal error:shall not reach here'
272
- when :permissions
273
-
274
279
  end # command_repo
275
280
  raise 'ERR'
276
281
  end # execute_node_gen4_command
@@ -278,7 +283,7 @@ module Aspera
278
283
  # build constructor option list for AoC based on options of CLI
279
284
  def aoc_params(subpath)
280
285
  # copy command line options to args
281
- opt=[:link,:url,:auth,:client_id,:client_secret,:scope,:redirect_uri,:private_key,:username,:password].inject({}){|m,i|m[i]=self.options.get_option(i,:optional);m}
286
+ opt=[:link,:url,:auth,:client_id,:client_secret,:scope,:redirect_uri,:private_key,:username,:password].each_with_object({}){|i,m|m[i]=options.get_option(i,:optional);}
282
287
  opt[:subpath]=subpath
283
288
  return opt
284
289
  end
@@ -291,17 +296,16 @@ module Aspera
291
296
  # @persist_ids
292
297
  # returns nil
293
298
  def set_workspace_info
294
- if @api_aoc.params[:auth].has_key?(:url_token)
295
- # TODO: can there be several in list ?
296
- @url_token_data=@api_aoc.read('url_tokens')[:data].first
299
+ @url_token_data=aoc_api.url_token_data
300
+ if @url_token_data.nil?
301
+ @default_workspace_id=aoc_api.user_info['default_workspace_id']
302
+ @persist_ids=[aoc_api.user_info['id']]
303
+ else
297
304
  @default_workspace_id=@url_token_data['data']['workspace_id']
298
305
  @persist_ids=[] # TODO : @url_token_data['id'] ?
299
- else
300
- @default_workspace_id=c_user_info['default_workspace_id']
301
- @persist_ids=[c_user_info['id']]
302
306
  end
303
307
 
304
- ws_name=self.options.get_option(:workspace,:optional)
308
+ ws_name=options.get_option(:workspace,:optional)
305
309
  if ws_name.nil?
306
310
  Log.log.debug('using default workspace'.green)
307
311
  if @default_workspace_id.eql?(nil)
@@ -311,7 +315,7 @@ module Aspera
311
315
  @workspace_id=@default_workspace_id
312
316
  else
313
317
  # lookup another workspace
314
- wss=@api_aoc.read('workspaces',{'q'=>ws_name})[:data]
318
+ wss=aoc_api.read('workspaces',{'q'=>ws_name})[:data]
315
319
  wss=wss.select { |i| i['name'].eql?(ws_name) }
316
320
  case wss.length
317
321
  when 0
@@ -322,7 +326,7 @@ module Aspera
322
326
  raise 'unexpected case'
323
327
  end
324
328
  end
325
- @workspace_data=@api_aoc.read("workspaces/#{@workspace_id}")[:data]
329
+ @workspace_data=aoc_api.read("workspaces/#{@workspace_id}")[:data]
326
330
  Log.log.debug("workspace_id=#{@workspace_id},@workspace_data=#{@workspace_data}".red)
327
331
 
328
332
  @workspace_name||=@workspace_data['name']
@@ -344,16 +348,16 @@ module Aspera
344
348
  home_file_id||=@workspace_data['home_file_id']
345
349
  raise 'node_id must be defined' if home_node_id.to_s.empty?
346
350
  @home_node_file={
347
- node_info: @api_aoc.read("nodes/#{home_node_id}")[:data],
351
+ node_info: aoc_api.read("nodes/#{home_node_id}")[:data],
348
352
  file_id: home_file_id
349
353
  }
350
- @api_aoc.check_get_node_file(@home_node_file)
354
+ aoc_api.check_get_node_file(@home_node_file)
351
355
 
352
356
  return nil
353
357
  end
354
358
 
355
359
  def do_bulk_operation(ids_or_one,success_msg,id_result='id',&do_action)
356
- ids_or_one=[ids_or_one] unless self.options.get_option(:bulk)
360
+ ids_or_one=[ids_or_one] unless options.get_option(:bulk)
357
361
  raise 'expecting Array' unless ids_or_one.is_a?(Array)
358
362
  result_list=[]
359
363
  ids_or_one.each do |id|
@@ -362,75 +366,107 @@ module Aspera
362
366
  res=do_action.call(id)
363
367
  one=res if id.is_a?(Hash) # if block returns a has, let's use this
364
368
  one['status']=success_msg
365
- rescue => e
369
+ rescue StandardError => e
366
370
  one['status']=e.to_s
367
371
  end
368
372
  result_list.push(one)
369
373
  end
370
- return {:type=>:object_list,:data=>result_list,:fields=>[id_result,'status']}
374
+ return {type: :object_list,data: result_list,fields: [id_result,'status']}
375
+ end
376
+
377
+ # get identifier or name from command line
378
+ # @return identifier
379
+ def get_resource_id_from_args(resource_class_path)
380
+ l_res_id=options.get_option(:id)
381
+ l_res_name=options.get_option(:name)
382
+ raise 'Provide either option id or name, not both' unless l_res_id.nil? || l_res_name.nil?
383
+ # try to find item by name (single partial match or exact match)
384
+ l_res_id=aoc_api.lookup_entity_by_name(resource_class_path,l_res_name)['id'] unless l_res_name.nil?
385
+ # if no name or id option, taken on command line (after command)
386
+ if l_res_id.nil?
387
+ l_res_id=options.get_next_argument('identifier')
388
+ l_res_id=aoc_api.lookup_entity_by_name(resource_class_path,options.get_next_argument('identifier'))['id'] if l_res_id.eql?('name')
389
+ end
390
+ return l_res_id
391
+ end
392
+
393
+ def get_resource_path_from_args(resource_class_path)
394
+ return "#{resource_class_path}/#{get_resource_id_from_args(resource_class_path)}"
371
395
  end
372
396
 
373
397
  # package creation params can give just email, and full hash is created
374
- def resolve_package_recipients(package_creation,recipient_list_field)
375
- return unless package_creation.has_key?(recipient_list_field)
376
- raise CliBadArgument,"#{recipient_list_field} must be an Array" unless package_creation[recipient_list_field].is_a?(Array)
377
- new_user_option=self.options.get_option(:new_user_option,:mandatory)
398
+ def resolve_package_recipients(package_data,recipient_list_field)
399
+ return unless package_data.has_key?(recipient_list_field)
400
+ raise CliBadArgument,"#{recipient_list_field} must be an Array" unless package_data[recipient_list_field].is_a?(Array)
401
+ new_user_option=options.get_option(:new_user_option,:mandatory)
402
+ # list with resolved elements
378
403
  resolved_list=[]
379
- package_creation[recipient_list_field].each do |recipient_email_or_info|
380
- case recipient_email_or_info
381
- when Hash
382
- raise 'recipient element hash shall have field id and type' unless recipient_email_or_info.has_key?('id') and recipient_email_or_info.has_key?('type')
383
- # already provided all information ?
384
- resolved_list.push(recipient_email_or_info)
385
- when String
386
- if recipient_email_or_info.include?('@')
387
- # or need to resolve email
388
- item_lookup=@api_aoc.read('contacts',{'current_workspace_id'=>@workspace_id,'q'=>recipient_email_or_info})[:data]
389
- case item_lookup.length
390
- when 1; recipient_user_id=item_lookup.first
391
- when 0; recipient_user_id=@api_aoc.create('contacts',{'current_workspace_id'=>@workspace_id,'email'=>recipient_email_or_info}.merge(new_user_option))[:data]
392
- else raise CliBadArgument,"multiple match for: #{recipient_email_or_info}"
393
- end
394
- resolved_list.push({'id'=>recipient_user_id['source_id'],'type'=>recipient_user_id['source_type']})
395
- else
396
- item_lookup=@api_aoc.read('dropboxes',{'current_workspace_id'=>@workspace_id,'q'=>recipient_email_or_info})[:data]
397
- case item_lookup.length
398
- when 1; recipient_user_id=item_lookup.first
399
- when 0; raise "no such shared inbox in workspace #{@workspace_name}"
400
- else raise CliBadArgument,"multiple match for: #{recipient_email_or_info}"
401
- end
402
- resolved_list.push({'id'=>recipient_user_id['id'],'type'=>'dropbox'})
404
+ package_data[recipient_list_field].each do |short_recipient_info|
405
+ case short_recipient_info
406
+ when Hash # native api information, check keys
407
+ raise "#{recipient_list_field} element shall have fields: id and type" unless short_recipient_info.keys.sort.eql?(['id','type'])
408
+ when String # need to resolve name to type/id
409
+ # email: user, else dropbox
410
+ entity_type=short_recipient_info.include?('@') ? 'contacts' : 'dropboxes'
411
+ begin
412
+ full_recipient_info=aoc_api.lookup_entity_by_name(entity_type,short_recipient_info,{'current_workspace_id'=>@workspace_id})
413
+ rescue RuntimeError => e
414
+ raise e unless e.message.eql?('not found')
415
+ raise "no such shared inbox in workspace #{@workspace_name}" unless entity_type.eql?('contacts')
416
+ full_recipient_info=aoc_api.create('contacts',{'current_workspace_id'=>@workspace_id,'email'=>short_recipient_info}.merge(new_user_option))[:data]
403
417
  end
404
- else
405
- raise "recipient item must be a String (email, shared inboc) or hash (id,type)"
418
+ short_recipient_info=entity_type.eql?('dropboxes') ? {'id'=>full_recipient_info['id'],'type'=>'dropbox'} : {'id'=>full_recipient_info['source_id'],'type'=>full_recipient_info['source_type']}
419
+ else # unexpected extended value, must be String or Hash
420
+ raise "#{recipient_list_field} item must be a String (email, shared inbox) or Hash (id,type)"
421
+ end # type of recipient info
422
+ # add original or resolved recipient info
423
+ resolved_list.push(short_recipient_info)
424
+ end
425
+ # replace with resolved elements
426
+ package_data[recipient_list_field]=resolved_list
427
+ end
428
+
429
+ def normalize_metadata(pkg_data)
430
+ case pkg_data['metadata']
431
+ when NilClass then return
432
+ when Array then return
433
+ when Hash
434
+ api_meta=[]
435
+ pkg_data['metadata'].each do |k,v|
436
+ api_meta.push({
437
+ #'input_type' => 'single-dropdown',
438
+ 'name' => k,
439
+ 'values' => v.is_a?(Array) ? v : [v]
440
+ })
406
441
  end
442
+ pkg_data['metadata']=api_meta
443
+ else raise "metadata field if not of expected type: #{pkg_meta.class}"
407
444
  end
408
- package_creation[recipient_list_field]=resolved_list
445
+ nil
409
446
  end
410
447
 
411
448
  # private
412
449
  def option_url_query(default)
413
- query=self.options.get_option(:query,:optional)
450
+ query=options.get_option(:query,:optional)
414
451
  query=default if query.nil?
415
452
  Log.log.debug("Query=#{query}".bg_red)
416
453
  begin
417
454
  # check it is suitable
418
455
  URI.encode_www_form(query) unless query.nil?
419
- rescue => e
456
+ rescue StandardError => e
420
457
  raise CliBadArgument,"query must be an extended value which can be encoded with URI.encode_www_form. Refer to manual. (#{e.message})"
421
458
  end
422
459
  return query
423
460
  end
424
461
 
425
462
  def assert_public_link_types(expected)
426
- if !expected.include?(@url_token_data['purpose'])
427
- raise CliBadArgument,"public link type is #{@url_token_data['purpose']} but action requires one of #{expected.join(',')}"
428
- end
463
+ raise CliBadArgument,"public link type is #{@url_token_data['purpose']} but action requires one of #{expected.join(',')}" unless expected.include?(@url_token_data['purpose'])
429
464
  end
430
465
 
431
- # Call @api_aoc.read with same parameters, but use paging if necessary to get all results
466
+ # Call aoc_api.read with same parameters.
467
+ # Use paging if necessary to get all results
432
468
  def read_with_paging(resource_class_path,base_query)
433
- raise "Query must be Hash" unless base_query.is_a?(Hash)
469
+ raise 'Query must be Hash' unless base_query.is_a?(Hash)
434
470
  # set default large page if user does not specify own parameters. AoC Caps to 1000 anyway
435
471
  base_query['per_page']=1000 unless base_query.has_key?('per_page')
436
472
  max_items=base_query[MAX_ITEMS]
@@ -445,7 +481,7 @@ module Aspera
445
481
  loop do
446
482
  query=base_query.clone
447
483
  query['page']=current_page
448
- result=@api_aoc.read(resource_class_path,query)
484
+ result=aoc_api.read(resource_class_path,query)
449
485
  total_count=result[:http]['X-Total-Count']
450
486
  page_count+=1
451
487
  current_page+=1
@@ -453,26 +489,28 @@ module Aspera
453
489
  break if add_items.empty?
454
490
  # append new items to full list
455
491
  item_list += add_items
456
- break if !max_pages.nil? and page_count > max_pages
457
- break if !max_items.nil? and item_list.count > max_items
492
+ break if !max_pages.nil? && page_count > max_pages
493
+ break if !max_items.nil? && item_list.count > max_items
458
494
  end
459
495
  return item_list,total_count
460
496
  end
461
497
 
462
498
  def execute_admin_action
463
- @api_aoc.oauth.params[:scope]=AoC::SCOPE_FILES_ADMIN
464
- command_admin=self.options.get_next_command([ :ats, :resource, :usage_reports, :analytics, :subscription, :auth_providers ])
499
+ # upgrade scope to admin
500
+ aoc_api.oauth.params[:scope]=AoC::SCOPE_FILES_ADMIN
501
+ command_admin=options.get_next_command([:ats, :resource, :usage_reports, :analytics, :subscription, :auth_providers])
465
502
  case command_admin
466
503
  when :auth_providers
467
- command_auth_prov=self.options.get_next_command([ :list, :update ])
504
+ command_auth_prov=options.get_next_command([:list, :update])
468
505
  case command_auth_prov
469
506
  when :list
470
- providers=@api_aoc.read('admin/auth_providers')[:data]
471
- return {:type=>:object_list,:data=>providers}
507
+ providers=aoc_api.read('admin/auth_providers')[:data]
508
+ return {type: :object_list,data: providers}
472
509
  when :update
510
+ raise 'not implemented'
473
511
  end
474
512
  when :subscription
475
- org=@api_aoc.read('organization')[:data]
513
+ org=aoc_api.read('organization')[:data]
476
514
  bss_api=AoC.new(aoc_params('bss/platform'))
477
515
  graphql_query="
478
516
  query ($organization_id: ID!) {
@@ -523,43 +561,43 @@ module Aspera
523
561
  }
524
562
  "
525
563
  result=bss_api.create('graphql',{'variables'=>{'organization_id'=>org['id']},'query'=>graphql_query})[:data]['data']
526
- return {:type=>:single_object,:data=>result['aoc']['bssSubscription']}
564
+ return {type: :single_object,data: result['aoc']['bssSubscription']}
527
565
  when :ats
528
- ats_api = Rest.new(@api_aoc.params.deep_merge({
529
- :base_url => @api_aoc.params[:base_url]+'/admin/ats/pub/v1',
530
- :auth => {:scope => AoC::SCOPE_FILES_ADMIN_USER}
566
+ ats_api = Rest.new(aoc_api.params.deep_merge({
567
+ base_url: aoc_api.params[:base_url]+'/admin/ats/pub/v1',
568
+ auth: {scope: AoC::SCOPE_FILES_ADMIN_USER}
531
569
  }))
532
570
  return Ats.new(@agents).execute_action_gen(ats_api)
533
571
  when :analytics
534
- analytics_api = Rest.new(@api_aoc.params.deep_merge({
535
- :base_url => @api_aoc.params[:base_url].gsub('/api/v1','')+'/analytics/v2',
536
- :auth => {:scope => AoC::SCOPE_FILES_ADMIN_USER}
572
+ analytics_api = Rest.new(aoc_api.params.deep_merge({
573
+ base_url: aoc_api.params[:base_url].gsub('/api/v1','')+'/analytics/v2',
574
+ auth: {scope: AoC::SCOPE_FILES_ADMIN_USER}
537
575
  }))
538
- command_analytics=self.options.get_next_command([ :application_events, :transfers ])
576
+ command_analytics=options.get_next_command([:application_events, :transfers])
539
577
  case command_analytics
540
578
  when :application_events
541
579
  event_type=command_analytics.to_s
542
- events=analytics_api.read("organizations/#{c_user_info['organization_id']}/#{event_type}")[:data][event_type]
543
- return {:type=>:object_list,:data=>events}
580
+ events=analytics_api.read("organizations/#{aoc_api.user_info['organization_id']}/#{event_type}")[:data][event_type]
581
+ return {type: :object_list,data: events}
544
582
  when :transfers
545
583
  event_type=command_analytics.to_s
546
- filter_resource=self.options.get_option(:name,:optional) || 'organizations'
547
- filter_id=self.options.get_option(:id,:optional) || case filter_resource
548
- when 'organizations'; c_user_info['organization_id']
549
- when 'users'; c_user_info['id']
550
- when 'nodes'; c_user_info['id']
584
+ filter_resource=options.get_option(:name,:optional) || 'organizations'
585
+ filter_id=options.get_option(:id,:optional) ||
586
+ case filter_resource
587
+ when 'organizations' then aoc_api.user_info['organization_id']
588
+ when 'users' then aoc_api.user_info['id']
589
+ when 'nodes' then aoc_api.user_info['id']
551
590
  else raise 'organizations or users for option --name'
552
591
  end
553
- #
554
- filter=self.options.get_option(:query,:optional) || {}
592
+ filter=options.get_option(:query,:optional) || {}
555
593
  raise 'query must be Hash' unless filter.is_a?(Hash)
556
594
  filter['limit']||=100
557
- if self.options.get_option(:once_only,:mandatory)
595
+ if options.get_option(:once_only,:mandatory)
558
596
  saved_date=[]
559
597
  startdate_persistency=PersistencyActionOnce.new(
560
598
  manager: @agents[:persistency],
561
599
  data: saved_date,
562
- ids: IdGenerator.from_list(['aoc_ana_date',self.options.get_option(:url,:mandatory),@workspace_name].push(filter_resource,filter_id)))
600
+ ids: IdGenerator.from_list(['aoc_ana_date',options.get_option(:url,:mandatory),@workspace_name].push(filter_resource,filter_id)))
563
601
  start_datetime=saved_date.first
564
602
  stop_datetime=Time.now.utc.strftime('%FT%T.%LZ')
565
603
  #Log.log().error("start: #{start_datetime}")
@@ -570,29 +608,27 @@ module Aspera
570
608
  end
571
609
  events=analytics_api.read("#{filter_resource}/#{filter_id}/#{event_type}",option_url_query(filter))[:data][event_type]
572
610
  startdate_persistency.save unless startdate_persistency.nil?
573
- if !self.options.get_option(:notif_to,:optional).nil?
611
+ if !options.get_option(:notif_to,:optional).nil?
574
612
  events.each do |tr_event|
575
- self.config.send_email_template({ev: tr_event})
613
+ config.send_email_template({ev: tr_event})
576
614
  end
577
615
  end
578
- return {:type=>:object_list,:data=>events}
616
+ return {type: :object_list,data: events}
579
617
  end
580
618
  when :resource
581
- resource_type=self.options.get_next_argument('resource',[:self,:organization,:user,:group,:client,:contact,:dropbox,:node,:operation,:package,:saml_configuration, :workspace, :dropbox_membership,:short_link,:workspace_membership,:application,:client_registration_token,:client_access_key,:kms_profile])
582
- # get path on API
583
- resource_class_path=case resource_type
584
- when :self,:organization
585
- resource_type
586
- when :application
587
- 'admin/apps_new'
588
- when :dropbox
589
- resource_type.to_s+'es'
590
- when :client_registration_token,:client_access_key
591
- "admin/#{resource_type}s"
592
- when :kms_profile
593
- "integrations/#{resource_type}s"
594
- else
595
- resource_type.to_s+'s'
619
+ resource_type=options.get_next_argument('resource',
620
+ [:self,:organization,:user,:group,:client,:contact,:dropbox,:node,:operation,:package,:saml_configuration, :workspace, :dropbox_membership,:short_link,:workspace_membership,
621
+ :application,:client_registration_token,:client_access_key,:kms_profile])
622
+ # get path on API, resource type is singular, but api is plural
623
+ resource_class_path=
624
+ case resource_type
625
+ # special cases: singleton, in admin, with x
626
+ when :self,:organization then resource_type
627
+ when :client_registration_token,:client_access_key then "admin/#{resource_type}s"
628
+ when :application then 'admin/apps_new'
629
+ when :dropbox then resource_type.to_s+'es'
630
+ when :kms_profile then "integrations/#{resource_type}s"
631
+ else resource_type.to_s+'s'
596
632
  end
597
633
  # build list of supported operations
598
634
  singleton_object=[:self,:organization].include?(resource_type)
@@ -602,24 +638,10 @@ module Aspera
602
638
  supported_operations.push(:v4,:v3) if resource_type.eql?(:node)
603
639
  supported_operations.push(:set_pub_key) if resource_type.eql?(:client)
604
640
  supported_operations.push(:shared_folders,:shared_create) if [:node,:workspace].include?(resource_type)
605
- command=self.options.get_next_command(supported_operations)
641
+ command=options.get_next_command(supported_operations)
606
642
  # require identifier for non global commands
607
- if !singleton_object and !global_operations.include?(command)
608
- res_id=self.options.get_option(:id)
609
- res_name=self.options.get_option(:name)
610
- if res_id.nil? and res_name.nil? and resource_type.eql?(:node)
611
- set_workspace_info
612
- set_home_node_file
613
- res_id=@home_node_file[:node_info]['id']
614
- end
615
- if !res_name.nil?
616
- Log.log.warn('name overrides id') unless res_id.nil?
617
- matching=@api_aoc.read(resource_class_path,{:q=>res_name})[:data]
618
- raise CliError,'no resource match name' if matching.empty?
619
- raise CliError,"several resources match name (#{matching.join(',')})" unless matching.length.eql?(1)
620
- res_id=matching.first['id']
621
- end
622
- raise CliBadArgument,'provide either id or name' if res_id.nil?
643
+ if !singleton_object && !global_operations.include?(command)
644
+ res_id=get_resource_id_from_args(resource_class_path)
623
645
  resource_instance_path="#{resource_class_path}/#{res_id}"
624
646
  end
625
647
  resource_instance_path=resource_class_path if singleton_object
@@ -629,79 +651,82 @@ module Aspera
629
651
  id_result='token' if resource_class_path.eql?('admin/client_registration_tokens')
630
652
  # TODO: report inconsistency: creation url is !=, and does not return id.
631
653
  resource_class_path='admin/client_registration/token' if resource_class_path.eql?('admin/client_registration_tokens')
632
- list_or_one=self.options.get_next_argument('creation data (Hash)')
633
- return do_bulk_operation(list_or_one,'created',id_result)do|params|
654
+ list_or_one=options.get_next_argument('creation data (Hash)')
655
+ return do_bulk_operation(list_or_one,'created',id_result) do |params|
634
656
  raise 'expecting Hash' unless params.is_a?(Hash)
635
- @api_aoc.create(resource_class_path,params)[:data]
657
+ aoc_api.create(resource_class_path,params)[:data]
636
658
  end
637
659
  when :list
638
660
  default_fields=['id']
639
661
  default_query={}
640
662
  case resource_type
641
- when :application; default_query={:organization_apps=>true};default_fields.push('app_type','app_name','available','direct_authorizations_allowed','workspace_authorizations_allowed')
642
- when :client,:client_access_key,:dropbox,:group,:package,:saml_configuration,:workspace; default_fields.push('name')
643
- when :client_registration_token; default_fields.push('value','data.client_subject_scopes','created_at')
644
- when :contact; default_fields=['email','name','source_id','source_type']
645
- when :node; default_fields.push('name','host','access_key')
646
- when :operation; default_fields=nil
647
- when :short_link; default_fields.push('short_url','data.url_token_data.purpose')
648
- when :user; default_fields.push('name','email')
663
+ when :application then default_query={organization_apps: true};
664
+ default_fields.push('app_type','app_name','available','direct_authorizations_allowed','workspace_authorizations_allowed')
665
+ when :client,:client_access_key,:dropbox,:group,:package,:saml_configuration,:workspace then default_fields.push('name')
666
+ when :client_registration_token then default_fields.push('value','data.client_subject_scopes','created_at')
667
+ when :contact then default_fields=['email','name','source_id','source_type']
668
+ when :node then default_fields.push('name','host','access_key')
669
+ when :operation then default_fields=nil
670
+ when :short_link then default_fields.push('short_url','data.url_token_data.purpose')
671
+ when :user then default_fields.push('name','email')
649
672
  end
650
673
  item_list,total_count=read_with_paging(resource_class_path,option_url_query(default_query))
651
674
  count_msg="Items: #{item_list.length}/#{total_count}"
652
675
  count_msg=count_msg.bg_red unless item_list.length.eql?(total_count.to_i)
653
676
  self.format.display_status(count_msg)
654
- return {:type=>:object_list,:data=>item_list,:fields=>default_fields}
677
+ return {type: :object_list,data: item_list,fields: default_fields}
655
678
  when :show
656
- object=@api_aoc.read(resource_instance_path)[:data]
657
- fields=object.keys.select{|k|!k.eql?('certificate')}
658
- return { :type=>:single_object, :data =>object, :fields=>fields }
679
+ object=aoc_api.read(resource_instance_path)[:data]
680
+ fields=object.keys.reject{|k|k.eql?('certificate')}
681
+ return { type: :single_object, data: object, fields: fields }
659
682
  when :modify
660
- changes=self.options.get_next_argument('modified parameters (hash)')
661
- @api_aoc.update(resource_instance_path,changes)
683
+ changes=options.get_next_argument('modified parameters (hash)')
684
+ aoc_api.update(resource_instance_path,changes)
662
685
  return Main.result_status('modified')
663
686
  when :delete
664
- return do_bulk_operation(res_id,'deleted')do|one_id|
665
- @api_aoc.delete("#{resource_class_path}/#{one_id.to_s}")
687
+ return do_bulk_operation(res_id,'deleted') do |one_id|
688
+ aoc_api.delete("#{resource_class_path}/#{one_id}")
666
689
  {'id'=>one_id}
667
690
  end
668
691
  when :set_pub_key
669
692
  # special : reads private and generate public
670
- the_private_key=self.options.get_next_argument('private_key')
693
+ the_private_key=options.get_next_argument('private_key')
671
694
  the_public_key=OpenSSL::PKey::RSA.new(the_private_key).public_key.to_s
672
- @api_aoc.update(resource_instance_path,{:jwt_grant_enabled=>true, :public_key=>the_public_key})
695
+ aoc_api.update(resource_instance_path,{jwt_grant_enabled: true, public_key: the_public_key})
673
696
  return Main.result_success
674
697
  when :v3,:v4
675
- res_data=@api_aoc.read(resource_instance_path)[:data]
676
- api_node=@api_aoc.get_node_api(res_data)
698
+ res_data=aoc_api.read(resource_instance_path)[:data]
699
+ api_node=aoc_api.get_node_api(res_data)
677
700
  return Node.new(@agents.merge(skip_basic_auth_options: true, node_api: api_node)).execute_action if command.eql?(:v3)
678
- ak_data=api_node.call({:operation=>'GET',:subpath=>"access_keys/#{res_data['access_key']}",:headers=>{'Accept'=>'application/json'}})[:data]
679
- command_repo=self.options.get_next_command(NODE4_COMMANDS)
701
+ ak_data=api_node.call({operation: 'GET',subpath: "access_keys/#{res_data['access_key']}",headers: {'Accept'=>'application/json'}})[:data]
702
+ command_repo=options.get_next_command(NODE4_COMMANDS)
680
703
  return execute_node_gen4_command(command_repo,{node_info: res_data, file_id: ak_data['root_file_id']})
681
704
  when :shared_folders
682
- read_params = case resource_type
683
- when :workspace;{'access_id'=>"ASPERA_ACCESS_KEY_ADMIN_WS_#{res_id}",'access_type'=>'user'}
684
- when :node;{'include'=>['[]','access_level','permission_count'],'created_by_id'=>'ASPERA_ACCESS_KEY_ADMIN'}
705
+ read_params=
706
+ case resource_type
707
+ when :workspace then{'access_id'=>"#{ID_AK_ADMIN}_WS_#{res_id}",'access_type'=>'user'}
708
+ when :node then{'include'=>['[]','access_level','permission_count'],'created_by_id'=>ID_AK_ADMIN}
685
709
  else raise 'error'
686
710
  end
687
- res_data=@api_aoc.read("#{resource_class_path}/#{res_id}/permissions",read_params)[:data]
688
- fields=case resource_type
689
- when :node;['id','file_id','file.path','access_type']
690
- when :workspace;['id','node_id','file_id','node_name','file.path','tags.aspera.files.workspace.share_as']
711
+ res_data=aoc_api.read("#{resource_instance_path}/permissions",read_params)[:data]
712
+ fields=
713
+ case resource_type
714
+ when :node then['id','file_id','file.path','access_type']
715
+ when :workspace then['id','node_id','file_id','node_name','file.path','tags.aspera.files.workspace.share_as']
691
716
  else raise "unexpected resource type #{resource_type}"
692
717
  end
693
- return { :type=>:object_list, :data =>res_data , :fields=>fields}
718
+ return { type: :object_list, data: res_data, fields: fields}
694
719
  when :shared_create
695
- # TODO
696
- folder_path=self.options.get_next_argument('folder path in node')
697
- user_create_data=self.options.get_next_argument('creation data (Hash)')
698
- res_data=@api_aoc.read(resource_instance_path)[:data]
699
- node_file = @api_aoc.resolve_node_file({node_info: res_data, file_id: ak_data['root_file_id']},folder_path)
720
+ # TODO: finish implementation
721
+ folder_path=options.get_next_argument('folder path in node')
722
+ user_create_data=options.get_next_argument('creation data (Hash)')
723
+ res_data=aoc_api.read(resource_instance_path)[:data]
724
+ node_file = aoc_api.resolve_node_file({node_info: res_data, file_id: ak_data['root_file_id']},folder_path)
700
725
 
701
- #node_api=@api_aoc.get_node_api(node_file[:node_info],scope: AoC::SCOPE_NODE_USER)
726
+ #node_api=aoc_api.get_node_api(node_file[:node_info])
702
727
  #file_info = node_api.read("files/#{node_file[:file_id]}")[:data]
703
728
 
704
- access_id="ASPERA_ACCESS_KEY_ADMIN_WS_#{@workspace_id}"
729
+ access_id="#{ID_AK_ADMIN}_WS_#{@workspace_id}"
705
730
  create_data={
706
731
  'file_id' =>node_file[:file_id],
707
732
  'access_type' =>'user',
@@ -711,10 +736,10 @@ module Aspera
711
736
  'id' =>@workspace_id,
712
737
  'workspace_name' =>@workspace_name,
713
738
  'share_as' =>File.basename(folder_path),
714
- 'user_name' =>c_user_info['name'],
715
- 'shared_by_user_id'=>c_user_info['id'],
716
- 'shared_by_name' =>c_user_info['name'],
717
- 'shared_by_email' =>c_user_info['email'],
739
+ 'user_name' =>aoc_api.user_info['name'],
740
+ 'shared_by_user_id'=>aoc_api.user_info['id'],
741
+ 'shared_by_name' =>aoc_api.user_info['name'],
742
+ 'shared_by_email' =>aoc_api.user_info['email'],
718
743
  'shared_with_name' =>access_id,
719
744
  'access_key' =>node_file[:node_info]['access_key'],
720
745
  'node' =>node_file[:node_info]['name']}
@@ -725,128 +750,136 @@ module Aspera
725
750
  else raise 'unknown command'
726
751
  end
727
752
  when :usage_reports
728
- return {:type=>:object_list,:data=>@api_aoc.read('usage_reports',{:workspace_id=>@workspace_id})[:data]}
753
+ return {type: :object_list,data: aoc_api.read('usage_reports',{workspace_id: @workspace_id})[:data]}
729
754
  end
730
755
  end
731
756
 
732
757
  # must be public
733
- ACTIONS=[ :reminder, :bearer_token, :organization, :tier_restrictions, :user, :workspace, :packages, :files, :gateway, :admin, :automation, :servers]
758
+ ACTIONS=[:reminder, :servers, :bearer_token, :organization, :tier_restrictions, :user, :packages, :files, :admin, :automation, :gateway].freeze
734
759
 
735
760
  def execute_action
736
- command=self.options.get_next_command(ACTIONS)
737
- get_api unless [:reminder,:servers].include?(command)
761
+ command=options.get_next_command(ACTIONS)
738
762
  case command
739
763
  when :reminder
740
764
  # send an email reminder with list of orgs
741
765
  user_email=options.get_option(:username,:mandatory)
742
766
  Rest.new(base_url: "#{AoC.api_base_url}/#{AoC::API_V1}").create('organization_reminders',{email: user_email})[:data]
743
767
  return Main.result_status("List of organizations user is member of, has been sent by e-mail to #{user_email}")
768
+ when :servers
769
+ return {type: :object_list,data: Rest.new(base_url: "#{AoC.api_base_url}/#{AoC::API_V1}").read('servers')[:data]}
744
770
  when :bearer_token
745
- return {:type=>:text,:data=>@api_aoc.oauth_token}
771
+ return {type: :text,data: aoc_api.oauth_token}
746
772
  when :organization
747
- return { :type=>:single_object, :data =>@api_aoc.read('organization')[:data] }
773
+ return { type: :single_object, data: aoc_api.read('organization')[:data] }
748
774
  when :tier_restrictions
749
- return { :type=>:single_object, :data =>@api_aoc.read('tier_restrictions')[:data] }
775
+ return { type: :single_object, data: aoc_api.read('tier_restrictions')[:data] }
750
776
  when :user
751
- command=self.options.get_next_command([ :workspaces,:info,:shared_inboxes ])
752
- case command
777
+ case options.get_next_command([:workspaces,:profile])
778
+ # when :settings
779
+ # return {type: :object_list,data: aoc_api.read('client_settings/')[:data]}
753
780
  when :workspaces
754
- return {:type=>:object_list,:data=>@api_aoc.read('workspaces')[:data],:fields=>['id','name']}
755
- # when :settings
756
- # return {:type=>:object_list,:data=>@api_aoc.read('client_settings/')[:data]}
757
- when :shared_inboxes
758
- query=option_url_query(nil)
759
- if query.nil?
781
+ case options.get_next_command([:list,:current])
782
+ when :list
783
+ return {type: :object_list,data: aoc_api.read('workspaces')[:data],fields: ['id','name']}
784
+ when :current
760
785
  set_workspace_info
761
- query={'embed[]'=>'dropbox','workspace_id'=>@workspace_id,'aggregate_permissions_by_dropbox'=>true,'sort'=>'dropbox_name'}
786
+ return { type: :single_object, data: @workspace_data }
762
787
  end
763
- return {:type=>:object_list,:data=>@api_aoc.read('dropbox_memberships',query)[:data],:fields=>['dropbox_id','dropbox.name']}
764
- when :info
765
- command=self.options.get_next_command([ :show,:modify ])
766
- case command
788
+ when :profile
789
+ case options.get_next_command([:show,:modify])
767
790
  when :show
768
- return { :type=>:single_object, :data =>c_user_info }
791
+ return { type: :single_object, data: aoc_api.user_info }
769
792
  when :modify
770
- @api_aoc.update("users/#{c_user_info['id']}",self.options.get_next_argument('modified parameters (hash)'))
793
+ aoc_api.update("users/#{aoc_api.user_info['id']}",options.get_next_argument('modified parameters (hash)'))
771
794
  return Main.result_status('modified')
772
795
  end
773
796
  end
774
- when :workspace # show current workspace parameters
775
- set_workspace_info
776
- return { :type=>:single_object, :data =>@workspace_data }
777
797
  when :packages
778
798
  set_workspace_info if @url_token_data.nil?
779
- command_pkg=self.options.get_next_command([ :send, :recv, :list, :show, :delete ])
780
- case command_pkg
799
+ case options.get_next_command([:shared_inboxes, :send, :recv, :list, :show, :delete])
800
+ when :shared_inboxes
801
+ case options.get_next_command([:list, :show])
802
+ when :list
803
+ query=option_url_query(nil)
804
+ if query.nil?
805
+ query={'embed[]'=>'dropbox','workspace_id'=>@workspace_id,'aggregate_permissions_by_dropbox'=>true,'sort'=>'dropbox_name'}
806
+ end
807
+ return {type: :object_list,data: aoc_api.read('dropbox_memberships',query)[:data],fields: ['dropbox_id','dropbox.name']}
808
+ when :show
809
+ return {type: :single_object,data: aoc_api.read(get_resource_path_from_args('dropboxes'),query)[:data]}
810
+ end
781
811
  when :send
782
- package_creation=self.options.get_option(:value,:mandatory)
783
- raise CliBadArgument,'value must be hash, refer to doc' unless package_creation.is_a?(Hash)
812
+ package_data=options.get_option(:value,:mandatory)
813
+ raise CliBadArgument,'value must be hash, refer to doc' unless package_data.is_a?(Hash)
784
814
 
785
815
  if !@url_token_data.nil?
786
816
  assert_public_link_types(['send_package_to_user','send_package_to_dropbox'])
787
817
  box_type=@url_token_data['purpose'].split('_').last
788
- package_creation['recipients']=[{'id'=>@url_token_data['data']["#{box_type}_id"],'type'=>box_type}]
818
+ package_data['recipients']=[{'id'=>@url_token_data['data']["#{box_type}_id"],'type'=>box_type}]
789
819
  @workspace_id=@url_token_data['data']['workspace_id']
790
820
  end
791
821
 
792
- package_creation['workspace_id']=@workspace_id
822
+ package_data['workspace_id']=@workspace_id
793
823
 
794
824
  # list of files to include in package, optional
795
- #package_creation['file_names']=self.transfer.ts_source_paths.map{|i|File.basename(i['source'])}
825
+ #package_data['file_names']=self.transfer.ts_source_paths.map{|i|File.basename(i['source'])}
796
826
 
797
827
  # lookup users
798
- resolve_package_recipients(package_creation,'recipients')
799
- resolve_package_recipients(package_creation,'bcc_recipients')
828
+ resolve_package_recipients(package_data,'recipients')
829
+ resolve_package_recipients(package_data,'bcc_recipients')
830
+ normalize_metadata(package_data)
800
831
 
801
832
  # create a new package container
802
- package_info=@api_aoc.create('packages',package_creation)[:data]
833
+ package_info=aoc_api.create('packages',package_data)[:data]
803
834
 
804
835
  # get node information for the node on which package must be created
805
- node_info=@api_aoc.read("nodes/#{package_info['node_id']}")[:data]
836
+ node_info=aoc_api.read("nodes/#{package_info['node_id']}")[:data]
806
837
 
807
- # tell Aspera what to expect in package: 1 transfer (can also be done after transfer)
808
- @api_aoc.update("packages/#{package_info['id']}",{'sent'=>true,'transfers_expected'=>1})[:data]
838
+ # tell AoC what to expect in package: 1 transfer (can also be done after transfer)
839
+ # TODO: if multisession was used we should probably tell
840
+ # also, currently no "multi-source" , i.e. only from client-side files, unless "node" agent is used
841
+ aoc_api.update("packages/#{package_info['id']}",{'sent'=>true,'transfers_expected'=>1})[:data]
809
842
 
810
- # execute transfer
843
+ # get destination: package folder
811
844
  node_file = {node_info: node_info, file_id: package_info['contents_file_id']}
812
- # raise exception if at least one error
813
- Main.result_transfer(transfer_start(AoC::PACKAGES_APP,'send',node_file,AoC.package_tags(package_info,'upload')))
845
+ # execute transfer, raise exception if at least one error
846
+ Main.result_transfer(transfer_start(AoC::PACKAGES_APP,Fasp::TransferSpec::DIRECTION_SEND,node_file,AoC.package_tags(package_info,'upload')))
814
847
  # return all info on package
815
- return { :type=>:single_object, :data =>package_info}
848
+ return { type: :single_object, data: package_info}
816
849
  when :recv
817
850
  if !@url_token_data.nil?
818
851
  assert_public_link_types(['view_received_package'])
819
- self.options.set_option(:id,@url_token_data['data']['package_id'])
852
+ options.set_option(:id,@url_token_data['data']['package_id'])
820
853
  end
821
854
  # scalar here
822
- ids_to_download=self.options.get_option(:id,:mandatory)
855
+ ids_to_download=instance_identifier()
823
856
  skip_ids_data=[]
824
857
  skip_ids_persistency=nil
825
- if self.options.get_option(:once_only,:mandatory)
858
+ if options.get_option(:once_only,:mandatory)
826
859
  skip_ids_persistency=PersistencyActionOnce.new(
827
860
  manager: @agents[:persistency],
828
861
  data: skip_ids_data,
829
- id: IdGenerator.from_list(['aoc_recv',self.options.get_option(:url,:mandatory),@workspace_id].push(*@persist_ids)))
862
+ id: IdGenerator.from_list(['aoc_recv',options.get_option(:url,:mandatory),@workspace_id].push(*@persist_ids)))
830
863
  end
831
864
  if ids_to_download.eql?(VAL_ALL)
832
865
  # get list of packages in inbox
833
- package_info=@api_aoc.read('packages',{'archived'=>false,'exclude_dropbox_packages'=>true,'has_content'=>true,'received'=>true,'workspace_id'=>@workspace_id})[:data]
866
+ package_info=aoc_api.read('packages',{'archived'=>false,'exclude_dropbox_packages'=>true,'has_content'=>true,'received'=>true,'workspace_id'=>@workspace_id})[:data]
834
867
  # remove from list the ones already downloaded
835
868
  ids_to_download=package_info.map{|e|e['id']}
836
869
  # array here
837
- ids_to_download.select!{|id|!skip_ids_data.include?(id)}
870
+ ids_to_download.reject!{|id|skip_ids_data.include?(id)}
838
871
  end # ALL
839
872
  # list here
840
873
  ids_to_download = [ids_to_download] unless ids_to_download.is_a?(Array)
841
874
  result_transfer=[]
842
875
  self.format.display_status("found #{ids_to_download.length} package(s).")
843
876
  ids_to_download.each do |package_id|
844
- package_info=@api_aoc.read("packages/#{package_id}")[:data]
845
- node_info=@api_aoc.read("nodes/#{package_info['node_id']}")[:data]
877
+ package_info=aoc_api.read("packages/#{package_id}")[:data]
878
+ node_info=aoc_api.read("nodes/#{package_info['node_id']}")[:data]
846
879
  self.format.display_status("downloading package: #{package_info['name']}")
847
880
  add_ts={'paths'=>[{'source'=>'.'}]}
848
881
  node_file = {node_info: node_info, file_id: package_info['contents_file_id']}
849
- statuses=transfer_start(AoC::PACKAGES_APP,'receive',node_file,AoC.package_tags(package_info,'download').merge(add_ts))
882
+ statuses=transfer_start(AoC::PACKAGES_APP,Fasp::TransferSpec::DIRECTION_RECEIVE,node_file,AoC.package_tags(package_info,'download').merge(add_ts))
850
883
  result_transfer.push({'package'=>package_id,Main::STATUS_FIELD=>statuses})
851
884
  # update skip list only if all transfer sessions completed
852
885
  if TransferAgent.session_status(statuses).eql?(:success)
@@ -856,51 +889,55 @@ module Aspera
856
889
  end
857
890
  return Main.result_transfer_multiple(result_transfer)
858
891
  when :show
859
- package_id=self.options.get_next_argument('package ID')
860
- package_info=@api_aoc.read("packages/#{package_id}")[:data]
861
- return { :type=>:single_object, :data =>package_info }
892
+ package_id=options.get_next_argument('package ID')
893
+ package_info=aoc_api.read("packages/#{package_id}")[:data]
894
+ return { type: :single_object, data: package_info }
862
895
  when :list
863
896
  query=option_url_query({'archived'=>false,'exclude_dropbox_packages'=>true,'has_content'=>true,'received'=>true})
897
+ if query.has_key?('dropbox_name')
898
+ # convenience: specify name instead of id
899
+ raise 'not both dropbox_name and dropbox_id' if query.has_key?('dropbox_id')
900
+ query['dropbox_id']=aoc_api.lookup_entity_by_name('dropboxes',query['dropbox_name'])['id']
901
+ query.delete('dropbox_name')
902
+ end
864
903
  raise 'option must be Hash' unless query.is_a?(Hash)
865
904
  query['workspace_id']||=@workspace_id
866
- packages=@api_aoc.read('packages',query)[:data]
867
- return {:type=>:object_list,:data=>packages,:fields=>['id','name','bytes_transferred']}
905
+ packages=aoc_api.read('packages',query)[:data]
906
+ return {type: :object_list,data: packages,fields: ['id','name','bytes_transferred']}
868
907
  when :delete
869
- list_or_one=self.options.get_option(:id,:mandatory)
870
- return do_bulk_operation(list_or_one,'deleted')do|id|
871
- raise 'expecting String identifier' unless id.is_a?(String) or id.is_a?(Integer)
872
- @api_aoc.delete("packages/#{id}")[:data]
908
+ list_or_one=instance_identifier()
909
+ return do_bulk_operation(list_or_one,'deleted') do |id|
910
+ raise 'expecting String identifier' unless id.is_a?(String) || id.is_a?(Integer)
911
+ aoc_api.delete("packages/#{id}")[:data]
873
912
  end
874
913
  end
875
914
  when :files
876
915
  # get workspace related information
877
916
  set_workspace_info
878
917
  set_home_node_file
879
- command_repo=self.options.get_next_command(NODE4_COMMANDS.clone.concat([:short_link]))
918
+ command_repo=options.get_next_command([NODE4_COMMANDS,:short_link].flatten)
880
919
  case command_repo
881
- when *NODE4_COMMANDS; return execute_node_gen4_command(command_repo,@home_node_file)
920
+ when *NODE4_COMMANDS then return execute_node_gen4_command(command_repo,@home_node_file)
882
921
  when :short_link
883
- folder_dest=self.options.get_option(:to_folder,:optional)
884
- value_option=self.options.get_option(:value,:optional)
922
+ folder_dest=options.get_option(:to_folder,:optional)
923
+ value_option=options.get_option(:value,:optional)
885
924
  case value_option
886
- when 'public'
887
- value_option={'purpose'=>'token_auth_redirection'}
888
- when 'private'
889
- value_option={'purpose'=>'shared_folder_auth_link'}
890
- when NilClass,Hash
925
+ when 'public' then value_option={'purpose'=>'token_auth_redirection'}
926
+ when 'private' then value_option={'purpose'=>'shared_folder_auth_link'}
927
+ when NilClass,Hash then nil # keep value
891
928
  else raise 'value must be either: public, private, Hash or nil'
892
929
  end
893
930
  create_params=nil
894
931
  node_file=nil
895
932
  if !folder_dest.nil?
896
- node_file = @api_aoc.resolve_node_file(@home_node_file,folder_dest)
933
+ node_file = aoc_api.resolve_node_file(@home_node_file,folder_dest)
897
934
  create_params={
898
935
  file_id: node_file[:file_id],
899
936
  node_id: node_file[:node_info]['id'],
900
937
  workspace_id: @workspace_id
901
938
  }
902
939
  end
903
- if !value_option.nil? and !create_params.nil?
940
+ if !value_option.nil? && !create_params.nil?
904
941
  case value_option['purpose']
905
942
  when 'shared_folder_auth_link'
906
943
  value_option['data']=create_params
@@ -918,11 +955,11 @@ module Aspera
918
955
  else
919
956
  raise 'purpose must be one of: token_auth_redirection or shared_folder_auth_link'
920
957
  end
921
- self.options.set_option(:value,value_option)
958
+ options.set_option(:value,value_option)
922
959
  end
923
- result=self.entity_action(@api_aoc,'short_links',nil,:id,'self')
924
- if result[:data].is_a?(Hash) and result[:data].has_key?('created_at') and result[:data]['resource_type'].eql?('UrlToken')
925
- node_api=@api_aoc.get_node_api(node_file[:node_info],scope: AoC::SCOPE_NODE_USER)
960
+ result=entity_action(@api_aoc,'short_links',id_default: 'self')
961
+ if result[:data].is_a?(Hash) && result[:data].has_key?('created_at') && result[:data]['resource_type'].eql?('UrlToken')
962
+ node_api=aoc_api.get_node_api(node_file[:node_info])
926
963
  # TODO: access level as arg
927
964
  access_levels=Aspera::Node::ACCESS_LEVELS #['delete','list','mkdir','preview','read','rename','write']
928
965
  perm_data={
@@ -935,8 +972,8 @@ module Aspera
935
972
  'workspace_id' =>@workspace_id,
936
973
  'workspace_name' =>@workspace_name,
937
974
  'folder_name' =>'my folder',
938
- 'created_by_name' =>c_user_info['name'],
939
- 'created_by_email'=>c_user_info['email'],
975
+ 'created_by_name' =>aoc_api.user_info['name'],
976
+ 'created_by_email'=>aoc_api.user_info['email'],
940
977
  'access_key' =>node_file[:node_info]['access_key'],
941
978
  'node' =>node_file[:node_info]['host']
942
979
  }
@@ -950,51 +987,49 @@ module Aspera
950
987
  when :automation
951
988
  Log.log.warn('BETA: work under progress')
952
989
  # automation api is not in the same place
953
- automation_rest_params=@api_aoc.params.clone
990
+ automation_rest_params=aoc_api.params.clone
954
991
  automation_rest_params[:base_url].gsub!('/api/','/automation/')
955
992
  automation_api=Rest.new(automation_rest_params)
956
- command_automation=self.options.get_next_command([ :workflows, :instances ])
993
+ command_automation=options.get_next_command([:workflows, :instances])
957
994
  case command_automation
958
995
  when :instances
959
- return self.entity_action(@api_aoc,'workflow_instances',nil,:id,nil)
996
+ return entity_action(@api_aoc,'workflow_instances')
960
997
  when :workflows
961
- wF_COMMANDS=Plugin::ALL_OPS.clone.push(:action,:launch)
962
- wf_command=self.options.get_next_command(wF_COMMANDS)
998
+ wf_command=options.get_next_command([Plugin::ALL_OPS,:action,:launch].flatten)
963
999
  case wf_command
964
1000
  when *Plugin::ALL_OPS
965
- return self.entity_command(wf_command,automation_api,'workflows',nil,:id)
1001
+ return entity_command(wf_command,automation_api,'workflows',id_default: :id)
966
1002
  when :launch
967
- wf_id=self.options.get_option(:id,:mandatory)
1003
+ wf_id=instance_identifier()
968
1004
  data=automation_api.create("workflows/#{wf_id}/launch",{})[:data]
969
- return {:type=>:single_object,:data=>data}
1005
+ return {type: :single_object,data: data}
970
1006
  when :action
971
- wf_command=self.options.get_next_command([:list,:create,:show])
972
- wf_id=self.options.get_option(:id,:mandatory)
1007
+ #TODO: not complete
1008
+ wf_id=instance_identifier()
1009
+ wf_action_cmd=options.get_next_command([:list,:create,:show])
1010
+ Log.log.warn("Not implemented: #{wf_action_cmd}")
973
1011
  step=automation_api.create('steps',{'workflow_id'=>wf_id})[:data]
974
1012
  automation_api.update("workflows/#{wf_id}",{'step_order'=>[step['id']]})
975
1013
  action=automation_api.create('actions',{'step_id'=>step['id'],'type'=>'manual'})[:data]
976
1014
  automation_api.update("steps/#{step['id']}",{'action_order'=>[action['id']]})
977
1015
  wf=automation_api.read("workflows/#{wf_id}")[:data]
978
- return {:type=>:single_object,:data=>wf}
1016
+ return {type: :single_object,data: wf}
979
1017
  end
980
1018
  end
1019
+ when :admin
1020
+ return execute_admin_action
981
1021
  when :gateway
982
1022
  set_workspace_info
983
1023
  require 'aspera/faspex_gw'
984
1024
  FaspexGW.new(@api_aoc,@workspace_id).start_server
985
- when :admin
986
- return execute_admin_action
987
- when :servers
988
- return {:type=>:object_list,:data=>Rest.new(base_url: "#{AoC.api_base_url}/#{AoC::API_V1}").read('servers')[:data]}
989
1025
  else
990
1026
  raise "internal error: #{command}"
991
1027
  end # action
992
- raise RuntimeError, 'internal error: command shall return'
1028
+ raise 'internal error: command shall return'
993
1029
  end
994
1030
 
995
- private :c_user_info,:aoc_params,:set_workspace_info,:set_home_node_file,:do_bulk_operation,:resolve_package_recipients,:option_url_query,:assert_public_link_types,:execute_admin_action
996
- private_constant :VAL_ALL,:NODE4_COMMANDS
997
-
1031
+ private :aoc_params,:set_workspace_info,:set_home_node_file,:do_bulk_operation,:resolve_package_recipients,:option_url_query,:assert_public_link_types,:execute_admin_action
1032
+ private_constant :VAL_ALL,:NODE4_COMMANDS, :ID_AK_ADMIN
998
1033
  end # AoC
999
1034
  end # Plugins
1000
1035
  end # Cli