aspera-cli 4.0.0.pre1 → 4.0.0.pre2
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 +213 -255
- data/docs/Makefile +19 -13
- data/docs/README.erb.md +109 -76
- data/docs/test_env.conf +37 -14
- data/examples/aoc.rb +2 -2
- data/examples/transfer.rb +23 -14
- data/lib/aspera/{on_cloud.rb → aoc.rb} +24 -15
- data/lib/aspera/cli/main.rb +1 -0
- data/lib/aspera/cli/plugins/alee.rb +2 -2
- data/lib/aspera/cli/plugins/{oncloud.rb → aoc.rb} +34 -34
- data/lib/aspera/cli/plugins/ats.rb +1 -1
- data/lib/aspera/cli/plugins/config.rb +31 -17
- data/lib/aspera/cli/plugins/cos.rb +9 -49
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/cos_node.rb +50 -0
- data/lib/aspera/data/1 +0 -0
- data/lib/aspera/data/2 +0 -0
- data/lib/aspera/data/3 +1 -0
- data/lib/aspera/data/4 +2 -0
- data/lib/aspera/data/5 +1 -0
- data/lib/aspera/data/6 +2 -0
- data/lib/aspera/data/7 +0 -0
- data/lib/aspera/data_repository.rb +13 -0
- data/lib/aspera/environment.rb +55 -0
- data/lib/aspera/fasp/aoc.rb +6 -6
- data/lib/aspera/fasp/installation.rb +112 -56
- data/lib/aspera/fasp/local.rb +2 -3
- data/lib/aspera/faspex_gw.rb +2 -2
- data/lib/aspera/open_application.rb +11 -24
- data/lib/aspera/preview/generator.rb +1 -5
- data/lib/aspera/rest.rb +56 -48
- data/lib/aspera/rest_error_analyzer.rb +5 -4
- data/lib/aspera/temp_file_manager.rb +1 -1
- metadata +52 -26
- data/docs/secrets.make +0 -38
- data/lib/aspera/cli/plugins/xnode.rb +0 -115
@@ -93,7 +93,7 @@ module Aspera
|
|
93
93
|
return Main.result_status('modified')
|
94
94
|
when :entitlement
|
95
95
|
ak=ats_api_pub_v1.read("access_keys/#{access_key_id}")[:data]
|
96
|
-
api_bss=
|
96
|
+
api_bss=AoC.metering_api(ak['license']['entitlement_id'],ak['license']['customer_id'])
|
97
97
|
return {:type=>:single_object, :data=>api_bss.read('entitlement')[:data]}
|
98
98
|
when :delete
|
99
99
|
res=ats_api_pub_v1.delete("access_keys/#{access_key_id}")
|
@@ -3,9 +3,10 @@ require 'aspera/cli/extended_value'
|
|
3
3
|
require 'aspera/fasp/installation'
|
4
4
|
require 'aspera/api_detector'
|
5
5
|
require 'aspera/open_application'
|
6
|
-
require 'aspera/
|
6
|
+
require 'aspera/aoc'
|
7
7
|
require 'aspera/proxy_auto_config'
|
8
8
|
require 'aspera/uri_reader'
|
9
|
+
require 'aspera/rest'
|
9
10
|
require 'xmlsimple'
|
10
11
|
require 'base64'
|
11
12
|
require 'net/smtp'
|
@@ -38,7 +39,8 @@ module Aspera
|
|
38
39
|
RUBY_FILE_EXT='.rb'
|
39
40
|
AOC_COMMAND_V1='files'
|
40
41
|
AOC_COMMAND_V2='aspera'
|
41
|
-
AOC_COMMAND_V3='
|
42
|
+
AOC_COMMAND_V3='aoc'
|
43
|
+
AOC_COMMAND_CURRENT=AOC_COMMAND_V3
|
42
44
|
CONNECT_WEB_URL = 'https://d3gcli72yxqn2z.cloudfront.net/connect'
|
43
45
|
CONNECT_VERSIONS = 'connectversions.js'
|
44
46
|
DEMO='demo'
|
@@ -48,7 +50,7 @@ module Aspera
|
|
48
50
|
self.options.add_option_preset(preset_by_name(value))
|
49
51
|
end
|
50
52
|
|
51
|
-
private_constant :ASPERA_HOME_FOLDER_NAME,:DEFAULT_CONFIG_FILENAME,:CONF_PRESET_CONFIG,:CONF_PRESET_VERSION,:CONF_PRESET_DEFAULT,:PROGRAM_NAME_V1,:PROGRAM_NAME_V2,:DEFAULT_REDIRECT,:ASPERA_PLUGINS_FOLDERNAME,:GEM_PLUGINS_FOLDER,:RUBY_FILE_EXT,:AOC_COMMAND_V1,:AOC_COMMAND_V2,:AOC_COMMAND_V3,:DEMO
|
53
|
+
private_constant :ASPERA_HOME_FOLDER_NAME,:DEFAULT_CONFIG_FILENAME,:CONF_PRESET_CONFIG,:CONF_PRESET_VERSION,:CONF_PRESET_DEFAULT,:PROGRAM_NAME_V1,:PROGRAM_NAME_V2,:DEFAULT_REDIRECT,:ASPERA_PLUGINS_FOLDERNAME,:GEM_PLUGINS_FOLDER,:RUBY_FILE_EXT,:AOC_COMMAND_V1,:AOC_COMMAND_V2,:AOC_COMMAND_V3,:AOC_COMMAND_CURRENT,:DEMO
|
52
54
|
attr_accessor :option_ak_secret,:option_secrets
|
53
55
|
|
54
56
|
def initialize(env,tool_name,help_url,version)
|
@@ -67,7 +69,8 @@ module Aspera
|
|
67
69
|
@option_config_file=@conf_file_default
|
68
70
|
@connect_versions=nil
|
69
71
|
# set folder where generated FASP files are
|
70
|
-
Fasp::Installation.instance.
|
72
|
+
Fasp::Installation.instance.folder=File.join(@main_folder,'sdk')
|
73
|
+
FileUtils.mkdir_p(Fasp::Installation.instance.folder)
|
71
74
|
add_plugin_lookup_folder(File.join(@main_folder,ASPERA_PLUGINS_FOLDERNAME))
|
72
75
|
add_plugin_lookup_folder(File.join(Main.gem_root,GEM_PLUGINS_FOLDER))
|
73
76
|
# do file parameter first
|
@@ -405,7 +408,7 @@ module Aspera
|
|
405
408
|
end
|
406
409
|
|
407
410
|
def execute_action_ascp
|
408
|
-
command=self.options.get_next_command([:connect,:use,:show,:products,:info])
|
411
|
+
command=self.options.get_next_command([:connect,:use,:show,:products,:info,:install])
|
409
412
|
case command
|
410
413
|
when :connect
|
411
414
|
return execute_connect_action
|
@@ -429,12 +432,15 @@ module Aspera
|
|
429
432
|
while line=stderr.gets do
|
430
433
|
line.chomp!
|
431
434
|
case line
|
432
|
-
when
|
433
|
-
when
|
435
|
+
when %r{^DBG Path ([^ ]+) (dir|file) +: (.*)$};data[$1]=$3
|
436
|
+
when %r{^DBG Added module group:"([^"]+)" name:"([^"]+)", version:"([^"]+)" interface:"([^"]+)"$};data[$2]=$4
|
437
|
+
when %r{^DBG License result \(/license/(\S+)\): (.+)$};data[$1]=$2
|
438
|
+
when %r{^LOG (.+) version ([0-9.]+)$};data['product_name']=$1;data['product_version']=$2
|
439
|
+
when %r{^LOG Initializing FASP version ([^,]+),};data['ascp_version']=$1
|
434
440
|
end
|
435
441
|
end
|
436
442
|
end
|
437
|
-
data['keypass']=Fasp::Installation.instance.
|
443
|
+
data['keypass']=Fasp::Installation.instance.bypass_pass
|
438
444
|
return {:type=>:single_object, :data=>data}
|
439
445
|
when :products
|
440
446
|
command=self.options.get_next_command([:list,:use])
|
@@ -448,7 +454,11 @@ module Aspera
|
|
448
454
|
save_presets_to_config_file
|
449
455
|
return {:type=>:status, :data=>"saved to default global preset #{preset_name}"}
|
450
456
|
end
|
457
|
+
when :install
|
458
|
+
v=Fasp::Installation.instance.install_sdk
|
459
|
+
return {:type=>:status, :data=>"Installed version #{v}"}
|
451
460
|
end
|
461
|
+
raise "unexpected case: #{command}"
|
452
462
|
end
|
453
463
|
|
454
464
|
ACTIONS=[:gem_path, :genkey,:plugins,:flush_tokens,:list,:overview,:open,:echo,:id,:documentation,:wizard,:export_to_cli,:detect,:coffee,:ascp,:email_test,:smtp_settings,:proxy_check,:folder,:file]
|
@@ -562,7 +572,7 @@ module Aspera
|
|
562
572
|
case appli[:product]
|
563
573
|
when :aoc
|
564
574
|
self.format.display_status("Detected: Aspera on Cloud".bold)
|
565
|
-
organization,instance_domain=
|
575
|
+
organization,instance_domain=AoC.parse_url(instance_url)
|
566
576
|
aspera_preset_name='aoc_'+organization
|
567
577
|
self.format.display_status("Preparing preset: #{aspera_preset_name}")
|
568
578
|
# init defaults if necessary
|
@@ -580,7 +590,7 @@ module Aspera
|
|
580
590
|
end
|
581
591
|
# else generate path
|
582
592
|
if private_key_path.empty?
|
583
|
-
private_key_path=File.join(@main_folder,'
|
593
|
+
private_key_path=File.join(@main_folder,'aspera_aoc_key')
|
584
594
|
end
|
585
595
|
if File.exist?(private_key_path)
|
586
596
|
self.format.display_status("Using existing key:")
|
@@ -592,7 +602,7 @@ module Aspera
|
|
592
602
|
self.format.display_status("#{private_key_path}")
|
593
603
|
pub_key_pem=OpenSSL::PKey::RSA.new(File.read(private_key_path)).public_key.to_s
|
594
604
|
# define options
|
595
|
-
require 'aspera/cli/plugins/
|
605
|
+
require 'aspera/cli/plugins/aoc'
|
596
606
|
# make username mandatory for jwt, this triggers interactive input
|
597
607
|
self.options.get_option(:username,:mandatory)
|
598
608
|
files_plugin=Plugins::Oncloud.new(@agents.merge({skip_basic_auth_options: true, private_key_path: private_key_path}))
|
@@ -634,7 +644,7 @@ module Aspera
|
|
634
644
|
self.options.set_option(:redirect_uri,DEFAULT_REDIRECT)
|
635
645
|
auto_set_pub_key=true
|
636
646
|
auto_set_jwt=true
|
637
|
-
self.options.set_option(:scope,
|
647
|
+
self.options.set_option(:scope,AoC::SCOPE_FILES_ADMIN)
|
638
648
|
end
|
639
649
|
files_plugin.update_aoc_api
|
640
650
|
myself=files_plugin.api_aoc.read('self')[:data]
|
@@ -663,20 +673,20 @@ module Aspera
|
|
663
673
|
@config_presets[CONF_PRESET_DEFAULT][AOC_COMMAND_V2]=aspera_preset_name
|
664
674
|
self.format.display_status("saving config file")
|
665
675
|
save_presets_to_config_file
|
666
|
-
return Main.result_status("Done.\nYou can test with:\n#{@tool_name}
|
676
|
+
return Main.result_status("Done.\nYou can test with:\n#{@tool_name} #{AOC_COMMAND_CURRENT} user info show")
|
667
677
|
else
|
668
678
|
raise CliBadArgument,"Supports only: aoc. Detected: #{appli}"
|
669
679
|
end
|
670
680
|
when :export_to_cli
|
671
681
|
self.format.display_status("Exporting: Aspera on Cloud")
|
672
|
-
require 'aspera/cli/plugins/
|
682
|
+
require 'aspera/cli/plugins/aoc'
|
673
683
|
# need url / username
|
674
684
|
add_plugin_default_preset(AOC_COMMAND_V3.to_sym)
|
675
685
|
files_plugin=Plugins::Oncloud.new(@agents) # TODO: is this line needed ?
|
676
686
|
url=self.options.get_option(:url,:mandatory)
|
677
687
|
cli_conf_file=Fasp::Installation.instance.cli_conf_file
|
678
688
|
data=JSON.parse(File.read(cli_conf_file))
|
679
|
-
organization,instance_domain=
|
689
|
+
organization,instance_domain=AoC.parse_url(url)
|
680
690
|
key_basename='org_'+organization+'.pem'
|
681
691
|
key_file=File.join(File.dirname(File.dirname(cli_conf_file)),'etc',key_basename)
|
682
692
|
File.write(key_file,self.options.get_option(:private_key,:mandatory))
|
@@ -686,7 +696,11 @@ module Aspera
|
|
686
696
|
'privateKeyFilename' => key_basename,
|
687
697
|
'username' => self.options.get_option(:username,:mandatory)
|
688
698
|
}
|
689
|
-
new_conf['clientId']
|
699
|
+
new_conf['clientId']=self.options.get_option(:client_id,:optional)
|
700
|
+
new_conf['clientSecret']=self.options.get_option(:client_secret,:optional)
|
701
|
+
if new_conf['clientId'].nil?
|
702
|
+
new_conf['clientId'],new_conf['clientSecret']=AoC.get_client_info()
|
703
|
+
end
|
690
704
|
entry=data['AoCAccounts'].select{|i|i['organization'].eql?(organization)}.first
|
691
705
|
if entry.nil?
|
692
706
|
data['AoCAccounts'].push(new_conf)
|
@@ -775,7 +789,7 @@ END_OF_MESSAGE
|
|
775
789
|
|
776
790
|
def save_presets_to_config_file
|
777
791
|
raise "no configuration loaded" if @config_presets.nil?
|
778
|
-
FileUtils
|
792
|
+
FileUtils.mkdir_p(@main_folder) unless Dir.exist?(@main_folder)
|
779
793
|
Log.log.debug "writing #{@option_config_file}"
|
780
794
|
File.write(@option_config_file,@config_presets.to_yaml)
|
781
795
|
end
|
@@ -1,14 +1,11 @@
|
|
1
|
-
require 'aspera/cli/plugins/node'
|
2
1
|
require 'aspera/cli/plugin'
|
3
|
-
require '
|
2
|
+
require 'aspera/cli/plugins/node'
|
3
|
+
require 'aspera/cos_node'
|
4
4
|
|
5
5
|
module Aspera
|
6
6
|
module Cli
|
7
7
|
module Plugins
|
8
8
|
class Cos < Plugin
|
9
|
-
# IBM Cloud authentication : + token
|
10
|
-
IBM_CLOUD_OAUTH_URL='https://iam.cloud.ibm.com/identity'
|
11
|
-
private_constant :IBM_CLOUD_OAUTH_URL
|
12
9
|
def initialize(env)
|
13
10
|
super(env)
|
14
11
|
@service_creds=nil
|
@@ -34,7 +31,7 @@ module Aspera
|
|
34
31
|
raise "one of: endpoint or service_credentials is required" if service_credentials.nil? and storage_endpoint.nil?
|
35
32
|
raise "endpoint and service_credentials are mutually exclusive" unless service_credentials.nil? or storage_endpoint.nil?
|
36
33
|
if service_credentials.nil?
|
37
|
-
|
34
|
+
service_api_key = self.options.get_option(:apikey,:mandatory)
|
38
35
|
instance_id = self.options.get_option(:crn,:mandatory)
|
39
36
|
else
|
40
37
|
# check necessary contents
|
@@ -46,57 +43,20 @@ module Aspera
|
|
46
43
|
# get options
|
47
44
|
bucket_region=self.options.get_option(:region,:mandatory)
|
48
45
|
# get API key from service credentials
|
49
|
-
|
46
|
+
service_api_key=service_credentials['apikey']
|
50
47
|
instance_id=service_credentials['resource_instance_id']
|
51
48
|
# read endpoints from service provided in service credentials
|
52
49
|
endpoints=Aspera::Rest.new({:base_url=>service_credentials['endpoints']}).read('')[:data]
|
53
50
|
Aspera::Log.dump('endpoints',endpoints)
|
54
|
-
storage_endpoint=
|
51
|
+
storage_endpoint=endpoints.dig('service-endpoints','regional',bucket_region,'public',bucket_region)
|
52
|
+
raise "no such region: #{bucket_region}" if storage_endpoint.nil?
|
53
|
+
storage_endpoint='https://'+storage_endpoint
|
55
54
|
end
|
56
|
-
|
57
|
-
s3_api=Aspera::Rest.new({
|
58
|
-
:base_url => storage_endpoint,
|
59
|
-
:not_auth_codes => ['401','403'],
|
60
|
-
:headers => {'ibm-service-instance-id' => instance_id},
|
61
|
-
:auth => {
|
62
|
-
:type => :oauth2,
|
63
|
-
:base_url => IBM_CLOUD_OAUTH_URL,
|
64
|
-
:grant => :ibm_apikey,
|
65
|
-
:api_key => serv_cred_storage_api_key
|
66
|
-
}})
|
67
|
-
# read FASP connection information for bucket
|
68
|
-
xml_result_text=s3_api.call({:operation=>'GET',:subpath=>bucket_name,:headers=>{'Accept'=>'application/xml'},:url_params=>{'faspConnectionInfo'=>nil}})[:http].body
|
69
|
-
ats_info=XmlSimple.xml_in(xml_result_text, {'ForceArray' => false})
|
70
|
-
Aspera::Log.dump('ats_info',ats_info)
|
71
|
-
# get delegated token
|
72
|
-
delegated_oauth=Oauth.new({
|
73
|
-
:type => :oauth2,
|
74
|
-
:base_url => IBM_CLOUD_OAUTH_URL,
|
75
|
-
:grant => :delegated_refresh,
|
76
|
-
:api_key => serv_cred_storage_api_key,
|
77
|
-
:token_field=> 'delegated_refresh_token'
|
78
|
-
})
|
79
|
-
# to be placed in rest call header and in transfer tags
|
80
|
-
aspera_storage_credentials={
|
81
|
-
'type' => 'token',
|
82
|
-
'token' => {'delegated_refresh_token'=>delegated_oauth.get_authorization().gsub(/^Bearer /,'')}
|
83
|
-
}
|
84
|
-
# transfer spec addition
|
85
|
-
add_ts={'tags'=>{'aspera'=>{'node'=>{'storage_credentials'=>aspera_storage_credentials}}}}
|
86
|
-
# set a general addon to transfer spec
|
87
|
-
# here we choose to use the add_request_param
|
88
|
-
#self.transfer.option_transfer_spec_deep_merge(add_ts)
|
89
|
-
api_node=Rest.new({
|
90
|
-
:base_url => ats_info['ATSEndpoint'],
|
91
|
-
:headers => {'X-Aspera-Storage-Credentials'=>JSON.generate(aspera_storage_credentials)},
|
92
|
-
:auth => {
|
93
|
-
:type => :basic,
|
94
|
-
:username => ats_info['AccessKey']['Id'],
|
95
|
-
:password => ats_info['AccessKey']['Secret']}})
|
55
|
+
api_node=CosNode.new(bucket_name,storage_endpoint,instance_id,service_api_key)
|
96
56
|
#command=self.options.get_next_command(Node::ACTIONS)
|
97
57
|
#command=self.options.get_next_command(Node::COMMON_ACTIONS)
|
98
58
|
command=self.options.get_next_command([:upload,:download,:info,:access_key,:api_details])
|
99
|
-
node_plugin=Node.new(@agents.merge(skip_basic_auth_options: true, node_api: api_node, add_request_param: add_ts))
|
59
|
+
node_plugin=Node.new(@agents.merge(skip_basic_auth_options: true, node_api: api_node, add_request_param: api_node.add_ts))
|
100
60
|
return node_plugin.execute_action(command)
|
101
61
|
end
|
102
62
|
end
|
data/lib/aspera/cli/version.rb
CHANGED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'aspera/log'
|
2
|
+
require 'aspera/rest'
|
3
|
+
require 'xmlsimple'
|
4
|
+
|
5
|
+
module Aspera
|
6
|
+
class CosNode < Rest
|
7
|
+
attr_reader :add_ts
|
8
|
+
def initialize(bucket_name,storage_endpoint,instance_id,api_key,auth_url='https://iam.cloud.ibm.com/identity')
|
9
|
+
s3_api=Aspera::Rest.new({
|
10
|
+
:base_url => storage_endpoint,
|
11
|
+
:not_auth_codes => ['401','403'],
|
12
|
+
:headers => {'ibm-service-instance-id' => instance_id},
|
13
|
+
:auth => {
|
14
|
+
:type => :oauth2,
|
15
|
+
:base_url => auth_url,
|
16
|
+
:grant => :ibm_apikey,
|
17
|
+
:api_key => api_key
|
18
|
+
}})
|
19
|
+
# read FASP connection information for bucket
|
20
|
+
xml_result_text=s3_api.call({:operation=>'GET',:subpath=>bucket_name,:headers=>{'Accept'=>'application/xml'},:url_params=>{'faspConnectionInfo'=>nil}})[:http].body
|
21
|
+
ats_info=XmlSimple.xml_in(xml_result_text, {'ForceArray' => false})
|
22
|
+
Aspera::Log.dump('ats_info',ats_info)
|
23
|
+
# get delegated token
|
24
|
+
delegated_oauth=Oauth.new({
|
25
|
+
:type => :oauth2,
|
26
|
+
:base_url => auth_url,
|
27
|
+
:grant => :delegated_refresh,
|
28
|
+
:api_key => api_key,
|
29
|
+
:token_field=> 'delegated_refresh_token'
|
30
|
+
})
|
31
|
+
# to be placed in rest call header and in transfer tags
|
32
|
+
aspera_storage_credentials={
|
33
|
+
'type' => 'token',
|
34
|
+
'token' => {'delegated_refresh_token'=>delegated_oauth.get_authorization().gsub(/^Bearer /,'')}
|
35
|
+
}
|
36
|
+
# transfer spec addition
|
37
|
+
@add_ts={'tags'=>{'aspera'=>{'node'=>{'storage_credentials'=>aspera_storage_credentials}}}}
|
38
|
+
# set a general addon to transfer spec
|
39
|
+
# here we choose to use the add_request_param
|
40
|
+
#self.transfer.option_transfer_spec_deep_merge(@add_ts)
|
41
|
+
super({
|
42
|
+
:base_url => ats_info['ATSEndpoint'],
|
43
|
+
:headers => {'X-Aspera-Storage-Credentials'=>JSON.generate(aspera_storage_credentials)},
|
44
|
+
:auth => {
|
45
|
+
:type => :basic,
|
46
|
+
:username => ats_info['AccessKey']['Id'],
|
47
|
+
:password => ats_info['AccessKey']['Secret']}})
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/aspera/data/1
ADDED
Binary file
|
data/lib/aspera/data/2
ADDED
Binary file
|
data/lib/aspera/data/3
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
t1(�;�E��F�)P
|
data/lib/aspera/data/4
ADDED
data/lib/aspera/data/5
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Q�3Cr�l�m���v���L�����]aj��8���3@���<RĖ�_���~mӽ�Nl=u~�7��}-��{u
|
data/lib/aspera/data/6
ADDED
data/lib/aspera/data/7
ADDED
Binary file
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'aspera/log'
|
2
|
+
require 'singleton'
|
3
|
+
|
4
|
+
module Aspera
|
5
|
+
# a simple binary data repository
|
6
|
+
class DataRepository
|
7
|
+
include Singleton
|
8
|
+
# get binary value from data repository
|
9
|
+
def get_bin(id)
|
10
|
+
File.read(File.join(File.expand_path(File.dirname(__FILE__)),'data',id.to_s),mode: 'rb')
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'aspera/log'
|
2
|
+
|
3
|
+
module Aspera
|
4
|
+
# a simple binary data repository
|
5
|
+
class Environment
|
6
|
+
OS_WINDOWS = :windows
|
7
|
+
OS_X = :osx
|
8
|
+
OS_LINUX = :linux
|
9
|
+
OS_AIX = :aix
|
10
|
+
OS_LIST=[OS_WINDOWS,OS_X,OS_LINUX,OS_AIX]
|
11
|
+
|
12
|
+
def self.os
|
13
|
+
case RbConfig::CONFIG['host_os']
|
14
|
+
when /mswin/,/msys/,/mingw/,/cygwin/,/bccwin/,/wince/,/emc/
|
15
|
+
return OS_WINDOWS
|
16
|
+
when /darwin/,/mac os/
|
17
|
+
return OS_X
|
18
|
+
when /linux/
|
19
|
+
return OS_LINUX
|
20
|
+
when /aix/
|
21
|
+
return OS_AIX
|
22
|
+
else
|
23
|
+
raise "Unknown: #{RbConfig::CONFIG['host_os']}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
CPU_X86_64=:x86_64
|
27
|
+
CPU_PPC64=:ppc64
|
28
|
+
CPU_PPC64LE=:ppc64le
|
29
|
+
CPU_S390=:s390
|
30
|
+
CPU_LIST=[CPU_X86_64,CPU_PPC64,CPU_PPC64LE,CPU_S390]
|
31
|
+
|
32
|
+
def self.cpu
|
33
|
+
case RbConfig::CONFIG['host_cpu']
|
34
|
+
when /x86_64/
|
35
|
+
return :x86_64
|
36
|
+
when /powerpc/
|
37
|
+
return :ppc64le if os.eql?(OS_LINUX)
|
38
|
+
return :ppc64
|
39
|
+
when /s390/
|
40
|
+
return :s390
|
41
|
+
else # other
|
42
|
+
raise "Unknown: #{RbConfig::CONFIG['host_cpu']}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.architecture
|
47
|
+
return "#{os}-#{cpu}"
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.exe_extension
|
51
|
+
return '.exe' if os.eql?(OS_WINDOWS)
|
52
|
+
return ''
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/lib/aspera/fasp/aoc.rb
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
require 'aspera/fasp/node'
|
2
2
|
require 'aspera/log'
|
3
|
-
require 'aspera/
|
3
|
+
require 'aspera/aoc.rb'
|
4
4
|
|
5
5
|
module Aspera
|
6
6
|
module Fasp
|
7
7
|
class Aoc < Node
|
8
|
-
def initialize(
|
9
|
-
@app=
|
10
|
-
@
|
8
|
+
def initialize(aoc_options)
|
9
|
+
@app=aoc_options[:app] || AoC::FILES_APP
|
10
|
+
@api_aoc=AoC.new(aoc_options)
|
11
11
|
Log.log.warn("Under Development")
|
12
|
-
server_node_file = @
|
12
|
+
server_node_file = @api_aoc.resolve_node_file(server_home_node_file,server_folder)
|
13
13
|
# force node as transfer agent
|
14
|
-
node_api=Fasp::Node.new(@
|
14
|
+
node_api=Fasp::Node.new(@api_aoc.get_node_api(client_node_file[:node_info],AoC::SCOPE_NODE_USER))
|
15
15
|
super(node_api)
|
16
16
|
# additional node to node TS info
|
17
17
|
@add_ts={
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'singleton'
|
2
2
|
require 'aspera/log'
|
3
|
-
require 'aspera/
|
4
|
-
|
3
|
+
require 'aspera/environment'
|
4
|
+
require 'aspera/data_repository'
|
5
5
|
require 'xmlsimple'
|
6
6
|
require 'zlib'
|
7
7
|
require 'base64'
|
@@ -14,13 +14,17 @@ module Aspera
|
|
14
14
|
# but the user can specify ascp location by calling:
|
15
15
|
# Installation.instance.use_ascp_from_product(product_name)
|
16
16
|
# or
|
17
|
-
# Installation.instance.ascp_path=
|
17
|
+
# Installation.instance.ascp_path=""
|
18
18
|
class Installation
|
19
19
|
include Singleton
|
20
20
|
# currently used ascp executable
|
21
21
|
attr_accessor :ascp_path
|
22
|
-
#
|
23
|
-
attr_accessor :
|
22
|
+
# location of SDK files
|
23
|
+
attr_accessor :folder
|
24
|
+
PRODUCT_CONNECT='Aspera Connect'
|
25
|
+
PRODUCT_CLI_V1='Aspera CLI'
|
26
|
+
PRODUCT_DRIVE='Aspera Drive'
|
27
|
+
PRODUCT_ENTSRV='Enterprise Server'
|
24
28
|
# find ascp in named product (use value : FIRST_FOUND='FIRST' to just use first one)
|
25
29
|
# or select one from installed_products()
|
26
30
|
def use_ascp_from_product(product_name)
|
@@ -38,12 +42,18 @@ module Aspera
|
|
38
42
|
# @return the list of installed products in format of product_locations
|
39
43
|
def installed_products
|
40
44
|
if @found_products.nil?
|
41
|
-
@found_products=product_locations
|
45
|
+
@found_products=product_locations
|
46
|
+
# add sdk as first search path
|
47
|
+
@found_products.unshift({# SDK
|
48
|
+
:expected =>'SDK',
|
49
|
+
:app_root =>@folder,
|
50
|
+
:sub_bin =>''
|
51
|
+
})
|
52
|
+
@found_products.select! do |pl|
|
42
53
|
next false unless Dir.exist?(pl[:app_root])
|
43
54
|
Log.log.debug("found #{pl[:app_root]}")
|
44
55
|
sub_bin = pl[:sub_bin] || BIN_SUBFOLDER
|
45
|
-
|
46
|
-
pl[:ascp_path]=File.join(pl[:app_root],sub_bin,'ascp')+exec_ext
|
56
|
+
pl[:ascp_path]=File.join(pl[:app_root],sub_bin,'ascp'+Environment.exe_extension)
|
47
57
|
next false unless File.exist?(pl[:ascp_path])
|
48
58
|
product_info_file="#{pl[:app_root]}/#{PRODUCT_INFO}"
|
49
59
|
if File.exist?(product_info_file)
|
@@ -59,7 +69,7 @@ module Aspera
|
|
59
69
|
return @found_products
|
60
70
|
end
|
61
71
|
|
62
|
-
FILES=[:ascp,:ascp4,:ssh_bypass_key_dsa,:ssh_bypass_key_rsa,:fallback_cert,:fallback_key]
|
72
|
+
FILES=[:ascp,:ascp4,:ssh_bypass_key_dsa,:ssh_bypass_key_rsa,:aspera_license,:aspera_conf,:fallback_cert,:fallback_key]
|
63
73
|
|
64
74
|
# get path of one resource file of currently activated product
|
65
75
|
# keys and certs are generated locally... (they are well known values, arch. independant)
|
@@ -71,19 +81,42 @@ module Aspera
|
|
71
81
|
# note that there might be a .exe at the end
|
72
82
|
file=file.gsub('ascp','ascp4') if k.eql?(:ascp4)
|
73
83
|
when :ssh_bypass_key_dsa
|
74
|
-
file=File.join(@
|
75
|
-
File.write(file,
|
84
|
+
file=File.join(@folder,'aspera_bypass_dsa.pem')
|
85
|
+
File.write(file,get_key('dsa',1)) unless File.exist?(file)
|
76
86
|
File.chmod(0400,file)
|
77
87
|
when :ssh_bypass_key_rsa
|
78
|
-
file=File.join(@
|
79
|
-
File.write(file,
|
88
|
+
file=File.join(@folder,'aspera_bypass_rsa.pem')
|
89
|
+
File.write(file,get_key('rsa',2)) unless File.exist?(file)
|
90
|
+
File.chmod(0400,file)
|
91
|
+
when :aspera_license
|
92
|
+
file=File.join(@folder,'aspera-license')
|
93
|
+
File.write(file,Base64.strict_encode64("#{Zlib::Inflate.inflate(DataRepository.instance.get_bin(6))}==SIGNATURE==\n#{Base64.strict_encode64(DataRepository.instance.get_bin(7))}")) unless File.exist?(file)
|
94
|
+
File.chmod(0400,file)
|
95
|
+
when :aspera_conf
|
96
|
+
file=File.join(@folder,'aspera.conf')
|
97
|
+
File.write(file,%Q{<?xml version='1.0' encoding='UTF-8'?>
|
98
|
+
<CONF version="2">
|
99
|
+
<default>
|
100
|
+
<file_system>
|
101
|
+
<storage_rc>
|
102
|
+
<adaptive>
|
103
|
+
true
|
104
|
+
</adaptive>
|
105
|
+
</storage_rc>
|
106
|
+
<resume_suffix>.aspera-ckpt</resume_suffix>
|
107
|
+
<partial_file_suffix>.partial</partial_file_suffix>
|
108
|
+
<replace_illegal_chars>_</replace_illegal_chars>
|
109
|
+
</file_system>
|
110
|
+
</default>
|
111
|
+
</CONF>
|
112
|
+
}) unless File.exist?(file)
|
80
113
|
File.chmod(0400,file)
|
81
114
|
when :fallback_cert,:fallback_key
|
82
|
-
file_key=File.join(@
|
83
|
-
file_cert=File.join(@
|
115
|
+
file_key=File.join(@folder,'aspera_fallback_key.pem')
|
116
|
+
file_cert=File.join(@folder,'aspera_fallback_cert.pem')
|
84
117
|
if !File.exist?(file_key) or !File.exist?(file_cert)
|
85
118
|
require 'openssl'
|
86
|
-
# create new self signed certificate
|
119
|
+
# create new self signed certificate for http fallback
|
87
120
|
private_key = OpenSSL::PKey::RSA.new(1024)
|
88
121
|
cert = OpenSSL::X509::Certificate.new
|
89
122
|
cert.subject = cert.issuer = OpenSSL::X509::Name.parse("/C=US/ST=California/L=Emeryville/O=Aspera Inc./OU=Corporate/CN=Aspera Inc./emailAddress=info@asperasoft.com")
|
@@ -108,7 +141,7 @@ module Aspera
|
|
108
141
|
|
109
142
|
# @returns the file path of local connect where API's URI can be read
|
110
143
|
def connect_uri
|
111
|
-
connect=get_product_folders(
|
144
|
+
connect=get_product_folders(PRODUCT_CONNECT)
|
112
145
|
folder=File.join(connect[:run_root],VARRUN_SUBFOLDER)
|
113
146
|
['','s'].each do |ext|
|
114
147
|
uri_file=File.join(folder,"http#{ext}.uri")
|
@@ -122,30 +155,51 @@ module Aspera
|
|
122
155
|
|
123
156
|
# @ return path to configuration file of aspera CLI
|
124
157
|
def cli_conf_file
|
125
|
-
connect=get_product_folders(
|
158
|
+
connect=get_product_folders(PRODUCT_CLI_V1)
|
126
159
|
return File.join(connect[:app_root],BIN_SUBFOLDER,'.aspera_cli_conf')
|
127
160
|
end
|
128
161
|
|
129
|
-
#
|
130
|
-
def
|
131
|
-
return
|
132
|
-
Installation.instance.path(:ssh_bypass_key_dsa),
|
133
|
-
Installation.instance.path(:ssh_bypass_key_rsa) ]
|
162
|
+
# default bypass key phrase
|
163
|
+
def bypass_pass
|
164
|
+
return "%08x-%04x-%04x-%04x-%04x%08x" % DataRepository.instance.get_bin(3).unpack("NnnnnN")
|
134
165
|
end
|
135
166
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
def activated=(product_name);Log.log.warn("deprecated, use method use_ascp_from_product");use_ascp_from_product(product_name);end
|
141
|
-
|
142
|
-
def paths;Log.log.warn("deprecated, no replacement");raise "deprecated";end
|
167
|
+
def bypass_keys
|
168
|
+
return [:ssh_bypass_key_dsa,:ssh_bypass_key_rsa].map{|i|Installation.instance.path(i)}
|
169
|
+
end
|
143
170
|
|
144
|
-
def
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
171
|
+
def install_sdk
|
172
|
+
require 'zip'
|
173
|
+
sdk_zip_path=File.join(Dir.tmpdir,'sdk.zip')
|
174
|
+
Aspera::Rest.new(base_url: SDK_URL).call(operation: 'GET',save_to_file: sdk_zip_path)
|
175
|
+
filter="/#{Environment.architecture}/"
|
176
|
+
ascp_path=nil
|
177
|
+
# first ensure license file is here so that ascp invokation for version works
|
178
|
+
self.path(:aspera_license)
|
179
|
+
self.path(:aspera_conf)
|
180
|
+
Zip::File.open(sdk_zip_path) do |zip_file|
|
181
|
+
zip_file.each do |entry|
|
182
|
+
if entry.name.include?(filter) and !entry.name.end_with?('/')
|
183
|
+
archive_file=File.join(@folder,File.basename(entry.name))
|
184
|
+
File.open(archive_file, 'wb') do |output_stream|
|
185
|
+
IO.copy_stream(entry.get_input_stream, output_stream)
|
186
|
+
end
|
187
|
+
if entry.name.include?('ascp')
|
188
|
+
FileUtils.chmod(0755,archive_file)
|
189
|
+
ascp_path=archive_file
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
File.unlink(sdk_zip_path) rescue nil # Windows may give error
|
195
|
+
ascp_version='n/a'
|
196
|
+
if !ascp_path.nil?
|
197
|
+
# get version from ascp, only after full extract, as windows requires SSL/TLS DLLs
|
198
|
+
m=%x{#{ascp_path} -A}.match(/ascp version (.*)/)
|
199
|
+
ascp_version=m[1] unless m.nil?
|
200
|
+
File.write(File.join(@folder,PRODUCT_INFO),"<product><name>IBM Aspera SDK</name><version>#{ascp_version}</version></product>")
|
201
|
+
end
|
202
|
+
return ascp_version
|
149
203
|
end
|
150
204
|
|
151
205
|
private
|
@@ -157,8 +211,9 @@ module Aspera
|
|
157
211
|
PRODUCT_INFO='product-info.mf'
|
158
212
|
# policy for product selection
|
159
213
|
FIRST_FOUND='FIRST'
|
214
|
+
SDK_URL='https://eudemo.asperademo.com/aspera/faspex/sdk.zip'
|
160
215
|
|
161
|
-
private_constant :BIN_SUBFOLDER,:ETC_SUBFOLDER,:VARRUN_SUBFOLDER,:PRODUCT_INFO
|
216
|
+
private_constant :BIN_SUBFOLDER,:ETC_SUBFOLDER,:VARRUN_SUBFOLDER,:PRODUCT_INFO,:SDK_URL
|
162
217
|
|
163
218
|
# get some specific folder from specific applications: Connect or CLI
|
164
219
|
def get_product_folders(name)
|
@@ -169,72 +224,73 @@ module Aspera
|
|
169
224
|
|
170
225
|
def initialize
|
171
226
|
@ascp_path=nil
|
172
|
-
@
|
227
|
+
@folder='.'
|
173
228
|
@found_products=nil
|
174
229
|
end
|
175
230
|
|
176
231
|
# returns product folders depending on OS
|
177
232
|
# fields
|
178
233
|
# :expected M app name is taken from the manifest if present, else defaults to this value
|
179
|
-
# :app_root M main
|
234
|
+
# :app_root M main folder for the application
|
180
235
|
# :log_root O location of log files (Linux uses syslog)
|
181
236
|
# :run_root O only for Connect Client, location of http port file
|
182
237
|
# :sub_bin O subfolder with executables, default : bin
|
183
238
|
def product_locations
|
184
|
-
case
|
185
|
-
when
|
186
|
-
:expected =>
|
239
|
+
case Aspera::Environment.os
|
240
|
+
when Aspera::Environment::OS_WINDOWS; return [{
|
241
|
+
:expected =>PRODUCT_CONNECT,
|
187
242
|
:app_root =>File.join(ENV['LOCALAPPDATA'],'Programs','Aspera','Aspera Connect'),
|
188
243
|
:log_root =>File.join(ENV['LOCALAPPDATA'],'Aspera','Aspera Connect','var','log'),
|
189
244
|
:run_root =>File.join(ENV['LOCALAPPDATA'],'Aspera','Aspera Connect')
|
190
245
|
},{
|
191
|
-
:expected =>
|
246
|
+
:expected =>PRODUCT_CLI_V1,
|
192
247
|
:app_root =>File.join('C:','Program Files','Aspera','cli'),
|
193
248
|
:log_root =>File.join('C:','Program Files','Aspera','cli','var','log'),
|
194
249
|
},{
|
195
|
-
:expected =>
|
250
|
+
:expected =>PRODUCT_ENTSRV,
|
196
251
|
:app_root =>File.join('C:','Program Files','Aspera','Enterprise Server'),
|
197
252
|
:log_root =>File.join('C:','Program Files','Aspera','Enterprise Server','var','log'),
|
198
253
|
}]
|
199
|
-
when
|
200
|
-
:expected =>
|
254
|
+
when Aspera::Environment::OS_X; return [{
|
255
|
+
:expected =>PRODUCT_CONNECT,
|
201
256
|
:app_root =>File.join(Dir.home,'Applications','Aspera Connect.app'),
|
202
257
|
:log_root =>File.join(Dir.home,'Library','Logs','Aspera_Connect'),
|
203
258
|
:run_root =>File.join(Dir.home,'Library','Application Support','Aspera','Aspera Connect'),
|
204
259
|
:sub_bin =>File.join('Contents','Resources'),
|
205
260
|
},{
|
206
|
-
:expected =>
|
261
|
+
:expected =>PRODUCT_CLI_V1,
|
207
262
|
:app_root =>File.join(Dir.home,'Applications','Aspera CLI'),
|
208
263
|
:log_root =>File.join(Dir.home,'Library','Logs','Aspera')
|
209
264
|
},{
|
210
|
-
:expected =>
|
265
|
+
:expected =>PRODUCT_ENTSRV,
|
211
266
|
:app_root =>File.join('','Library','Aspera'),
|
212
267
|
:log_root =>File.join(Dir.home,'Library','Logs','Aspera'),
|
213
268
|
},{
|
214
|
-
:expected =>
|
269
|
+
:expected =>PRODUCT_DRIVE,
|
215
270
|
:app_root =>File.join('','Applications','Aspera Drive.app'),
|
216
271
|
:log_root =>File.join(Dir.home,'Library','Logs','Aspera_Drive'),
|
217
272
|
:sub_bin =>File.join('Contents','Resources'),
|
218
273
|
}]
|
219
274
|
else; return [{ # other: Linux and unix family
|
220
|
-
:expected =>
|
275
|
+
:expected =>PRODUCT_CONNECT,
|
221
276
|
:app_root =>File.join(Dir.home,'.aspera','connect'),
|
222
277
|
:run_root =>File.join(Dir.home,'.aspera','connect')
|
223
278
|
},{
|
224
|
-
:expected =>
|
279
|
+
:expected =>PRODUCT_CLI_V1,
|
225
280
|
:app_root =>File.join(Dir.home,'.aspera','cli'),
|
226
281
|
},{
|
227
|
-
:expected =>
|
282
|
+
:expected =>PRODUCT_ENTSRV,
|
228
283
|
:app_root =>File.join('','opt','aspera'),
|
229
284
|
}]
|
230
285
|
end
|
231
286
|
end
|
232
287
|
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
288
|
+
def get_key(type,id)
|
289
|
+
hf=['begin','end'].map{|t|"-----#{t} #{type} private key-----".upcase}
|
290
|
+
bin=Base64.strict_encode64(DataRepository.instance.get_bin(id))
|
291
|
+
hf.insert(1,bin).join("\n")
|
292
|
+
end
|
293
|
+
|
238
294
|
end # Installation
|
239
295
|
end
|
240
296
|
end
|