aspera-cli 4.2.1 → 4.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +187 -127
- data/docs/Makefile +4 -4
- data/docs/README.erb.md +206 -38
- data/docs/test_env.conf +2 -1
- data/examples/faspex4.rb +28 -17
- data/lib/aspera/cli/main.rb +47 -19
- data/lib/aspera/cli/plugins/aoc.rb +5 -13
- data/lib/aspera/cli/plugins/config.rb +47 -30
- data/lib/aspera/cli/plugins/faspex.rb +90 -52
- data/lib/aspera/cli/plugins/faspex5.rb +8 -7
- data/lib/aspera/cli/plugins/preview.rb +29 -25
- data/lib/aspera/cli/transfer_agent.rb +71 -44
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/command_line_builder.rb +49 -31
- data/lib/aspera/fasp/parameters.rb +57 -87
- data/lib/aspera/fasp/parameters.yaml +531 -0
- data/lib/aspera/fasp/uri.rb +1 -1
- data/lib/aspera/oauth.rb +4 -4
- data/lib/aspera/sync.rb +40 -35
- metadata +17 -3
- data/docs/transfer_spec.html +0 -99
|
@@ -39,7 +39,6 @@ module Aspera
|
|
|
39
39
|
self.options.add_opt_simple(:new_user_option,'new user creation option')
|
|
40
40
|
self.options.add_opt_simple(:from_folder,'share to share source folder')
|
|
41
41
|
self.options.add_opt_simple(:scope,'OAuth scope for AoC API calls')
|
|
42
|
-
self.options.add_opt_simple(:notify,'notify users that file was received')
|
|
43
42
|
self.options.add_opt_boolean(:bulk,'bulk operation')
|
|
44
43
|
self.options.add_opt_boolean(:default_ports,'use standard FASP ports or get from node api')
|
|
45
44
|
self.options.set_option(:bulk,:no)
|
|
@@ -527,18 +526,11 @@ module Aspera
|
|
|
527
526
|
filter['start_time'] = start_datetime unless start_datetime.nil?
|
|
528
527
|
filter['stop_time'] = stop_datetime
|
|
529
528
|
end
|
|
530
|
-
notification=self.options.get_option(:notify,:optional)
|
|
531
529
|
events=analytics_api.read("#{filter_resource}/#{filter_id}/#{event_type}",option_url_query(filter))[:data][event_type]
|
|
532
530
|
startdate_persistency.save unless startdate_persistency.nil?
|
|
533
|
-
if !
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
email_to_send={}
|
|
537
|
-
notification.each do |k,v|
|
|
538
|
-
email_to_send[k.to_sym]=ERB.new(v).result(binding)
|
|
539
|
-
end
|
|
540
|
-
Log.log().error("send email: #{email_to_send}")
|
|
541
|
-
self.config.send_email(email_to_send)
|
|
531
|
+
if !self.options.get_option(:notif_to,:optional).nil?
|
|
532
|
+
events.each do |tr_event|
|
|
533
|
+
self.config.send_email_template({ev: tr_event})
|
|
542
534
|
end
|
|
543
535
|
end
|
|
544
536
|
return {:type=>:object_list,:data=>events}
|
|
@@ -810,14 +802,14 @@ module Aspera
|
|
|
810
802
|
add_ts={'paths'=>[{'source'=>'.'}]}
|
|
811
803
|
node_file = {node_info: node_info, file_id: package_info['contents_file_id']}
|
|
812
804
|
statuses=transfer_start(AoC::PACKAGES_APP,'receive',node_file,AoC.package_tags(package_info,'download').merge(add_ts))
|
|
813
|
-
result_transfer.push({'package'=>package_id,
|
|
805
|
+
result_transfer.push({'package'=>package_id,Main::STATUS_FIELD=>statuses})
|
|
814
806
|
# update skip list only if all transfer sessions completed
|
|
815
807
|
if TransferAgent.session_status(statuses).eql?(:success)
|
|
816
808
|
skip_ids_data.push(package_id)
|
|
817
809
|
skip_ids_persistency.save unless skip_ids_persistency.nil?
|
|
818
810
|
end
|
|
819
811
|
end
|
|
820
|
-
return
|
|
812
|
+
return Main.result_transfer_multiple(result_transfer)
|
|
821
813
|
when :show
|
|
822
814
|
package_id=self.options.get_next_argument('package ID')
|
|
823
815
|
package_info=@api_aoc.read("packages/#{package_id}")[:data]
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
require 'aspera/cli/basic_auth_plugin'
|
|
2
2
|
require 'aspera/cli/extended_value'
|
|
3
3
|
require 'aspera/fasp/installation'
|
|
4
|
+
require 'aspera/fasp/parameters'
|
|
4
5
|
require 'aspera/api_detector'
|
|
5
6
|
require 'aspera/open_application'
|
|
6
7
|
require 'aspera/aoc'
|
|
@@ -13,6 +14,7 @@ require 'base64'
|
|
|
13
14
|
require 'net/smtp'
|
|
14
15
|
require 'open3'
|
|
15
16
|
require 'date'
|
|
17
|
+
require 'erb'
|
|
16
18
|
|
|
17
19
|
module Aspera
|
|
18
20
|
module Cli
|
|
@@ -48,13 +50,20 @@ module Aspera
|
|
|
48
50
|
DEMO='demo'
|
|
49
51
|
DEMO_SERVER_PRESET='demoserver'
|
|
50
52
|
AOC_PATH_API_CLIENTS='admin/api-clients'
|
|
53
|
+
EMAIL_TEST_TEMPLATE=<<END_OF_TEMPLATE
|
|
54
|
+
From: <%=from_name%> <<%=from_email%>>
|
|
55
|
+
To: <<%=to%>>
|
|
56
|
+
Subject: Amelia email test
|
|
57
|
+
|
|
58
|
+
It worked !
|
|
59
|
+
END_OF_TEMPLATE
|
|
51
60
|
def option_preset; nil; end
|
|
52
61
|
|
|
53
62
|
def option_preset=(value)
|
|
54
63
|
self.options.add_option_preset(preset_by_name(value))
|
|
55
64
|
end
|
|
56
65
|
|
|
57
|
-
private_constant :DEFAULT_CONFIG_FILENAME,:CONF_PRESET_CONFIG,:CONF_PRESET_VERSION,:CONF_PRESET_DEFAULT,:CONF_PRESET_GLOBAL,:PROGRAM_NAME_V1,:PROGRAM_NAME_V2,:DEFAULT_REDIRECT,:ASPERA_PLUGINS_FOLDERNAME,:RUBY_FILE_EXT,:AOC_COMMAND_V1,:AOC_COMMAND_V2,:AOC_COMMAND_V3,:AOC_COMMAND_CURRENT,:DEMO,:TRANSFER_SDK_ARCHIVE_URL,:AOC_PATH_API_CLIENTS,:DEMO_SERVER_PRESET
|
|
66
|
+
private_constant :DEFAULT_CONFIG_FILENAME,:CONF_PRESET_CONFIG,:CONF_PRESET_VERSION,:CONF_PRESET_DEFAULT,:CONF_PRESET_GLOBAL,:PROGRAM_NAME_V1,:PROGRAM_NAME_V2,:DEFAULT_REDIRECT,:ASPERA_PLUGINS_FOLDERNAME,:RUBY_FILE_EXT,:AOC_COMMAND_V1,:AOC_COMMAND_V2,:AOC_COMMAND_V3,:AOC_COMMAND_CURRENT,:DEMO,:TRANSFER_SDK_ARCHIVE_URL,:AOC_PATH_API_CLIENTS,:DEMO_SERVER_PRESET,:EMAIL_TEST_TEMPLATE
|
|
58
67
|
|
|
59
68
|
def initialize(env,tool_name,help_url,version,main_folder)
|
|
60
69
|
super(env)
|
|
@@ -103,6 +112,8 @@ module Aspera
|
|
|
103
112
|
self.options.add_opt_simple(:secrets,'secret repository (Hash)')
|
|
104
113
|
self.options.add_opt_simple(:sdk_url,'URL to get SDK')
|
|
105
114
|
self.options.add_opt_simple(:sdk_folder,'SDK folder location')
|
|
115
|
+
self.options.add_opt_simple(:notif_to,'email recipient for notification of transfers')
|
|
116
|
+
self.options.add_opt_simple(:notif_template,'email ERB template for notification of transfers')
|
|
106
117
|
self.options.add_opt_boolean(:test_mode,'skip user validation in wizard mode')
|
|
107
118
|
self.options.add_opt_simple(:version_check_days,Integer,'period to check neew version in days (zero to disable)')
|
|
108
119
|
self.options.set_option(:use_generic_client,true)
|
|
@@ -465,7 +476,7 @@ module Aspera
|
|
|
465
476
|
end
|
|
466
477
|
|
|
467
478
|
def execute_action_ascp
|
|
468
|
-
command=self.options.get_next_command([:connect,:use,:show,:products,:info,:install])
|
|
479
|
+
command=self.options.get_next_command([:connect,:use,:show,:products,:info,:install,:spec])
|
|
469
480
|
case command
|
|
470
481
|
when :connect
|
|
471
482
|
return execute_connect_action
|
|
@@ -516,6 +527,8 @@ module Aspera
|
|
|
516
527
|
when :install
|
|
517
528
|
v=Fasp::Installation.instance.install_sdk(self.options.get_option(:sdk_url,:mandatory))
|
|
518
529
|
return Main.result_status("Installed version #{v}")
|
|
530
|
+
when :spec
|
|
531
|
+
return {type: :object_list, data: Fasp::Parameters.man_table, fields: ['name','type',Fasp::Parameters::SUPPORTED_AGENTS_SHORT.map{|i|i.to_s},'description'].flatten}
|
|
519
532
|
end
|
|
520
533
|
raise "unexpected case: #{command}"
|
|
521
534
|
end
|
|
@@ -788,12 +801,7 @@ module Aspera
|
|
|
788
801
|
when :file
|
|
789
802
|
return Main.result_status(@option_config_file)
|
|
790
803
|
when :email_test
|
|
791
|
-
|
|
792
|
-
send_email({
|
|
793
|
-
to: dest_email,
|
|
794
|
-
subject: 'Amelia email test',
|
|
795
|
-
body: 'It worked !',
|
|
796
|
-
})
|
|
804
|
+
send_email_template({},EMAIL_TEST_TEMPLATE)
|
|
797
805
|
return Main.result_nothing
|
|
798
806
|
when :smtp_settings
|
|
799
807
|
return {:type=>:single_object,:data=>email_settings}
|
|
@@ -824,9 +832,10 @@ module Aspera
|
|
|
824
832
|
end
|
|
825
833
|
end
|
|
826
834
|
|
|
835
|
+
# @return email server setting with defaults if not defined
|
|
827
836
|
def email_settings
|
|
828
837
|
smtp=self.options.get_option(:smtp,:mandatory)
|
|
829
|
-
# change string keys into
|
|
838
|
+
# change string keys into symbol keys
|
|
830
839
|
smtp=smtp.keys.inject({}){|m,v|m[v.to_sym]=smtp[v];m}
|
|
831
840
|
# defaults
|
|
832
841
|
smtp[:tls]||=true
|
|
@@ -836,34 +845,42 @@ module Aspera
|
|
|
836
845
|
smtp[:domain]||=smtp[:from_email].gsub(/^.*@/,'') if smtp.has_key?(:from_email)
|
|
837
846
|
# check minimum required
|
|
838
847
|
[:server,:port,:domain].each do |n|
|
|
839
|
-
raise "
|
|
848
|
+
raise "Missing smtp parameter: #{n}" unless smtp.has_key?(n)
|
|
840
849
|
end
|
|
841
850
|
Log.log.debug("smtp=#{smtp}")
|
|
842
851
|
return smtp
|
|
843
852
|
end
|
|
844
853
|
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
854
|
+
# create a clean binding (ruby variable environment)
|
|
855
|
+
def empty_binding
|
|
856
|
+
Kernel.binding
|
|
857
|
+
end
|
|
858
|
+
|
|
859
|
+
def send_email_template(vars,email_template_default=nil)
|
|
860
|
+
vars[:to]||=options.get_option(:notif_to,:mandatory)
|
|
861
|
+
notif_template=options.get_option(:notif_template,email_template_default.nil? ? :mandatory : :optional) || email_template_default
|
|
862
|
+
mail_conf=email_settings
|
|
863
|
+
vars[:from_name]||=mail_conf[:from_name]
|
|
864
|
+
vars[:from_email]||=mail_conf[:from_email]
|
|
865
|
+
[:from_name,:from_email].each do |n|
|
|
866
|
+
raise "Missing email parameter: #{n}" unless vars.has_key?(n)
|
|
867
|
+
end
|
|
868
|
+
start_options=[mail_conf[:domain]]
|
|
869
|
+
start_options.push(mail_conf[:username],mail_conf[:password],:login) if mail_conf.has_key?(:username) and mail_conf.has_key?(:password)
|
|
870
|
+
# create a binding with only variables defined in vars
|
|
871
|
+
template_binding=empty_binding
|
|
872
|
+
# add variables to binding
|
|
873
|
+
vars.each do |k,v|
|
|
874
|
+
raise "key (#{k.class}) must be Symbol" unless k.is_a?(Symbol)
|
|
875
|
+
template_binding.local_variable_set(k,v)
|
|
852
876
|
end
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
#{email[:body]}
|
|
859
|
-
END_OF_MESSAGE
|
|
860
|
-
start_options=[opts[:domain]]
|
|
861
|
-
start_options.push(opts[:username],opts[:password],:login) if opts.has_key?(:username) and opts.has_key?(:password)
|
|
862
|
-
|
|
863
|
-
smtp = Net::SMTP.new(opts[:server], opts[:port])
|
|
864
|
-
smtp.enable_starttls if opts[:tls]
|
|
877
|
+
# execute template
|
|
878
|
+
msg_with_headers=ERB.new(notif_template).result(template_binding)
|
|
879
|
+
Log.dump(:msg_with_headers,msg_with_headers)
|
|
880
|
+
smtp = Net::SMTP.new(mail_conf[:server], mail_conf[:port])
|
|
881
|
+
smtp.enable_starttls if mail_conf[:tls]
|
|
865
882
|
smtp.start(*start_options) do |smtp|
|
|
866
|
-
smtp.send_message(
|
|
883
|
+
smtp.send_message(msg_with_headers, vars[:from_email], vars[:to])
|
|
867
884
|
end
|
|
868
885
|
end
|
|
869
886
|
|
|
@@ -9,6 +9,7 @@ require 'aspera/fasp/uri'
|
|
|
9
9
|
require 'aspera/nagios'
|
|
10
10
|
require 'xmlsimple'
|
|
11
11
|
require 'json'
|
|
12
|
+
require 'cgi'
|
|
12
13
|
|
|
13
14
|
module Aspera
|
|
14
15
|
module Cli
|
|
@@ -17,7 +18,17 @@ module Aspera
|
|
|
17
18
|
KEY_NODE='node'
|
|
18
19
|
KEY_PATH='path'
|
|
19
20
|
VAL_ALL='ALL'
|
|
20
|
-
|
|
21
|
+
# added field in result that identifies the package
|
|
22
|
+
PACKAGE_MATCH_FIELD='package_id'
|
|
23
|
+
# list of supported atoms
|
|
24
|
+
ATOM_MAILBOXES=[:inbox, :archive, :sent]
|
|
25
|
+
# number is added by CLI
|
|
26
|
+
MAX_ITEMS='max'
|
|
27
|
+
MAX_PAGES='pmax'
|
|
28
|
+
ATOM_PARAMS=['page', 'count', 'startIndex', MAX_ITEMS, MAX_PAGES]
|
|
29
|
+
PUB_LINK_EXTERNAL_MATCH='external_deliveries/'
|
|
30
|
+
private_constant :KEY_NODE,:KEY_PATH,:VAL_ALL,:PACKAGE_MATCH_FIELD,:ATOM_MAILBOXES,:PUB_LINK_EXTERNAL_MATCH
|
|
31
|
+
|
|
21
32
|
def initialize(env)
|
|
22
33
|
@api_v3=nil
|
|
23
34
|
@api_v4=nil
|
|
@@ -27,7 +38,7 @@ module Aspera
|
|
|
27
38
|
self.options.add_opt_simple(:source_name,'create package from remote source (by name)')
|
|
28
39
|
self.options.add_opt_simple(:storage,'Faspex local storage definition')
|
|
29
40
|
self.options.add_opt_simple(:recipient,'use if recipient is a dropbox (with *)')
|
|
30
|
-
self.options.add_opt_list(:box,
|
|
41
|
+
self.options.add_opt_list(:box,ATOM_MAILBOXES,'package box')
|
|
31
42
|
self.options.set_option(:box,:inbox)
|
|
32
43
|
self.options.parse_options!
|
|
33
44
|
end
|
|
@@ -102,29 +113,57 @@ module Aspera
|
|
|
102
113
|
return @api_v4
|
|
103
114
|
end
|
|
104
115
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
# we match recv command on atom feed on this field
|
|
108
|
-
PACKAGE_MATCH_FIELD='package_id'
|
|
109
|
-
|
|
116
|
+
# query supports : {"startIndex":10,"count":1,"page":109}
|
|
110
117
|
def mailbox_all_entries
|
|
111
118
|
recipient_name=self.options.get_option(:recipient,:optional) || self.options.get_option(:username,:mandatory)
|
|
119
|
+
# mailbox is in ATOM_MAILBOXES
|
|
112
120
|
mailbox=self.options.get_option(:box,:mandatory)
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
result
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
121
|
+
# parameters
|
|
122
|
+
mailbox_query=self.options.get_option(:query,:optional)
|
|
123
|
+
max_items=nil
|
|
124
|
+
max_pages=nil
|
|
125
|
+
result=[]
|
|
126
|
+
if !mailbox_query.nil?
|
|
127
|
+
raise "query: must be Hash or nil" unless mailbox_query.is_a?(Hash)
|
|
128
|
+
raise "query: supported params: #{ATOM_PARAMS}" unless (mailbox_query.keys-ATOM_PARAMS).empty?
|
|
129
|
+
raise "query: startIndex and page are exclusive" if mailbox_query.has_key?('startIndex') and mailbox_query.has_key?('page')
|
|
130
|
+
max_items=mailbox_query[MAX_ITEMS]
|
|
131
|
+
mailbox_query.delete(MAX_ITEMS)
|
|
132
|
+
max_pages=mailbox_query[MAX_PAGES]
|
|
133
|
+
mailbox_query.delete(MAX_PAGES)
|
|
134
|
+
end
|
|
135
|
+
loop do
|
|
136
|
+
atom_xml=api_v3.call({operation: 'GET',subpath: "#{mailbox}.atom",headers: {'Accept'=>'application/xml'},url_params: mailbox_query})[:http].body
|
|
137
|
+
box_data=XmlSimple.xml_in(atom_xml, {'ForceArray' => true})
|
|
138
|
+
Log.dump(:box_data,box_data)
|
|
139
|
+
items=box_data.has_key?('entry') ? box_data['entry'] : []
|
|
140
|
+
Log.log.debug("new items: #{items.count}")
|
|
141
|
+
# it is the end if page is empty
|
|
142
|
+
break if items.empty?
|
|
143
|
+
items.each do |package|
|
|
144
|
+
package[PACKAGE_MATCH_FIELD]=case mailbox
|
|
145
|
+
when :inbox,:archive
|
|
146
|
+
recipient=package['to'].select{|i|i['name'].first.eql?(recipient_name)}.first
|
|
147
|
+
recipient.nil? ? nil : recipient['recipient_delivery_id'].first
|
|
148
|
+
else # :sent
|
|
149
|
+
package['delivery_id'].first
|
|
150
|
+
end
|
|
151
|
+
# keep only those for the specified recipient
|
|
152
|
+
result.push(package) unless package[PACKAGE_MATCH_FIELD].nil?
|
|
124
153
|
end
|
|
154
|
+
Log.log.debug("total items: #{result.count}")
|
|
155
|
+
# reach the limit ?
|
|
156
|
+
break if !max_items.nil? and result.count > max_items
|
|
157
|
+
link=box_data['link'].select{|i|i['rel'].eql?('next')}.first
|
|
158
|
+
Log.log.debug("link: #{link}")
|
|
159
|
+
# no next link
|
|
160
|
+
break if link.nil?
|
|
161
|
+
# replace parameters with the ones from next link
|
|
162
|
+
params=CGI.parse(URI.parse(link['href']).query)
|
|
163
|
+
mailbox_query=params.keys.inject({}){|m,i|;m[i]=params[i].first;m}
|
|
164
|
+
Log.log.debug("query: #{mailbox_query}")
|
|
165
|
+
break if !max_pages.nil? and mailbox_query['page'].to_i > max_pages
|
|
125
166
|
end
|
|
126
|
-
# remove dropbox packages
|
|
127
|
-
result.select!{|p|p['metadata'].first['field'].select{|j|j['name'].eql?('_dropbox_name')}.empty? rescue false}
|
|
128
167
|
return result
|
|
129
168
|
end
|
|
130
169
|
|
|
@@ -160,6 +199,8 @@ module Aspera
|
|
|
160
199
|
return pkgdatares.first
|
|
161
200
|
end
|
|
162
201
|
|
|
202
|
+
ACTIONS=[ :health,:package, :source, :me, :dropbox, :v4, :address_book, :login_methods ]
|
|
203
|
+
|
|
163
204
|
def execute_action
|
|
164
205
|
command=self.options.get_next_command(ACTIONS)
|
|
165
206
|
case command
|
|
@@ -215,44 +256,26 @@ module Aspera
|
|
|
215
256
|
skip_ids_data=[]
|
|
216
257
|
skip_ids_persistency=nil
|
|
217
258
|
case link_url
|
|
218
|
-
when nil
|
|
219
|
-
# usual case: no link
|
|
220
|
-
when /^faspe:/
|
|
221
|
-
pkg_id_uri=[{:id=>'package',:uri=>link_url}]
|
|
222
|
-
else
|
|
223
|
-
link_data=self.class.get_link_data(link_url)
|
|
224
|
-
if !link_data[:subpath].match(%r{external_deliveries/})
|
|
225
|
-
raise CliBadArgument,"pub link is #{link_data[:subpath]}, expecting external_deliveries/"
|
|
226
|
-
end
|
|
227
|
-
# Note: unauthenticated API
|
|
228
|
-
api_public_link=Rest.new({:base_url=>link_data[:base_url]})
|
|
229
|
-
pkgdatares=api_public_link.call({:operation=>'GET',:subpath=>link_data[:subpath],:url_params=>{:passcode=>link_data[:query]['passcode']},:headers=>{'Accept'=>'application/xml'}})
|
|
230
|
-
if !pkgdatares[:http].body.start_with?('<?xml ')
|
|
231
|
-
OpenApplication.instance.uri(link_url)
|
|
232
|
-
raise CliError, 'no such package'
|
|
233
|
-
end
|
|
234
|
-
package_entry=XmlSimple.xml_in(pkgdatares[:http].body, {'ForceArray' => false})
|
|
235
|
-
transfer_uri=self.class.get_fasp_uri_from_entry(package_entry)
|
|
236
|
-
transfer_spec=Fasp::Uri.new(transfer_uri).transfer_spec
|
|
237
|
-
transfer_spec['direction']='receive'
|
|
238
|
-
return Main.result_transfer(self.transfer.start(transfer_spec,{:src=>:node_gen3}))
|
|
239
|
-
end # public link
|
|
240
|
-
if pkg_id_uri.nil?
|
|
241
|
-
# get command line parameters
|
|
242
|
-
delivid=self.options.get_option(:id,:mandatory)
|
|
259
|
+
when nil # usual case: no link
|
|
243
260
|
if self.options.get_option(:once_only,:mandatory)
|
|
244
261
|
skip_ids_persistency=PersistencyActionOnce.new(
|
|
245
262
|
manager: @agents[:persistency],
|
|
246
263
|
data: skip_ids_data,
|
|
247
264
|
ids: ['faspex_recv',self.options.get_option(:url,:mandatory),self.options.get_option(:username,:mandatory),self.options.get_option(:box,:mandatory).to_s])
|
|
248
265
|
end
|
|
266
|
+
# get command line parameters
|
|
267
|
+
delivid=self.options.get_option(:id,:mandatory)
|
|
249
268
|
if delivid.eql?(VAL_ALL)
|
|
250
269
|
pkg_id_uri=mailbox_all_entries.map{|i|{:id=>i[PACKAGE_MATCH_FIELD],:uri=>self.class.get_fasp_uri_from_entry(i)}}
|
|
251
270
|
# TODO : remove ids from skip not present in inbox
|
|
252
271
|
# skip_ids_data.select!{|id|pkg_id_uri.select{|p|p[:id].eql?(id)}}
|
|
253
272
|
pkg_id_uri.select!{|i|!skip_ids_data.include?(i[:id])}
|
|
254
273
|
else
|
|
255
|
-
|
|
274
|
+
recipient=options.get_option(:recipient,:optional)
|
|
275
|
+
if !recipient.nil? and recipient.start_with?('*')
|
|
276
|
+
raise "Dropbox and Workgroup packages should use link option with faspe:"
|
|
277
|
+
end
|
|
278
|
+
# TODO: delivery id is the right one if package was receive by workgroup
|
|
256
279
|
endpoint=case self.options.get_option(:box,:mandatory)
|
|
257
280
|
when :inbox,:archive;'received'
|
|
258
281
|
when :sent; 'sent'
|
|
@@ -261,7 +284,25 @@ module Aspera
|
|
|
261
284
|
package_entry=XmlSimple.xml_in(entry_xml, {'ForceArray' => true})
|
|
262
285
|
pkg_id_uri=[{:id=>delivid,:uri=>self.class.get_fasp_uri_from_entry(package_entry)}]
|
|
263
286
|
end
|
|
264
|
-
|
|
287
|
+
when /^faspe:/
|
|
288
|
+
pkg_id_uri=[{:id=>'package',:uri=>link_url}]
|
|
289
|
+
else
|
|
290
|
+
link_data=self.class.get_link_data(link_url)
|
|
291
|
+
if !link_data[:subpath].start_with?(PUB_LINK_EXTERNAL_MATCH)
|
|
292
|
+
raise CliBadArgument,"Pub link is #{link_data[:subpath]}. Expecting #{PUB_LINK_EXTERNAL_MATCH}"
|
|
293
|
+
end
|
|
294
|
+
# Note: unauthenticated API (autorization is in url params)
|
|
295
|
+
api_public_link=Rest.new({:base_url=>link_data[:base_url]})
|
|
296
|
+
pkgdatares=api_public_link.call({:operation=>'GET',:subpath=>link_data[:subpath],:url_params=>{:passcode=>link_data[:query]['passcode']},:headers=>{'Accept'=>'application/xml'}})
|
|
297
|
+
if !pkgdatares[:http].body.start_with?('<?xml ')
|
|
298
|
+
OpenApplication.instance.uri(link_url)
|
|
299
|
+
raise CliError, 'no such package'
|
|
300
|
+
end
|
|
301
|
+
package_entry=XmlSimple.xml_in(pkgdatares[:http].body, {'ForceArray' => false})
|
|
302
|
+
Log.dump(:package_entry,package_entry)
|
|
303
|
+
transfer_uri=self.class.get_fasp_uri_from_entry(package_entry)
|
|
304
|
+
pkg_id_uri=[{:id=>package_entry['id'],:uri=>transfer_uri}]
|
|
305
|
+
end # public link
|
|
265
306
|
Log.dump(:pkg_id_uri,pkg_id_uri)
|
|
266
307
|
return Main.result_status('no package') if pkg_id_uri.empty?
|
|
267
308
|
result_transfer=[]
|
|
@@ -270,20 +311,17 @@ module Aspera
|
|
|
270
311
|
# NOTE: only external users have token in faspe: link !
|
|
271
312
|
if !transfer_spec.has_key?('token')
|
|
272
313
|
sanitized=id_uri[:uri].gsub('&','&')
|
|
273
|
-
# TODO: file jira
|
|
274
|
-
#XXsanitized.gsub!(/%3D%3D$/,'==')
|
|
275
|
-
#XXsanitized.gsub!(/%3D$/,'=')
|
|
276
314
|
xmlpayload='<?xml version="1.0" encoding="UTF-8"?><url-list xmlns="http://schemas.asperasoft.com/xml/url-list"><url href="'+sanitized+'"/></url-list>'
|
|
277
315
|
transfer_spec['token']=api_v3.call({:operation=>'POST',:subpath=>'issue-token?direction=down',:headers=>{'Accept'=>'text/plain','Content-Type'=>'application/vnd.aspera.url-list+xml'},:text_body_params=>xmlpayload})[:http].body
|
|
278
316
|
end
|
|
279
317
|
transfer_spec['direction']='receive'
|
|
280
318
|
statuses=self.transfer.start(transfer_spec,{:src=>:node_gen3})
|
|
281
|
-
result_transfer.push({'package'=>id_uri[:id],
|
|
319
|
+
result_transfer.push({'package'=>id_uri[:id],Main::STATUS_FIELD=>statuses})
|
|
282
320
|
# skip only if all sessions completed
|
|
283
321
|
skip_ids_data.push(id_uri[:id]) if TransferAgent.session_status(statuses).eql?(:success)
|
|
284
322
|
end
|
|
285
323
|
skip_ids_persistency.save unless skip_ids_persistency.nil?
|
|
286
|
-
return
|
|
324
|
+
return Main.result_transfer_multiple(result_transfer)
|
|
287
325
|
end
|
|
288
326
|
when :source
|
|
289
327
|
command_source=self.options.get_next_command([ :list, :id, :name ])
|
|
@@ -19,9 +19,9 @@ module Aspera
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def set_api
|
|
22
|
-
faxpex5_api_base_url=options.get_option(:url,:mandatory)
|
|
23
|
-
faxpex5_api_v5_url="#{faxpex5_api_base_url}/api/v5"
|
|
24
|
-
faxpex5_api_auth_url="#{faxpex5_api_base_url}/auth"
|
|
22
|
+
@faxpex5_api_base_url=options.get_option(:url,:mandatory)
|
|
23
|
+
faxpex5_api_v5_url="#{@faxpex5_api_base_url}/api/v5"
|
|
24
|
+
faxpex5_api_auth_url="#{@faxpex5_api_base_url}/auth"
|
|
25
25
|
case options.get_option(:auth,:mandatory)
|
|
26
26
|
when :boot
|
|
27
27
|
# the password here is the token copied directly from browser in developer mode
|
|
@@ -50,12 +50,13 @@ module Aspera
|
|
|
50
50
|
:type => :oauth2,
|
|
51
51
|
:base_url => faxpex5_api_auth_url,
|
|
52
52
|
:grant => :jwt,
|
|
53
|
+
:f5_username => options.get_option(:username,:mandatory),
|
|
54
|
+
:f5_password => options.get_option(:password,:mandatory),
|
|
53
55
|
:client_id => app_client_id,
|
|
54
56
|
:client_secret => options.get_option(:client_secret,:mandatory),
|
|
55
57
|
:jwt_subject => "client:#{app_client_id}", # TODO Mmmm
|
|
56
58
|
:jwt_audience => app_client_id, # TODO Mmmm
|
|
57
59
|
:jwt_private_key_obj => OpenSSL::PKey::RSA.new(options.get_option(:private_key,:mandatory)),
|
|
58
|
-
:jwt_is_f5 => true, # TODO: remove when clarified
|
|
59
60
|
:jwt_headers => {typ: 'JWT'}
|
|
60
61
|
}})
|
|
61
62
|
end
|
|
@@ -69,7 +70,7 @@ module Aspera
|
|
|
69
70
|
command=options.get_next_command(ACTIONS)
|
|
70
71
|
case command
|
|
71
72
|
when :auth_client
|
|
72
|
-
api_auth=Rest.new(@api_v5.params.merge({base_url: @
|
|
73
|
+
api_auth=Rest.new(@api_v5.params.merge({base_url: "#{@faxpex5_api_base_url}/auth"}))
|
|
73
74
|
return self.entity_action(api_auth,'oauth_clients',nil,:id,nil,true)
|
|
74
75
|
when :node
|
|
75
76
|
return self.entity_action(@api_v5,'nodes',nil,:id,nil,true)
|
|
@@ -119,12 +120,12 @@ module Aspera
|
|
|
119
120
|
transfer_spec=@api_v5.create("packages/#{id}/transfer_spec/download",{transfer_type: 'Connect', type: pkg_type})[:data]
|
|
120
121
|
transfer_spec.delete('authentication')
|
|
121
122
|
statuses=self.transfer.start(transfer_spec,{:src=>:node_gen3})
|
|
122
|
-
result_transfer.push({'package'=>id,
|
|
123
|
+
result_transfer.push({'package'=>id,Main::STATUS_FIELD=>statuses})
|
|
123
124
|
# skip only if all sessions completed
|
|
124
125
|
skip_ids_data.push(id) if TransferAgent.session_status(statuses).eql?(:success)
|
|
125
126
|
end
|
|
126
127
|
skip_ids_persistency.save unless skip_ids_persistency.nil?
|
|
127
|
-
return
|
|
128
|
+
return Main.result_transfer_multiple(result_transfer)
|
|
128
129
|
end
|
|
129
130
|
end
|
|
130
131
|
end
|
|
@@ -344,34 +344,38 @@ module Aspera
|
|
|
344
344
|
next
|
|
345
345
|
end
|
|
346
346
|
Log.log.debug("item:#{entry}")
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
folder_entry
|
|
347
|
+
begin
|
|
348
|
+
case entry['type']
|
|
349
|
+
when 'file'
|
|
350
|
+
if filter_block.call(entry)
|
|
351
|
+
generate_preview(entry)
|
|
352
|
+
else
|
|
353
|
+
Log.log.debug('skip by filter')
|
|
354
|
+
end
|
|
355
|
+
when 'link'
|
|
356
|
+
Log.log.debug('Ignoring link.')
|
|
357
|
+
when 'folder'
|
|
358
|
+
if @option_skip_folders.include?(entry['path'])
|
|
359
|
+
Log.log.debug("#{entry['path']} folder (skip list)".bg_red)
|
|
360
|
+
else
|
|
361
|
+
Log.log.debug("#{entry['path']} folder".green)
|
|
362
|
+
# get folder content
|
|
363
|
+
folder_entries=get_folder_entries(entry['id'])
|
|
364
|
+
# process all items in current folder
|
|
365
|
+
folder_entries.each do |folder_entry|
|
|
366
|
+
# add path for older versions of ES
|
|
367
|
+
if !folder_entry.has_key?('path')
|
|
368
|
+
folder_entry['path']=entry_path_with_slash+folder_entry['name']
|
|
369
|
+
end
|
|
370
|
+
folder_entry['parent_file_id']=entry['id']
|
|
371
|
+
entries_to_process.push(folder_entry)
|
|
368
372
|
end
|
|
369
|
-
folder_entry['parent_file_id']=entry['id']
|
|
370
|
-
entries_to_process.push(folder_entry)
|
|
371
373
|
end
|
|
374
|
+
else
|
|
375
|
+
Log.log.warn("unknown entry type: #{entry['type']}")
|
|
372
376
|
end
|
|
373
|
-
|
|
374
|
-
Log.log.warn("
|
|
377
|
+
rescue => e
|
|
378
|
+
Log.log.warn("An error occured: #{e}, ignoring")
|
|
375
379
|
end
|
|
376
380
|
end
|
|
377
381
|
end
|