asperalm 0.5.13 → 0.5.14

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4ffd8a30b8aa955e32436e3081b4aec6ffec8e4a
4
- data.tar.gz: 923c7734993bb61f5fb5ca77bb235fbab0ca044d
3
+ metadata.gz: 791d3f73a84e9a94a93c0d39fde9c8157b9acd6f
4
+ data.tar.gz: 694bad85db393795dc86d266e55d226797342229
5
5
  SHA512:
6
- metadata.gz: 5491d725b98e88d7dcaea4a507cda81ec9e290532bf85046f446234d6d8781b9e4c16cee05c98dae27fdcc2818c8fe4c5a448560594c495dd6e8e101b8db6750
7
- data.tar.gz: 769a38644668f14fc5e67cc39e7bdc2ac12d3db2752375dfce2ef8d9cb596a8f48b588f62a96d84c62cd5ed142e80d8bbf01f112224360809c322e9a59b736cb
6
+ metadata.gz: 85401c1a241efdd50467e4659aaa76e3f59fda2ef031a9085b8745ac143f5e375a62f1fc09c687219076234c934277de210e5ab2495d7e2250c9c488f9d52c8b
7
+ data.tar.gz: 23ab57e03ef546dc4b94df20538950a5b57df7f056b6c01dda696372757ea38fbea86dce275a966e3530fc9cc205f0b07c28ee937ba2c544da30ce590147265c
data/README.md CHANGED
@@ -93,7 +93,7 @@ see section: [Download FASP](download-fasp).
93
93
  One can test the "server" application using the well known demo server:
94
94
 
95
95
  ```bash
96
- $ aslmcli config id aspera_demo_server init @json:'{"url":"ssh://demo.asperasoft.com:33001","username":"asperaweb","password":"demoaspera"}'
96
+ $ aslmcli config id aspera_demo_server update --url=ssh://demo.asperasoft.com:33001 --username=asperaweb --password=demoaspera
97
97
  $ aslmcli config id default set server aspera_demo_server
98
98
  $ aslmcli server browse /aspera-test-dir-large
99
99
  $ aslmcli server download /aspera-test-dir-large/200MB
@@ -119,7 +119,7 @@ This can also be provisioned in a config file:
119
119
  3$ aslmcli config id shares06 set password 4sp3ra
120
120
  4$ aslmcli config id default set shares shares06
121
121
  5$ aslmcli config show
122
- 6$ aslmcli config shares repo browse /
122
+ 6$ aslmcli shares repo browse /
123
123
  ```
124
124
 
125
125
  The three first commands build a parameter set.
@@ -159,9 +159,11 @@ $ aslmcli config id files_myorg set url https://myorg.asperafiles.com
159
159
  $ aslmcli config id files_myorg set client_id MyClIeNtKeY
160
160
  $ aslmcli config id files_myorg set client_secret MyClIeNtSeCrEtMyClIeNtSeCrEt
161
161
  $ aslmcli config id files_myorg set username user@example.com
162
- $ aslmcli config id files_myorg set private_key @val:@file:~/.aspera/aslmcli/filesapikey
162
+ $ aslmcli config id files_myorg set private_key @val:@file:"$HOME/.aspera/aslmcli/filesapikey"
163
163
  ```
164
164
 
165
+ Note: the private key argument represents the actual PEM string. In order to read the content from a file, use the @file: prefix. But if the @file: argument is used as is, it will read the file and set in the config file. So to keep the "@file" tag in the configuration file, the @val: prefix is added.
166
+
165
167
  * CLI is ready to use:
166
168
 
167
169
  ```bash
@@ -527,7 +529,7 @@ table, th, td {border: 1px solid black;}
527
529
  <tr><td>target_rate_cap_kbps</td><td></td><td></td><td class="no">N</td><td class="no">?</td><td class="yes">?</td><td>-</td><td>Returned by upload/download_setup node api.</td></tr>
528
530
  <tr><td>rate_policy_allowed</td><td></td><td></td><td></td><td></td><td></td><td>-</td><td>returned by node API. Specifies most aggressive rate policy that is allowed. Valid literals include "low", "fair","high" and "fixed".</td></tr>
529
531
  <tr><td>ssh_private_key</td><td></td><td>string</td><td></td><td></td><td></td><td>-</td><td>todo</td></tr>
530
- <tr><td>password</td><td>-</td><td>string</td><td class="yes">Y</td><td class="yes">Y</td><td class="yes">Y</td><td>PASS</td><td>SSH session password</td></tr>
532
+ <tr><td>remote_password</td><td>-</td><td>string</td><td class="yes">Y</td><td class="yes">Y</td><td class="yes">Y</td><td>PASS</td><td>SSH session password</td></tr>
531
533
  <tr><td>resume_policy</td><td>faspmgr:<br/>none<br/>other:<br/>sparse_csum</td><td>string</td><td class="yes">Y</td><td class="yes">Y</td><td class="yes">Y</td><td>-k</td><td>none,attrs,sparse_csum,full_csum</td></tr>
532
534
  <tr><td>authentication</td><td>faspmgr:<br/>none<br/>other:<br/>sparse_csum</td><td>string</td><td class="yes">Y</td><td class="yes">Y</td><td class="no">N</td><td>-</td><td>token: Aspera web keys are provided to allow transparent web based session initiation. on connect: password is not asked. Else, password is asked, and keys are not provided.</td></tr>
533
535
  <tr><td>EX_ssh_key_value</td><td>-</td><td>string</td><td class="yes">Y</td><td class="no">N</td><td class="no">N</td><td>KEY</td><td>Private key used for SSH authentication</td></tr>
@@ -549,7 +551,7 @@ It is possible to start a FASPStream session using the node API:
549
551
  Use the "node stream create" command, then arguments are provided as a "transfer spec".
550
552
 
551
553
  ```bash
552
- ./bin/aslmcli node stream create --ts=@json:'{"direction":"send","source":"udp://233.3.3.4:3000?loopback=1&ttl=2","destination":"udp://233.3.3.3:3001/","remote_host":"localhost","remote_user":"stream","password":"XXXX"}' --load-params=stream
554
+ ./bin/aslmcli node stream create --ts=@json:'{"direction":"send","source":"udp://233.3.3.4:3000?loopback=1&ttl=2","destination":"udp://233.3.3.3:3001/","remote_host":"localhost","remote_user":"stream","remote_password":"XXXX"}' --load-params=stream
553
555
  ```
554
556
 
555
557
  # Download FASP
@@ -665,6 +667,8 @@ On first execution, the user is asked to login to Aspera ID using a web browser.
665
667
 
666
668
  When only one ats_id is created, it is taken by default. Else it shall be specified with --ats-id or using a parameter set.
667
669
 
670
+ Note: APIs are described here: [https://ts.asperasoft.com/ats-guide/getting-started-guide/#guide_transfers_create_ak](https://ts.asperasoft.com/ats-guide/getting-started-guide/#guide_transfers_create_ak)
671
+
668
672
  ## Usage
669
673
 
670
674
  Example: create access key on softlayer:
@@ -902,7 +906,7 @@ aslmcli orchestrator processes
902
906
  aslmcli ats server list provisioned
903
907
  aslmcli ats server list clouds
904
908
  aslmcli ats server list instance --cloud=aws --region=eu-west-1
905
- aslmcli ats server id gk7f5356-f4ea-kj83-ddfW-7da4ed99f8eb
909
+ aslmcli ats server id 1f412ae7-869a-445c-9c05-02ad16813be2
906
910
  aslmcli ats subscriptions
907
911
  aslmcli ats api_key repository list
908
912
  aslmcli ats api_key list
@@ -951,7 +955,7 @@ aslmcli config id default set preview test_preview
951
955
  ```bash
952
956
  $ aslmcli -h
953
957
  NAME
954
- aslmcli -- a command line tool for Aspera Applications (v0.5.13)
958
+ aslmcli -- a command line tool for Aspera Applications (v0.5.14)
955
959
 
956
960
  --interactive=ENUM use interactive input of missing params. Values=(yes,no), current=yes
957
961
  --ask-options=ENUM ask even optional options. Values=(yes,no), current=no
@@ -990,7 +994,7 @@ OPTIONS: global
990
994
  --transfer=ENUM type of transfer. Values=(ascp,connect,node), current=ascp
991
995
  -C, --config-fileSTRING read parameters from file in YAML format, current=/Users/laurent/.aspera/aslmcli/config.yaml
992
996
  -P, --load-paramsNAME load the named configuration from current config file, use "none" to avoid loading the default configuration
993
- --fasp-folder=NAME specify where to find FASP (main folder), current={:ascp=>"ascp", :app_root=>"/Users/laurent/Applications/Aspera Connect.app", :run_root=>"/Users/laurent/Library/Application Support/Aspera/Aspera Connect", :log_root=>"/Users/laurent/Library/Logs/Aspera", :sub_bin=>"Contents/Resources", :sub_keys=>"Contents/Resources", :dsa=>"asperaweb_id_dsa.openssh"}
997
+ --fasp-folder=NAME specify where to find FASP (main folder), current={:ascp=>{:path=>"/Users/laurent/Applications/Aspera Connect.app/Contents/Resources/ascp", :type=>:file, :required=>true}, :ssh_bypass_key_dsa=>{:path=>"/Users/laurent/Applications/Aspera Connect.app/Contents/Resources/asperaweb_id_dsa.openssh", :type=>:file, :required=>true}, :ssh_bypass_key_rsa=>{:path=>"/Users/laurent/Applications/Aspera Connect.app/Contents/Resources/aspera_tokenauth_id_rsa", :type=>:file, :required=>true}, :fallback_cert=>{:path=>"/Users/laurent/Applications/Aspera Connect.app/Contents/Resources/aspera_web_cert.pem", :type=>:file, :required=>false}, :fallback_key=>{:path=>"/Users/laurent/Applications/Aspera Connect.app/Contents/Resources/aspera_web_key.pem", :type=>:file, :required=>false}, :localhost_cert=>{:path=>"/Users/laurent/Applications/Aspera Connect.app/Contents/Resources/localhost.crt", :type=>:file, :required=>false}, :localhost_key=>{:path=>"/Users/laurent/Applications/Aspera Connect.app/Contents/Resources/localhost.key", :type=>:file, :required=>false}, :plugin_https_port_file=>{:path=>"/Users/laurent/Library/Application Support/Aspera/Aspera Connect/var/run/https.uri", :type=>:file, :required=>false}, :log_folder=>{:path=>"/Users/laurent/Library/Logs/Aspera", :type=>:folder, :required=>false}}
994
998
  --transfer-node=STRING name of configuration used to transfer when using --transfer=node
995
999
  --fields=STRING comma separated list of fields, or ALL, or DEF
996
1000
  --fasp-proxy=STRING URL of FASP proxy (dnat / dnats)
@@ -1001,6 +1005,7 @@ OPTIONS: global
1001
1005
  --ts=JSON override transfer spec values for transfers (hash, use @json: prefix), current={}
1002
1006
  --to-folder=PATH destination folder for downloaded files, current=
1003
1007
  --lock-port=NUMBER prevent dual execution of a command, e.g. in cron
1008
+ --use-product=NAME which local product to use for ascp
1004
1009
 
1005
1010
  --interactive=ENUM use interactive input of missing params. Values=(yes,no), current=yes
1006
1011
  --ask-options=ENUM ask even optional options. Values=(yes,no), current=no
@@ -1009,16 +1014,16 @@ SUBCOMMANDS: repository, admin
1009
1014
  OPTIONS:
1010
1015
  -w, --urlURI URL of application, e.g. https://org.asperafiles.com
1011
1016
  -u, --usernameSTRING username to log in
1012
- -p, --passwordSTRING password
1017
+ -p, --passwordSTRING user's password
1013
1018
 
1014
1019
  --interactive=ENUM use interactive input of missing params. Values=(yes,no), current=yes
1015
1020
  --ask-options=ENUM ask even optional options. Values=(yes,no), current=no
1016
1021
  COMMAND: node
1017
- SUBCOMMANDS: events, space, info, mkdir, mklink, mkfile, rename, delete, browse, upload, download, stream, transfer, cleanup, forward, access_key, watch_folder, service, async, central
1022
+ SUBCOMMANDS: events, space, info, mkdir, mklink, mkfile, rename, delete, browse, upload, download, postprocess, stream, transfer, cleanup, forward, access_key, watch_folder, service, async, central
1018
1023
  OPTIONS:
1019
1024
  -w, --urlURI URL of application, e.g. https://org.asperafiles.com
1020
1025
  -u, --usernameSTRING username to log in
1021
- -p, --passwordSTRING password
1026
+ -p, --passwordSTRING user's password
1022
1027
  --persistency=FILEPATH persistency file (cleanup,forward)
1023
1028
  --filter-transfer=EXPRESSION Ruby expression for filter at transfer level (cleanup)
1024
1029
  --filter-file=EXPRESSION Ruby expression for filter at file level (cleanup)
@@ -1032,7 +1037,7 @@ SUBCOMMANDS: info, workflow, plugins, processes
1032
1037
  OPTIONS:
1033
1038
  -w, --urlURI URL of application, e.g. https://org.asperafiles.com
1034
1039
  -u, --usernameSTRING username to log in
1035
- -p, --passwordSTRING password
1040
+ -p, --passwordSTRING user's password
1036
1041
  --params=HASH_TABLE parameters hash table, use @json:{"param":"value"}
1037
1042
  --result=step:name work step:parameter expected as result
1038
1043
  --synchronous=ENUM work step:parameter expected as result. Values=(yes,no), current=no
@@ -1050,7 +1055,7 @@ OPTIONS:
1050
1055
  --interactive=ENUM use interactive input of missing params. Values=(yes,no), current=yes
1051
1056
  --ask-options=ENUM ask even optional options. Values=(yes,no), current=no
1052
1057
  COMMAND: client
1053
- SUBCOMMANDS: location, connect
1058
+ SUBCOMMANDS: installation, monitor, location, connect
1054
1059
  OPTIONS:
1055
1060
 
1056
1061
  --interactive=ENUM use interactive input of missing params. Values=(yes,no), current=yes
@@ -1060,7 +1065,7 @@ SUBCOMMANDS: package, dropbox, recv_publink, source, me
1060
1065
  OPTIONS:
1061
1066
  -w, --urlURI URL of application, e.g. https://org.asperafiles.com
1062
1067
  -u, --usernameSTRING username to log in
1063
- -p, --passwordSTRING password
1068
+ -p, --passwordSTRING user's password
1064
1069
  --recipient=STRING package recipient
1065
1070
  --title=STRING package title
1066
1071
  --note=STRING package note
@@ -1084,7 +1089,7 @@ SUBCOMMANDS: scan, events, folder, check, test
1084
1089
  OPTIONS:
1085
1090
  -w, --urlURI URL of application, e.g. https://org.asperafiles.com
1086
1091
  -u, --usernameSTRING username to log in
1087
- -p, --passwordSTRING password
1092
+ -p, --passwordSTRING user's password
1088
1093
  --file-access=ENUM how to read and write files in repository. Values=(local,remote), current=local
1089
1094
  --skip-types=LIST skip types in comma separated list
1090
1095
  --overwrite=ENUM when to generate preview file. Values=(always,never,mtime), current=mtime
@@ -1118,20 +1123,20 @@ SUBCOMMANDS: nodeadmin, userdata, configurator, download, upload, browse, delete
1118
1123
  OPTIONS:
1119
1124
  -w, --urlURI URL of application, e.g. https://org.asperafiles.com
1120
1125
  -u, --usernameSTRING username to log in
1121
- -p, --passwordSTRING password
1126
+ -p, --passwordSTRING user's password
1122
1127
  --ssh-keys=PATH_ARRAY PATH_ARRAY is @json:'["path1","path2"]'
1123
1128
 
1124
1129
  --interactive=ENUM use interactive input of missing params. Values=(yes,no), current=yes
1125
1130
  --ask-options=ENUM ask even optional options. Values=(yes,no), current=no
1126
1131
  COMMAND: files
1127
- SUBCOMMANDS: package, repo, faspexgw, admin
1132
+ SUBCOMMANDS: package, repository, faspexgw, admin
1128
1133
  OPTIONS:
1129
1134
  --download-mode=ENUM download mode. Values=(fasp,node_http), current=fasp
1130
1135
  -t, --authTYPE type of authentication. Values=(basic,web,jwt,url_token), current=
1131
1136
  -w, --urlURI URL of application, e.g. http://org.asperafiles.com
1132
1137
  -u, --usernameSTRING username to log in
1133
- -p, --passwordSTRING password
1134
- -k, --private-keySTRING RSA private key for JWT (@ for ext. file)
1138
+ -p, --passwordSTRING user's password
1139
+ -k, --private-keySTRING RSA private key PEM value for JWT (prefix file path with @val:@file:)
1135
1140
  --workspace=STRING name of workspace
1136
1141
  --recipient=STRING package recipient
1137
1142
  --title=STRING package title
@@ -1146,7 +1151,7 @@ SUBCOMMANDS: transfers
1146
1151
  OPTIONS:
1147
1152
  -w, --urlURI URL of application, e.g. https://org.asperafiles.com
1148
1153
  -u, --usernameSTRING username to log in
1149
- -p, --passwordSTRING password
1154
+ -p, --passwordSTRING user's password
1150
1155
  --filter-from=DATE only after date
1151
1156
  --filter-to=DATE only before date
1152
1157
 
@@ -12,7 +12,7 @@ transferspec=nil
12
12
  p=OptionParser.new
13
13
  p.banner = "Usage: asfasp [options]"
14
14
  p.separator("EXAMPLES")
15
- p.separator(%q( asfasp --ts=@json:'{"remote_host":"demo.asperasoft.com","remote_user":"asperaweb","ssh_port":33001,"password":"demoaspera","direction":"receive","destination_root":"./test.dir","paths":[{"source":"/aspera-test-dir-tiny/200KB.1"}]}'))
15
+ p.separator(%q( asfasp --ts=@json:'{"remote_host":"demo.asperasoft.com","remote_user":"asperaweb","ssh_port":33001,"remote_password":"demoaspera","direction":"receive","destination_root":"./test.dir","paths":[{"source":"/aspera-test-dir-tiny/200KB.1"}]}'))
16
16
  p.separator(%q( echo '{"remote_host":...}'|asfasp --ts=@json:@stdin))
17
17
  p.separator("OPTIONS")
18
18
  p.on("-D", "debug mode"){logger.level=logger.level+1}
@@ -25,11 +25,15 @@ if transferspec.nil?
25
25
  STDERR.puts(p)
26
26
  Process.exit(1)
27
27
  end
28
+ if !transferspec.is_a?(Hash)
29
+ STDERR.puts("expecting a hash, did you specify: @json: ?")
30
+ Process.exit(1)
31
+ end
28
32
  # disable ascp output on stdout to not mix with progress json
29
33
  transferspec['EX_quiet']=true
30
34
  # FASP event listener display management events as JSON
31
35
  class FaspListenerStdout < Asperalm::Fasp::Listener
32
- def event(data);STDOUT.puts(JSON.generate(data));end
36
+ def event(data);STDOUT.puts(JSON.generate(data));STDOUT.flush;end
33
37
  end
34
38
  # display JSON instead of legacy Lines
35
39
  Asperalm::Fasp::Manager.instance.add_listener(FaspListenerStdout.new,:enhanced)
@@ -1,7 +1,7 @@
1
- #!/usr/bin/env ruby -w
1
+ #!/usr/bin/env ruby
2
+ #-w -r tracer
2
3
  # Laurent Martin/2017
3
4
  require 'rubygems'
4
5
  $LOAD_PATH.unshift(File.dirname(__FILE__)+"/../lib")
5
6
  require 'asperalm/cli/main'
6
- require 'asperalm/log'
7
7
  Asperalm::Cli::Main.tool.process_command_line(ARGV)
@@ -13,7 +13,7 @@ module Asperalm
13
13
  def declare_options
14
14
  Main.tool.options.add_opt_simple(:url,"URI","-wURI","URL of application, e.g. https://org.asperafiles.com")
15
15
  Main.tool.options.add_opt_simple(:username,"STRING","-uSTRING","username to log in")
16
- Main.tool.options.add_opt_simple(:password,"STRING","-pSTRING","password")
16
+ Main.tool.options.add_opt_simple(:password,"STRING","-pSTRING","user's password")
17
17
  end
18
18
  end # BasicAuthPlugin
19
19
  end # Cli
@@ -70,7 +70,7 @@ module Asperalm
70
70
  singleton_class.send(:alias_method, :tool, :instance)
71
71
  def self.version;return @@TOOL_VERSION;end
72
72
  private
73
- @@TOOL_VERSION='0.5.13'
73
+ @@TOOL_VERSION='0.5.14'
74
74
  # first level command for the main tool
75
75
  @@MAIN_PLUGIN_NAME_STR='config'
76
76
  # name of application, also foldername where config is stored
@@ -190,9 +190,9 @@ module Asperalm
190
190
 
191
191
  def option_browser=(value); OperatingSystem.open_url_method=value; end
192
192
 
193
- def option_fasp_folder; Fasp::ResourceFinder.fasp_install_paths; end
193
+ def option_fasp_folder; Fasp::Installation.instance.paths; end
194
194
 
195
- def option_fasp_folder=(value); Fasp::ResourceFinder.fasp_install_paths=value; end
195
+ def option_fasp_folder=(value); Fasp::Installation.instance.paths=value; end
196
196
 
197
197
  # returns the list of plugins from plugin folder
198
198
  def plugin_sym_list
@@ -249,6 +249,7 @@ module Asperalm
249
249
  node_config=Manager.get_extended_value(:transfer_node,transfer_node_spec)
250
250
  end
251
251
  Log.log.debug("node=#{node_config}")
252
+ raise CliBadArgument,"the node configuration shall be a hash, use either @json:<json> or @param:<parameter set name>" if !node_config.is_a?(Hash)
252
253
  # now check there are required parameters
253
254
  sym_config={}
254
255
  [:url,:username,:password].each do |param|
@@ -310,6 +311,7 @@ module Asperalm
310
311
  @options.set_obj_attr(:logger,self,:option_logtype)
311
312
  @options.set_obj_attr(:gui_mode,self,:option_browser)
312
313
  @options.set_obj_attr(:fasp_folder,self,:option_fasp_folder)
314
+ @options.set_obj_attr(:use_product,Fasp::Installation.instance,:activated)
313
315
  end
314
316
 
315
317
  # plugin_name_sym is symbol
@@ -363,6 +365,7 @@ module Asperalm
363
365
  @options.add_opt_simple(:ts,"JSON","override transfer spec values for transfers (hash, use @json: prefix), current=#{@options.get_option(:ts,:optional)}")
364
366
  @options.add_opt_simple(:to_folder,"PATH","destination folder for downloaded files, current=#{@options.get_option(:to_folder,:optional)}")
365
367
  @options.add_opt_simple(:lock_port,"NUMBER","prevent dual execution of a command, e.g. in cron")
368
+ @options.add_opt_simple(:use_product,"NAME","which local product to use for ascp")
366
369
  end
367
370
 
368
371
  def self.flatten_config_show(t)
@@ -89,6 +89,7 @@ module Asperalm
89
89
 
90
90
  # create a new API key , requires aspera id authentication
91
91
  def create_new_api_key
92
+ # TODO: provide param username and password to avoid web auth
92
93
  # get login page url in exception code 3xx
93
94
  res=@api_pub.call({:operation=>'POST',:subpath=>"api_keys",:return_error=>true,:headers=>{'Accept'=>'application/json'},:url_params=>{:description => "created by aslmcli",:redirect_uri=>LOCAL_REDIRECT_URI}})
94
95
  # TODO: check code is 3xx ?
@@ -1,6 +1,6 @@
1
1
  require 'asperalm/cli/main'
2
2
  require 'asperalm/cli/plugins/node'
3
- require 'asperalm/fasp/resource_finder'
3
+ require 'asperalm/fasp/installation'
4
4
  require 'asperalm/operating_system'
5
5
 
6
6
  module Asperalm
@@ -12,7 +12,7 @@ module Asperalm
12
12
  CONNECT_VERSIONS = 'connectversions.js'
13
13
  def declare_options; end
14
14
 
15
- def action_list; [ :location, :connect ];end
15
+ def action_list; [ :installation, :monitor, :location, :connect ];end
16
16
 
17
17
  def self.textify_list(table_data)
18
18
  return table_data.select {|i| ! i['key'].eql?('links') }
@@ -31,7 +31,17 @@ module Asperalm
31
31
  command=Main.tool.options.get_next_argument('command',action_list)
32
32
  case command
33
33
  when :location # shows files used
34
- return {:type=>:hash_array, :data=>Fasp::ResourceFinder.resource.map {|k,v| {'name'=>k,'path'=>v[:path]}}}
34
+ return {:type=>:hash_array, :data=>Fasp::Installation.instance.paths.map {|k,v| {'name'=>k,'path'=>v[:path]}}}
35
+ when :installation
36
+ subcmd=Main.tool.options.get_next_argument('command',[:list])
37
+ all=Fasp::Installation.instance.installed_products
38
+ case subcmd
39
+ when :list # shows files used
40
+ return {:type=>:hash_array, :data=>all, :fields=>[:name,:app_root]}
41
+ end
42
+ when :monitor # todo
43
+ raise "xx"
44
+ return {:type=>:hash_array, :data=>Fasp::Installation.instance.installed_products}
35
45
  when :connect #
36
46
  command=Main.tool.options.get_next_argument('command',[:list,:id])
37
47
  case command
@@ -9,7 +9,7 @@ module Asperalm
9
9
  module Cli
10
10
  module Plugins
11
11
  class Files < Plugin
12
- def action_list; [ :package, :repo, :faspexgw, :admin];end
12
+ def action_list; [ :package, :repository, :faspexgw, :admin];end
13
13
 
14
14
  def declare_options
15
15
  Main.tool.options.set_option(:download_mode,:fasp)
@@ -17,8 +17,8 @@ module Asperalm
17
17
  Main.tool.options.add_opt_list(:auth,Oauth.auth_types,"type of authentication",'-tTYPE')
18
18
  Main.tool.options.add_opt_simple(:url,"URI","-wURI","URL of application, e.g. http://org.asperafiles.com")
19
19
  Main.tool.options.add_opt_simple(:username,"STRING","-uSTRING","username to log in")
20
- Main.tool.options.add_opt_simple(:password,"STRING","-pSTRING","password")
21
- Main.tool.options.add_opt_simple(:private_key,"STRING","-kSTRING","RSA private key for JWT (@ for ext. file)")
20
+ Main.tool.options.add_opt_simple(:password,"STRING","-pSTRING","user's password")
21
+ Main.tool.options.add_opt_simple(:private_key,"STRING","-kSTRING","RSA private key PEM value for JWT (prefix file path with @val:@file:)")
22
22
  Main.tool.options.add_opt_simple(:workspace,"STRING","name of workspace")
23
23
  Main.tool.options.add_opt_simple(:recipient,"STRING","package recipient")
24
24
  Main.tool.options.add_opt_simple(:title,"STRING","package title")
@@ -102,13 +102,15 @@ module Asperalm
102
102
  PATH_SEPARATOR='/'
103
103
 
104
104
  def execute_node_action(home_node_id,home_file_id)
105
- command_repo=Main.tool.options.get_next_argument('command',Node.simple_actions.clone.concat([ :browse, :upload, :download, :file ]))
105
+ command_repo=Main.tool.options.get_next_argument('command',[ :node, :file, :browse, :upload, :download ])
106
106
  case command_repo
107
- when *Node.simple_actions
107
+ when :node
108
+ # Note: other "common" actions are unauthorized with user scope
109
+ command_legacy=Main.tool.options.get_next_argument('command',Node.simple_actions)
108
110
  # TODO: shall we support all methods here ? what if there is a link ?
109
111
  node_info=@api_files_user.read("nodes/#{home_node_id}")[:data]
110
112
  node_api=get_files_node_api(node_info,FilesApi::SCOPE_NODE_USER)
111
- return Node.execute_common(command_repo,node_api)
113
+ return Node.execute_common(command_legacy,node_api)
112
114
  when :file
113
115
  fileid=Main.tool.options.get_next_argument("file id")
114
116
  node_info,file_id = find_nodeinfo_and_fileid(home_node_id,fileid,"")
@@ -158,7 +160,7 @@ module Asperalm
158
160
  # get parameters
159
161
  instance_fqdn=URI.parse(Main.tool.options.get_option(:url,:mandatory)).host
160
162
  organization,instance_domain=instance_fqdn.split('.',2)
161
-
163
+
162
164
  raise "expecting a public FQDN for Files" if instance_domain.nil?
163
165
 
164
166
  Log.log.debug("instance_fqdn=#{instance_fqdn}")
@@ -186,9 +188,12 @@ module Asperalm
186
188
  auth_data[:redirect_uri]=Main.tool.options.get_option(:redirect_uri,:mandatory)
187
189
  Log.log.info("redirect_uri=#{auth_data[:redirect_uri]}")
188
190
  when :jwt
189
- auth_data[:private_key]=OpenSSL::PKey::RSA.new(Main.tool.options.get_option(:private_key,:mandatory))
191
+ private_key_PEM_string=Main.tool.options.get_option(:private_key,:mandatory)
192
+ auth_data[:private_key_obj]=OpenSSL::PKey::RSA.new(private_key_PEM_string)
190
193
  auth_data[:subject]=Main.tool.options.get_option(:username,:mandatory)
191
- Log.log.info("private_key=#{auth_data[:private_key]}")
194
+ auth_data[:audience]=FilesApi.apiurl+"/oauth2/token" # TODO: set by parameters
195
+
196
+ Log.log.info("private_key=#{auth_data[:private_key_obj]}")
192
197
  Log.log.info("subject=#{auth_data[:subject]}")
193
198
  when :url_token
194
199
  auth_data[:url_token]=Main.tool.options.get_option(:url_token,:mandatory)
@@ -282,7 +287,7 @@ module Asperalm
282
287
  packages=@api_files_user.read("packages",{'archived'=>false,'exclude_dropbox_packages'=>true,'has_content'=>true,'received'=>true,'workspace_id'=>@workspace_id})[:data]
283
288
  return {:data=>packages,:fields=>['id','name','bytes_transferred'],:type=>:hash_array}
284
289
  end
285
- when :repo
290
+ when :repository
286
291
  return execute_node_action(@workspace_data['home_node_id'],@workspace_data['home_file_id'])
287
292
  when :faspexgw
288
293
  require 'asperalm/faspex_gw'
@@ -89,7 +89,8 @@ module Asperalm
89
89
  end
90
90
 
91
91
  # retrieve tranfer list using API and persistency file
92
- def get_transfers_iteration(api_node,persistencyfile,params)
92
+ def self.get_transfers_iteration(api_node,params)
93
+ persistencyfile=Main.tool.options.get_option(:persistency,:mandatory)
93
94
  # first time run ? or subsequent run ?
94
95
  iteration_token=nil
95
96
  if !persistencyfile.nil? and File.exist?(persistencyfile)
@@ -133,16 +134,6 @@ module Asperalm
133
134
  when :info
134
135
  node_info=api_node.call({:operation=>'GET',:subpath=>'info',:headers=>{'Accept'=>'application/json'}})[:data]
135
136
  return { :type=>:key_val_list, :data => node_info, :textify => lambda { |table_data| textify_bool_list_result(table_data,['capabilities','settings'])}}
136
- when :browse
137
- thepath=get_next_arg_add_prefix(prefix_path,"path")
138
- send_result=api_node.call({:operation=>'POST',:subpath=>'files/browse',:json_params=>{ :path => thepath} } )
139
- #send_result={:data=>{'items'=>[{'file'=>"filename1","permissions"=>[{'name'=>'read'},{'name'=>'write'}]}]}}
140
- return Main.no_result if !send_result[:data].has_key?('items')
141
- result={ :data => send_result[:data]['items'] , :type => :hash_array, :textify => lambda { |table_data| Node.textify_browse(table_data) } }
142
- #display_prefix=thepath
143
- #display_prefix=File.join(prefix_path,display_prefix) if !prefix_path.nil?
144
- #puts display_prefix.red
145
- return result_remove_prefix_path(result,'path',prefix_path)
146
137
  when :delete
147
138
  paths_to_delete = get_next_arg_add_prefix(prefix_path,"file list",:multiple)
148
139
  return delete_files(api_node,paths_to_delete,prefix_path)
@@ -173,6 +164,16 @@ module Asperalm
173
164
  path_dst=get_next_arg_add_prefix(prefix_path,"path_dst")
174
165
  resp=api_node.call({:operation=>'POST',:subpath=>'files/rename',:json_params=>{ "paths" => [{ "path" => path_base, "source" => path_src, "destination" => path_dst } ] } } )
175
166
  return result_translate_rem_prefix(resp,'entry','moved',prefix_path)
167
+ when :browse
168
+ thepath=get_next_arg_add_prefix(prefix_path,"path")
169
+ send_result=api_node.call({:operation=>'POST',:subpath=>'files/browse',:json_params=>{ :path => thepath} } )
170
+ #send_result={:data=>{'items'=>[{'file'=>"filename1","permissions"=>[{'name'=>'read'},{'name'=>'write'}]}]}}
171
+ return Main.no_result if !send_result[:data].has_key?('items')
172
+ result={ :data => send_result[:data]['items'] , :type => :hash_array, :textify => lambda { |table_data| Node.textify_browse(table_data) } }
173
+ #display_prefix=thepath
174
+ #display_prefix=File.join(prefix_path,display_prefix) if !prefix_path.nil?
175
+ #puts display_prefix.red
176
+ return result_remove_prefix_path(result,'path',prefix_path)
176
177
  when :upload
177
178
  filelist = Main.tool.options.get_next_argument("source file list",:multiple)
178
179
  Log.log.debug("file list=#{filelist}")
@@ -222,7 +223,7 @@ module Asperalm
222
223
  end
223
224
  end
224
225
 
225
- def action_list; self.class.common_actions.clone.concat([ :stream, :transfer, :cleanup, :forward, :access_key, :watch_folder, :service, :async, :central ]);end
226
+ def action_list; self.class.common_actions.clone.concat([ :postprocess,:stream, :transfer, :cleanup, :forward, :access_key, :watch_folder, :service, :async, :central ]);end
226
227
 
227
228
  def execute_action
228
229
  api_node=Rest.new(Main.tool.options.get_option(:url,:mandatory),{:auth=>{:type=>:basic,:username=>Main.tool.options.get_option(:username,:mandatory), :password=>Main.tool.options.get_option(:password,:mandatory)}})
@@ -362,7 +363,7 @@ module Asperalm
362
363
  return {:data=>resp[:data]["session_info_result"]["session_info"],:type=>:hash_array,:fields=>["session_uuid","status","transport","direction","bytes_transferred"]}
363
364
  end
364
365
  when :cleanup
365
- transfers=self.class.get_transfers_iteration(api_node,Main.tool.options.get_option(:persistency,:mandatory),{:active_only=>false})
366
+ transfers=self.class.get_transfers_iteration(api_node,{:active_only=>false})
366
367
  filter_transfer=Main.tool.options.get_option(:filter_transfer,:mandatory)
367
368
  filter_file=Main.tool.options.get_option(:filter_file,:mandatory)
368
369
  Log.log.debug("filter_transfer: #{filter_transfer}")
@@ -391,7 +392,7 @@ module Asperalm
391
392
  return Main.no_result
392
393
  when :forward
393
394
  # detect transfer sessions since last call
394
- transfers=self.class.get_transfers_iteration(api_node,Main.tool.options.get_option(:persistency,:optional),{:active_only=>false})
395
+ transfers=self.class.get_transfers_iteration(api_node,{:active_only=>false})
395
396
  # build list of all files received in all sessions
396
397
  filelist=[]
397
398
  transfers.select { |t| t['status'].eql?('completed') and t['start_spec']['direction'].eql?('receive') }.each do |t|
@@ -411,7 +412,10 @@ module Asperalm
411
412
  transfer_spec=transfer_data['transfer_spec']
412
413
  # execute transfer
413
414
  return Main.tool.start_transfer(transfer_spec)
414
- end
415
+ when :postprocess
416
+ transfers=self.class.get_transfers_iteration(api_node,{:view=>'summary',:direction=>'receive',:active_only=>false})
417
+ return { :type=>:hash_array,:data => transfers }
418
+ end # case command
415
419
  raise "ERROR: shall not reach this line"
416
420
  end # execute_action
417
421
  end # Main
@@ -51,7 +51,7 @@ module Asperalm
51
51
  password=Main.tool.options.get_option(:password,:optional)
52
52
  if !password.nil?
53
53
  ssh_options[:password]=password
54
- transfer_spec["password"]=password
54
+ transfer_spec['remote_password']=password
55
55
  cred_set=true
56
56
  end
57
57
  ssh_keys=Main.tool.options.get_option(:ssh_keys,:optional)
@@ -1,4 +1,4 @@
1
- require 'asperalm/fasp/resource_finder'
1
+ require 'asperalm/fasp/installation'
2
2
  require 'asperalm/fasp/resumer'
3
3
  require 'asperalm/fasp/manager'
4
4
  require 'securerandom'
@@ -28,7 +28,7 @@ module Asperalm
28
28
  trynumber=0
29
29
  begin
30
30
  Log.log.debug("reading connect port file")
31
- connect_url=File.open(ResourceFinder.path(:plugin_https_port_file)) {|f| f.gets }.strip
31
+ connect_url=File.open(Installation.instance.path(:plugin_https_port_file)) {|f| f.gets }.strip
32
32
  connect_api=Rest.new("#{connect_url}/v5/connect",{})
33
33
  connect_api.read('info/version')
34
34
  rescue => e # Errno::ECONNREFUSED
@@ -0,0 +1,168 @@
1
+ require 'asperalm/log'
2
+ require 'asperalm/operating_system'
3
+ require 'singleton'
4
+ require 'xmlsimple'
5
+
6
+ module Asperalm
7
+ module Fasp
8
+ # locate Aspera transfer products based on OS
9
+ # then identifies resources (binary, keys..)
10
+ class Installation
11
+ include Singleton
12
+ VARRUN_SUBFOLDER='var/run'
13
+ FIRST_FOUND=:first
14
+
15
+ # name of Aspera application to be used
16
+ attr_reader :activated
17
+ def activated=(value)
18
+ @activated=value
19
+ # installed paths
20
+ @i_p=nil
21
+ end
22
+
23
+ def initialize
24
+ @i_p=nil
25
+ @found_products=nil
26
+ @activated=FIRST_FOUND
27
+ end
28
+
29
+ # a user can set an alternate location, example:
30
+ # { :expected=>'Enterprise Server',
31
+ # :ascp=>'ascp',
32
+ # :app_root=>'/Library/Aspera',
33
+ # :run_root=>File.join(Dir.home,'Library','Application Support','Aspera','Enterprise Server'),
34
+ # :log_root=>File.join(Dir.home,'Library','Logs','Aspera'),
35
+ # :sub_bin=>'bin',
36
+ # :sub_keys=>'var',
37
+ # :dsa=>'aspera_tokenauth_id_dsa'}
38
+ def set_location(p)
39
+ @i_p={}
40
+ @i_p[:ascp] = { :path =>File.join(p[:app_root],p[:sub_bin],p[:ascp]), :type => :file, :required => true}
41
+ @i_p[:ssh_bypass_key_dsa] = { :path =>File.join(p[:app_root],p[:sub_keys],p[:dsa]), :type => :file, :required => true}
42
+ @i_p[:ssh_bypass_key_rsa] = { :path =>File.join(p[:app_root],p[:sub_keys],'aspera_tokenauth_id_rsa'), :type => :file, :required => true}
43
+ @i_p[:fallback_cert] = { :path =>File.join(p[:app_root],p[:sub_keys],'aspera_web_cert.pem'), :type => :file, :required => false}
44
+ @i_p[:fallback_key] = { :path =>File.join(p[:app_root],p[:sub_keys],'aspera_web_key.pem'), :type => :file, :required => false}
45
+ @i_p[:localhost_cert] = { :path =>File.join(p[:app_root],p[:sub_keys],'localhost.crt'), :type => :file, :required => false}
46
+ @i_p[:localhost_key] = { :path =>File.join(p[:app_root],p[:sub_keys],'localhost.key'), :type => :file, :required => false}
47
+ @i_p[:plugin_https_port_file] = { :path =>File.join(p[:run_root],VARRUN_SUBFOLDER,'https.uri'), :type => :file, :required => false}
48
+ @i_p[:log_folder] = { :path =>p[:log_root], :type => :folder, :required => false}
49
+ Log.log.debug "resources=#{@i_p}"
50
+ notfound=[]
51
+ @i_p.each_pair do |k,v|
52
+ notfound.push(k) if v[:type].eql?(:file) and v[:required] and ! File.exist?(v[:path])
53
+ end
54
+ if !notfound.empty?
55
+ reslist=notfound.map { |k| "#{k.to_s}: #{@i_p[k][:path]}"}.join("\n")
56
+ raise StandardError.new("Please check your connect client installation, Cannot locate resource(s):\n#{reslist}")
57
+ end
58
+ end
59
+
60
+ # installation paths
61
+ # get fasp resource files paths
62
+ def paths
63
+ return @i_p unless @i_p.nil?
64
+ # this contains var/run, files generated on runtime
65
+ if @activated.eql?(FIRST_FOUND)
66
+ p = installed_products.first
67
+ else
68
+ p=installed_products.select{|p|p[:name].eql?(@activated)}.first
69
+ end
70
+ raise "no FASP installation found\nPlease check manual on how to install FASP." if p.nil?
71
+ set_location(p)
72
+ return @i_p
73
+ end
74
+
75
+ # user can set all path directly
76
+ def paths=(path_set)
77
+ raise "must be a hash" if !path_set.is_a?(Hash)
78
+ @i_p=path_set
79
+ end
80
+
81
+ # get path of one resource file
82
+ def path(k)
83
+ file=paths[k][:path]
84
+ raise "no such file: #{file}" if !File.exist?(file)
85
+ return file
86
+ end
87
+
88
+ # returns product folders depending on OS
89
+ def product_locations
90
+ common_places=[]
91
+ case OperatingSystem.current_os_type
92
+ when :mac
93
+ common_places.push({
94
+ :expected=>'Connect Client',
95
+ :ascp=>'ascp',
96
+ :app_root=>File.join(Dir.home,'Applications','Aspera Connect.app'),
97
+ :run_root=>File.join(Dir.home,'Library','Application Support','Aspera','Aspera Connect'),
98
+ :log_root=>File.join(Dir.home,'Library','Logs','Aspera'),
99
+ :sub_bin=>File.join('Contents','Resources'),
100
+ :sub_keys=>File.join('Contents','Resources'),
101
+ :dsa=>'asperaweb_id_dsa.openssh'})
102
+ common_places.push({
103
+ :expected=>'Enterprise Server',
104
+ :ascp=>'ascp',
105
+ :app_root=>'/Library/Aspera',
106
+ :run_root=>File.join(Dir.home,'Library','Application Support','Aspera','Enterprise Server'),
107
+ :log_root=>File.join(Dir.home,'Library','Logs','Aspera'),
108
+ :sub_bin=>'bin',
109
+ :sub_keys=>'var',
110
+ :dsa=>'aspera_tokenauth_id_dsa'})
111
+ common_places.push({
112
+ :expected=>'Aspera CLI',
113
+ :ascp=>'ascp',
114
+ :app_root=>File.join(Dir.home,'Applications','Aspera CLI'),
115
+ :run_root=>File.join(Dir.home,'Library','Application Support','Aspera','Aspera Connect'),
116
+ :log_root=>File.join(Dir.home,'Library','Logs','Aspera'),
117
+ :sub_bin=>File.join('bin'),
118
+ :sub_keys=>File.join('etc'),
119
+ :dsa=>'asperaweb_id_dsa.openssh'})
120
+ when :windows
121
+ common_places.push({
122
+ :expected=>'Connect Client',
123
+ :ascp=>'ascp.exe',
124
+ :app_root=>File.join(ENV['LOCALAPPDATA'],'Programs','Aspera','Aspera Connect'),
125
+ :run_root=>File.join(ENV['LOCALAPPDATA'],'Aspera','Aspera Connect'),
126
+ :sub_bin=>'bin',
127
+ :sub_keys=>'etc',
128
+ :dsa=>'asperaweb_id_dsa.openssh'})
129
+ else # unix family
130
+ common_places.push({
131
+ :expected=>'Connect Client',
132
+ :ascp=>'ascp',
133
+ :app_root=>File.join(Dir.home,'.aspera','connect'),
134
+ :run_root=>File.join(Dir.home,'.aspera','connect'),
135
+ :sub_bin=>'bin',
136
+ :sub_keys=>'etc',
137
+ :dsa=>'asperaweb_id_dsa.openssh'})
138
+ common_places.push({
139
+ :expected=>'Enterprise Server',
140
+ :ascp=>'ascp',
141
+ :app_root=>'/opt/aspera',
142
+ :run_root=>'/opt/aspera',
143
+ :sub_bin=>'bin',
144
+ :sub_keys=>'var',
145
+ :dsa=>'aspera_tokenauth_id_dsa'})
146
+ end
147
+ return common_places
148
+ end
149
+
150
+ # try to find connect client or other Aspera product installed.
151
+ def installed_products
152
+ return @found_products unless @found_products.nil?
153
+ @found_products=product_locations.select do |l|
154
+ next false unless Dir.exist?(l[:app_root])
155
+ product_info_file="#{l[:app_root]}/product-info.mf"
156
+ if File.exist?(product_info_file)
157
+ res_s=XmlSimple.xml_in(File.read(product_info_file),{"ForceArray"=>false})
158
+ l[:name]=res_s['name']
159
+ l[:version]=res_s['version']
160
+ else
161
+ l[:name]=l[:expected]
162
+ end
163
+ true # select this version
164
+ end
165
+ end
166
+ end # Installation
167
+ end # Fasp
168
+ end # Asperalm
@@ -14,7 +14,7 @@ require 'singleton'
14
14
  require 'asperalm/fasp/listener'
15
15
  require 'asperalm/fasp/error'
16
16
  require 'asperalm/fasp/parameters'
17
- require 'asperalm/fasp/resource_finder'
17
+ require 'asperalm/fasp/installation'
18
18
  require 'asperalm/log'
19
19
 
20
20
  # for file lists
@@ -23,7 +23,7 @@ require 'asperalm/log'
23
23
  module Asperalm
24
24
  module Fasp
25
25
  ACCESS_KEY_TRANSFER_USER='xfer'
26
- # Manages FASP based transfers based on local ascp command line
26
+ # Manages FASP based transfers based on local ascp process
27
27
  class Manager
28
28
  # use "instance" class method
29
29
  include Singleton
@@ -36,17 +36,13 @@ module Asperalm
36
36
  downcase
37
37
  end
38
38
 
39
- # user can also specify another location for ascp
40
- attr_accessor :ascp_path
41
-
42
39
  def initialize
43
- @ascp_path=Fasp::ResourceFinder.path(:ascp)
44
40
  @listeners=[]
45
41
  end
46
42
 
47
43
  # fields that shall be integer in JSON
48
- IntegerFields=['Rate','MinRate','Port','Priority','RateCap','MinRateCap','TCPPort','CreatePolicy','TimePolicy','DatagramSize','XoptFlags','VLinkVersion','PeerVLinkVersion','DSPipelineDepth','PeerDSPipelineDepth','ReadBlockSize','WriteBlockSize','ClusterNumNodes','ClusterNodeId','Size','Written','Loss','FileBytes','PreTransferBytes','TransferBytes','PMTU','Elapsedusec','ArgScansAttempted','ArgScansCompleted','PathScansAttempted','FileScansCompleted','TransfersAttempted','TransfersPassed','Delay']
49
-
44
+ IntegerFields=['Bytescont','FaspFileArgIndex','StartByte','Rate','MinRate','Port','Priority','RateCap','MinRateCap','TCPPort','CreatePolicy','TimePolicy','DatagramSize','XoptFlags','VLinkVersion','PeerVLinkVersion','DSPipelineDepth','PeerDSPipelineDepth','ReadBlockSize','WriteBlockSize','ClusterNumNodes','ClusterNodeId','Size','Written','Loss','FileBytes','PreTransferBytes','TransferBytes','PMTU','Elapsedusec','ArgScansAttempted','ArgScansCompleted','PathScansAttempted','FileScansCompleted','TransfersAttempted','TransfersPassed','Delay']
45
+ BooleanFields=['Encryption','Remote','RateLock','MinRateLock','PolicyLock','FilesEncrypt','FilesDecrypt','VLinkLocalEnabled','VLinkRemoteEnabled','MoveRange','Keepalive','TestLogin','UseProxy','Precalc','RTTAutocorrect']
50
46
  # event format
51
47
  Formats=[:text,:struct,:enhanced]
52
48
 
@@ -58,12 +54,13 @@ module Asperalm
58
54
  self
59
55
  end
60
56
 
61
- # translates legacy event into enhanced event
57
+ # translates legacy event into enhanced (JSON) event
62
58
  def enhanced_event_format(event)
63
59
  return event.keys.inject({}) do |h,e|
64
60
  new_name=Manager.snake_case(e)
65
61
  value=event[e]
66
62
  value=value.to_i if IntegerFields.include?(e)
63
+ value=value.eql?('Yes') ? true : false if BooleanFields.include?(e)
67
64
  h[new_name]=value
68
65
  h
69
66
  end
@@ -90,8 +87,10 @@ module Asperalm
90
87
  # currently, relies on command line arguments
91
88
  # start ascp with management port.
92
89
  # raises FaspError on error
90
+ # @param a hash containing :args and :env
93
91
  def start_transfer_with_args_env(ascp_params)
94
- raise Fasp::Error.new("no ascp path defined") if @ascp_path.nil?
92
+ ascp_path=Fasp::Installation.instance.path(:ascp)
93
+ raise Fasp::Error.new("no ascp path defined") if ascp_path.nil?
95
94
  begin
96
95
  ascp_pid=nil
97
96
  ascp_arguments=ascp_params[:args].clone
@@ -100,8 +99,8 @@ module Asperalm
100
99
  # add management port
101
100
  ascp_arguments.unshift('-M', mgt_sock.addr[1].to_s)
102
101
  # start ascp in sub process
103
- Log.log.debug "execute: #{ascp_params[:env].map{|k,v| "#{k}=\"#{v}\""}.join(' ')} \"#{@ascp_path}\" \"#{ascp_arguments.join('" "')}\""
104
- ascp_pid = Process.spawn(ascp_params[:env],[@ascp_path,@ascp_path],*ascp_arguments)
102
+ Log.log.debug "execute: #{ascp_params[:env].map{|k,v| "#{k}=\"#{v}\""}.join(' ')} \"#{ascp_path}\" \"#{ascp_arguments.join('" "')}\""
103
+ ascp_pid = Process.spawn(ascp_params[:env],[ascp_path,ascp_path],*ascp_arguments)
105
104
  # in parent, wait for connection to socket max 3 seconds
106
105
  Log.log.debug "before accept for pid (#{ascp_pid})"
107
106
  ascp_mgt_io=nil
@@ -180,18 +179,20 @@ module Asperalm
180
179
 
181
180
  # start FASP transfer based on transfer spec (hash table)
182
181
  # note that it returns upon completion only
182
+ # if the user wants to run in background, just spawn a thread
183
+ # listener methods are called in context of calling thread
183
184
  def start_transfer(transfer_spec)
184
185
  Log.log().debug("ts=#{transfer_spec}")
185
186
  # shall we use bypass keys ?
186
187
  if transfer_spec['authentication'].eql?("token")
187
188
  # add Aspera private keys for web access, token based authorization
188
- transfer_spec['EX_ssh_key_paths'] = [ ResourceFinder.path(:ssh_bypass_key_dsa), ResourceFinder.path(:ssh_bypass_key_rsa) ]
189
- transfer_spec['drowssap'.reverse] = "%08x-%04x-%04x-%04x-%04x%08x" % "t1(\xBF;\xF3E\xB5\xAB\x14F\x02\xC6\x7F)P".unpack("NnnnnN")
189
+ transfer_spec['EX_ssh_key_paths'] = [ Installation.instance.path(:ssh_bypass_key_dsa), Installation.instance.path(:ssh_bypass_key_rsa) ]
190
+ transfer_spec['drowssap_etomer'.reverse] = "%08x-%04x-%04x-%04x-%04x%08x" % "t1(\xBF;\xF3E\xB5\xAB\x14F\x02\xC6\x7F)P".unpack("NnnnnN")
190
191
  end
191
192
  # add fallback cert and key
192
193
  if ['1','force'].include?(transfer_spec['http_fallback'])
193
- transfer_spec['EX_fallback_key']=ResourceFinder.path(:fallback_key)
194
- transfer_spec['EX_fallback_cert']=ResourceFinder.path(:fallback_cert)
194
+ transfer_spec['EX_fallback_key']=Installation.instance.path(:fallback_key)
195
+ transfer_spec['EX_fallback_cert']=Installation.instance.path(:fallback_cert)
195
196
  end
196
197
  start_transfer_with_args_env(Parameters.new(transfer_spec).compute_args)
197
198
  return nil
@@ -104,14 +104,14 @@ module Asperalm
104
104
  # transformation input, output, validation
105
105
 
106
106
  # some ssh credentials are required to avoid interactive password input
107
- if !@state[:transfer_spec].has_key?('password') and
107
+ if !@state[:transfer_spec].has_key?('remote_password') and
108
108
  !@state[:transfer_spec].has_key?('EX_ssh_key_value') and
109
109
  !@state[:transfer_spec].has_key?('EX_ssh_key_paths') then
110
110
  raise Fasp::Error.new('required: ssh key (value or path) or password')
111
111
  end
112
112
 
113
113
  # parameters with env vars
114
- param_string_env('password','ASPERA_SCP_PASS')
114
+ param_string_env('remote_password','ASPERA_SCP_PASS')
115
115
  param_string_env('token','ASPERA_SCP_TOKEN')
116
116
  param_string_env('cookie','ASPERA_SCP_COOKIE')
117
117
  param_string_env('EX_ssh_key_value','ASPERA_SCP_KEY')
@@ -1,5 +1,5 @@
1
1
  require 'asperalm/log'
2
- require 'asperalm/fasp/resource_finder'
2
+ require 'asperalm/fasp/installation'
3
3
  require 'sinatra/base'
4
4
  require 'webrick'
5
5
  require 'webrick/https'
@@ -15,8 +15,8 @@ module Asperalm
15
15
  @@api_files_user=api_files_user
16
16
  @@api_files_oauth=@@api_files_user.param_default[:auth][:obj]
17
17
  @@the_workspaceid=workspace_id
18
- $CERTIFICATE=File.read(Fasp::ResourceFinder.path(:localhost_cert))
19
- $PRIVATE_KEY=File.read(Fasp::ResourceFinder.path(:localhost_key))
18
+ $CERTIFICATE=File.read(Fasp::Installation.instance.path(:localhost_cert))
19
+ $PRIVATE_KEY=File.read(Fasp::Installation.instance.path(:localhost_key))
20
20
  webrick_options = {
21
21
  :app => FaspexGW,
22
22
  :Port => 9443,
@@ -5,6 +5,9 @@ module Asperalm
5
5
  def self.baseurl(instance_domain)
6
6
  return 'https://api.'+instance_domain+'/api/v1'
7
7
  end
8
+ def self.apiurl
9
+ return 'https://api.asperafiles.com/api/v1'
10
+ end
8
11
 
9
12
  # node API scopes
10
13
  def self.node_scope(access_key,scope)
@@ -26,6 +26,8 @@ module Asperalm
26
26
  TOKEN_FILE_SEPARATOR='_'
27
27
  TOKEN_FILE_SUFFIX='.txt'
28
28
  WINDOWS_PROTECTED_CHAR=%r{[/:"<>\\\*\?]}
29
+ OFFSET_ALLOWANCE_SEC=300
30
+ ASSERTION_VALIDITY_SEC=3600
29
31
  # delete cached tokens
30
32
  def self.flush_tokens(persist_folder)
31
33
  tokenfiles=Dir[File.join(persist_folder,TOKEN_FILE_PREFIX+'*'+TOKEN_FILE_SUFFIX)]
@@ -193,20 +195,19 @@ module Asperalm
193
195
  }})
194
196
  when :jwt
195
197
  require 'jwt'
196
-
197
198
  # remove 5 minutes to account for time offset
198
- seconds_since_epoch=Time.new.to_i-300
199
+ seconds_since_epoch=Time.new.to_i-OFFSET_ALLOWANCE_SEC
199
200
  Log.log.info("seconds=#{seconds_since_epoch}")
200
201
 
201
202
  payload = {
202
203
  :iss => @auth_data[:client_id],
203
204
  :sub => @auth_data[:subject],
204
- :aud => @rest.base_url+"/oauth2/token",
205
+ :aud => @auth_data[:audience],
205
206
  :nbf => seconds_since_epoch,
206
- :exp => seconds_since_epoch+3600 # TODO: configurable ?
207
+ :exp => seconds_since_epoch+ASSERTION_VALIDITY_SEC # TODO: configurable ?
207
208
  }
208
209
 
209
- rsa_private =@auth_data[:private_key] # rsa_private.public_key
210
+ rsa_private=@auth_data[:private_key_obj] # rsa_private.public_key
210
211
 
211
212
  Log.log.debug("private=[#{rsa_private}]")
212
213
 
@@ -93,6 +93,9 @@ module Asperalm
93
93
  # build URI from URL and parameters
94
94
  def get_uri(call_data)
95
95
  uri=URI.parse(@api_base+"/"+call_data[:subpath])
96
+ if ! ['http','https'].include?(uri.scheme)
97
+ raise "REST endpoint shall be http(s)"
98
+ end
96
99
  if call_data.has_key?(:url_params) and !call_data[:url_params].nil? then
97
100
  uri.query=URI.encode_www_form(call_data[:url_params])
98
101
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: asperalm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.13
4
+ version: 0.5.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Laurent Martin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-01-22 00:00:00.000000000 Z
11
+ date: 2018-01-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: xml-simple
@@ -157,14 +157,14 @@ email:
157
157
  - laurent@asperasoft.com
158
158
  executables:
159
159
  - asclit
160
- - asfasp
160
+ - asession
161
161
  - aslmcli
162
162
  extensions: []
163
163
  extra_rdoc_files: []
164
164
  files:
165
165
  - README.md
166
166
  - bin/asclit
167
- - bin/asfasp
167
+ - bin/asession
168
168
  - bin/aslmcli
169
169
  - docs/Auth1.png
170
170
  - docs/Auth2.png
@@ -189,10 +189,10 @@ files:
189
189
  - lib/asperalm/colors.rb
190
190
  - lib/asperalm/fasp/agent.rb
191
191
  - lib/asperalm/fasp/error.rb
192
+ - lib/asperalm/fasp/installation.rb
192
193
  - lib/asperalm/fasp/listener.rb
193
194
  - lib/asperalm/fasp/manager.rb
194
195
  - lib/asperalm/fasp/parameters.rb
195
- - lib/asperalm/fasp/resource_finder.rb
196
196
  - lib/asperalm/fasp/resumer.rb
197
197
  - lib/asperalm/fasp/uri.rb
198
198
  - lib/asperalm/faspex_gw.rb
@@ -1,115 +0,0 @@
1
- require 'asperalm/log'
2
- require 'asperalm/operating_system'
3
-
4
- module Asperalm
5
- module Fasp
6
- # locate Connect client resources based on OS
7
- class ResourceFinder
8
- @@res=nil
9
- def self.resource
10
- if @@res.nil?
11
- @@res=locate_resources
12
- end
13
- return @@res
14
- end
15
-
16
- def self.path(k)
17
- file=resource[k][:path]
18
- raise "no such file: #{file}" if !File.exist?(file)
19
- return file
20
- end
21
- @@fasp_install_paths=nil
22
-
23
- def self.fasp_install_paths=(path)
24
- raise "must be a hash" if !path.is_a?(Hash)
25
- @@fasp_install_paths=path
26
- end
27
-
28
- # try to find connect client or other Aspera product installed.
29
- def self.fasp_install_paths
30
- if @@fasp_install_paths.nil?
31
- common_places=[]
32
- case OperatingSystem.current_os_type
33
- when :mac
34
- common_places.push({
35
- :ascp=>'ascp',
36
- :app_root=>File.join(Dir.home,'Applications','Aspera Connect.app'),
37
- :run_root=>File.join(Dir.home,'Library','Application Support','Aspera','Aspera Connect'),
38
- :log_root=>File.join(Dir.home,'Library','Logs','Aspera'),
39
- :sub_bin=>File.join('Contents','Resources'),
40
- :sub_keys=>File.join('Contents','Resources'),
41
- :dsa=>'asperaweb_id_dsa.openssh'})
42
- common_places.push({
43
- :ascp=>'ascp',
44
- :app_root=>'/Library/Aspera',
45
- :run_root=>File.join(Dir.home,'Library','Application Support','Aspera','Enterprise Server'),
46
- :log_root=>File.join(Dir.home,'Library','Logs','Aspera'),
47
- :sub_bin=>'bin',
48
- :sub_keys=>'var',
49
- :dsa=>'aspera_tokenauth_id_dsa'})
50
- when :windows
51
- common_places.push({
52
- :ascp=>'ascp.exe',
53
- :app_root=>File.join(ENV['LOCALAPPDATA'],'Programs','Aspera','Aspera Connect'),
54
- :run_root=>File.join(ENV['LOCALAPPDATA'],'Aspera','Aspera Connect'),
55
- :sub_bin=>'bin',
56
- :sub_keys=>'etc',
57
- :dsa=>'asperaweb_id_dsa.openssh'})
58
- else # unix family
59
- common_places.push({
60
- :ascp=>'ascp',
61
- :app_root=>File.join(Dir.home,'.aspera','connect'),
62
- :run_root=>File.join(Dir.home,'.aspera','connect'),
63
- :sub_bin=>'bin',
64
- :sub_keys=>'etc',
65
- :dsa=>'asperaweb_id_dsa.openssh'})
66
- common_places.push({
67
- :ascp=>'ascp',
68
- :app_root=>'/opt/aspera',
69
- :run_root=>'/opt/aspera',
70
- :sub_bin=>'bin',
71
- :sub_keys=>'var',
72
- :dsa=>'aspera_tokenauth_id_dsa'})
73
- end
74
- common_places.each do |one_place|
75
- if Dir.exist?(one_place[:app_root])
76
- Log.log.debug("found: #{one_place[:app_root]}")
77
- @@fasp_install_paths=one_place
78
- return @@fasp_install_paths
79
- end
80
- end
81
- Log.log.debug("no FASP found in common places".red)
82
- end
83
- return @@fasp_install_paths
84
- end
85
-
86
- # locate connect plugin resources
87
- def self.locate_resources
88
- # this contains var/run, files generated on runtime
89
- sub_varrun='var/run'
90
- p = fasp_install_paths
91
- raise "no FASP installation found\nPlease check manual on how to install FASP." if p.nil?
92
- res={}
93
- res[:ascp] = { :path =>File.join(p[:app_root],p[:sub_bin],p[:ascp]), :type => :file, :required => true}
94
- res[:ssh_bypass_key_dsa] = { :path =>File.join(p[:app_root],p[:sub_keys],p[:dsa]), :type => :file, :required => true}
95
- res[:ssh_bypass_key_rsa] = { :path =>File.join(p[:app_root],p[:sub_keys],'aspera_tokenauth_id_rsa'), :type => :file, :required => true}
96
- res[:fallback_cert] = { :path =>File.join(p[:app_root],p[:sub_keys],'aspera_web_cert.pem'), :type => :file, :required => false}
97
- res[:fallback_key] = { :path =>File.join(p[:app_root],p[:sub_keys],'aspera_web_key.pem'), :type => :file, :required => false}
98
- res[:localhost_cert] = { :path =>File.join(p[:app_root],p[:sub_keys],'localhost.crt'), :type => :file, :required => false}
99
- res[:localhost_key] = { :path =>File.join(p[:app_root],p[:sub_keys],'localhost.key'), :type => :file, :required => false}
100
- res[:plugin_https_port_file] = { :path =>File.join(p[:run_root],sub_varrun,'https.uri'), :type => :file, :required => false}
101
- res[:log_folder] = { :path =>p[:log_root], :type => :folder, :required => false}
102
- Log.log.debug "resources=#{res}"
103
- notfound=[]
104
- res.each_pair do |k,v|
105
- notfound.push(k) if v[:type].eql?(:file) and v[:required] and ! File.exist?(v[:path])
106
- end
107
- if !notfound.empty?
108
- reslist=notfound.map { |k| "#{k.to_s}: #{res[k][:path]}"}.join("\n")
109
- raise StandardError.new("Please check your connect client installation, Cannot locate resource(s):\n#{reslist}")
110
- end
111
- return res
112
- end
113
- end # ResourceFinder
114
- end # Fasp
115
- end # Asperalm