aspera-cli 4.9.0 → 4.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/README.md +749 -667
- data/docs/test_env.conf +6 -4
- data/examples/dascli +9 -4
- data/examples/faspex4.rb +1 -1
- data/examples/node.rb +1 -1
- data/examples/server.rb +1 -1
- data/lib/aspera/cli/info.rb +2 -2
- data/lib/aspera/cli/main.rb +1 -1
- data/lib/aspera/cli/manager.rb +6 -4
- data/lib/aspera/cli/plugin.rb +5 -1
- data/lib/aspera/cli/plugins/aoc.rb +1 -1
- data/lib/aspera/cli/plugins/config.rb +100 -84
- data/lib/aspera/cli/plugins/faspex.rb +3 -3
- data/lib/aspera/cli/plugins/faspex5.rb +5 -1
- data/lib/aspera/cli/plugins/node.rb +24 -4
- data/lib/aspera/cli/plugins/preview.rb +1 -1
- data/lib/aspera/cli/transfer_agent.rb +3 -2
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/environment.rb +19 -1
- data/lib/aspera/fasp/agent_direct.rb +4 -0
- data/lib/aspera/fasp/agent_httpgw.rb +147 -88
- data/lib/aspera/fasp/installation.rb +4 -4
- data/lib/aspera/fasp/parameters.rb +13 -1
- data/lib/aspera/fasp/parameters.yaml +5 -2
- data/lib/aspera/fasp/resume_policy.rb +1 -1
- data/lib/aspera/keychain/encrypted_hash.rb +36 -98
- data/lib/aspera/keychain/macos_security.rb +127 -57
- data/lib/aspera/persistency_folder.rb +3 -2
- data/lib/aspera/proxy_auto_config.rb +12 -5
- data/lib/aspera/rest.rb +19 -10
- data.tar.gz.sig +0 -0
- metadata +5 -33
- metadata.gz.sig +0 -0
data/docs/test_env.conf
CHANGED
@@ -6,8 +6,7 @@ default:
|
|
6
6
|
aoc: tst_aoc1
|
7
7
|
faspex: tst_faspex
|
8
8
|
faspex5: tst_faspex5
|
9
|
-
shares:
|
10
|
-
shares2: tst_shares2
|
9
|
+
shares: tst_shares
|
11
10
|
node: tst_node
|
12
11
|
server: tst_server
|
13
12
|
orchestrator: tst_orch
|
@@ -74,11 +73,11 @@ tst_shares_1:
|
|
74
73
|
url: your value here
|
75
74
|
username: your value here
|
76
75
|
password: your value here
|
77
|
-
|
76
|
+
tst_node:
|
78
77
|
url: your value here
|
79
78
|
username: your value here
|
80
79
|
password: your value here
|
81
|
-
|
80
|
+
node_srv:
|
82
81
|
url: your value here
|
83
82
|
username: your value here
|
84
83
|
password: your value here
|
@@ -118,6 +117,9 @@ tst_cos:
|
|
118
117
|
crn: your value here
|
119
118
|
bucket: your value here
|
120
119
|
endpoint: your value here
|
120
|
+
sync:
|
121
|
+
local_path: your value here
|
122
|
+
remote_path: your value here
|
121
123
|
misc:
|
122
124
|
upload_folder: your value here
|
123
125
|
syncuser: your value here
|
data/examples/dascli
CHANGED
@@ -1,12 +1,16 @@
|
|
1
1
|
#!/usr/bin/env bash
|
2
|
+
# set env var image to specify another docker image
|
3
|
+
# set env var version to specify another image version
|
4
|
+
# set env var docker_args to add options to docker run
|
2
5
|
: ${image:=martinlaurent/ascli}
|
3
6
|
# by default take latest version
|
4
7
|
: ${version:=latest}
|
5
|
-
|
8
|
+
: ${docker:=docker}
|
9
|
+
: ${imgtag=$image:$version}
|
10
|
+
# transform var into array
|
11
|
+
add_dock_args=( $docker_args )
|
6
12
|
# same location as in Dockerfile: main config folder for ascli in container
|
7
13
|
ascli_home_container=/home/cliuser/.aspera/ascli
|
8
|
-
# convenience: special argument to install the image
|
9
|
-
case "$1" in install) docker pull $imgtag; exit 0; esac
|
10
14
|
# set default location for config folder on host if necessary
|
11
15
|
: ${ASCLI_HOME:=$HOME/.aspera/ascli}
|
12
16
|
if test ! -d $ASCLI_HOME;then
|
@@ -14,10 +18,11 @@ if test ! -d $ASCLI_HOME;then
|
|
14
18
|
# create it if necessary to allow mounting the volume in container
|
15
19
|
mkdir -p "$ASCLI_HOME"
|
16
20
|
fi
|
17
|
-
exec docker run \
|
21
|
+
exec $docker run \
|
18
22
|
--rm \
|
19
23
|
--tty \
|
20
24
|
--interactive \
|
21
25
|
--volume "$ASCLI_HOME:$ascli_home_container" \
|
26
|
+
"${add_dock_args[@]}" \
|
22
27
|
$imgtag \
|
23
28
|
ascli "$@"
|
data/examples/faspex4.rb
CHANGED
@@ -74,7 +74,7 @@ Aspera::Log.dump('job_id',job_id)
|
|
74
74
|
result = transfer_client.wait_for_transfers_completion
|
75
75
|
# notify of any transfer error
|
76
76
|
result.reject{|i|i.eql?(:success)}.each do |e|
|
77
|
-
Aspera::Log.log.error("A transfer error
|
77
|
+
Aspera::Log.log.error("A transfer error occurred: #{e.message}")
|
78
78
|
end
|
79
79
|
|
80
80
|
# 3: Faspex 4 API v4
|
data/examples/node.rb
CHANGED
@@ -93,4 +93,4 @@ transfer_agent.start_transfer(transfer_spec)
|
|
93
93
|
transfer_result = transfer_agent.wait_for_transfers_completion
|
94
94
|
errors = transfer_result.reject{|i|i.eql?(:success)}
|
95
95
|
# the transfer was not success, as there is at least one error
|
96
|
-
raise "Error(s)
|
96
|
+
raise "Error(s) occurred: #{errors.join(',')}" if !errors.empty?
|
data/examples/server.rb
CHANGED
@@ -90,4 +90,4 @@ $stdout.puts(JSON.generate(transfer_result))
|
|
90
90
|
# get list of errors only
|
91
91
|
errors = transfer_result.reject{|i|i.eql?(:success)}
|
92
92
|
# the transfer was not success, as there is at least one error
|
93
|
-
raise "Error(s)
|
93
|
+
raise "Error(s) occurred: #{errors.join(',')}" if !errors.empty?
|
data/lib/aspera/cli/info.rb
CHANGED
@@ -10,9 +10,9 @@ module Aspera
|
|
10
10
|
GEM_URL = "https://rubygems.org/gems/#{GEM_NAME}"
|
11
11
|
SRC_URL = 'https://github.com/IBM/aspera-cli'
|
12
12
|
# set this to warn in advance when minimum required ruby version will increase
|
13
|
-
# for example currently minimum version is 2.4 in gemspec, but future minimum will be
|
13
|
+
# for example currently minimum version is 2.4 in gemspec, but future minimum will be different
|
14
14
|
# set to current minimum if there is no deprecation
|
15
15
|
# the actual current minimum required version is in gemspec at required_ruby_version
|
16
|
-
RUBY_FUTURE_MINIMUM_VERSION = '2.
|
16
|
+
RUBY_FUTURE_MINIMUM_VERSION = '2.7'
|
17
17
|
end
|
18
18
|
end
|
data/lib/aspera/cli/main.rb
CHANGED
@@ -87,7 +87,7 @@ module Aspera
|
|
87
87
|
if @option_insecure
|
88
88
|
url=http.inspect.gsub(/^[^ ]* /,'https://').gsub(/ [^ ]*$/,'')
|
89
89
|
if !@ssl_warned_urls.include?(url)
|
90
|
-
@plugin_env[:formater].display_message(:error,"#{WARNING_FLASH} ignoring certificate for: #{url}.
|
90
|
+
@plugin_env[:formater].display_message(:error,"#{WARNING_FLASH} ignoring certificate for: #{url}. Do not use unsafe certificates in production.")
|
91
91
|
@ssl_warned_urls.push(url)
|
92
92
|
end
|
93
93
|
http.verify_mode = SELF_SIGNED_CERT
|
data/lib/aspera/cli/manager.rb
CHANGED
@@ -44,15 +44,17 @@ module Aspera
|
|
44
44
|
# resolves on extended value syntax
|
45
45
|
class Manager
|
46
46
|
# boolean options are set to true/false from the following values
|
47
|
-
|
48
|
-
|
49
|
-
|
47
|
+
BOOLEAN_SIMPLE = %i[no yes].freeze
|
48
|
+
FALSE_VALUES = [BOOLEAN_SIMPLE.first,false].freeze
|
49
|
+
TRUE_VALUES = [BOOLEAN_SIMPLE.last,true].freeze
|
50
|
+
BOOLEAN_VALUES = [TRUE_VALUES,FALSE_VALUES].flatten.freeze
|
51
|
+
|
50
52
|
# option name separator on command line
|
51
53
|
OPTION_SEP_LINE = '-'
|
52
54
|
# option name separator in code (symbol)
|
53
55
|
OPTION_SEP_NAME = '_'
|
54
56
|
|
55
|
-
private_constant :TRUE_VALUES,:BOOLEAN_VALUES,:OPTION_SEP_LINE,:OPTION_SEP_NAME
|
57
|
+
private_constant :FALSE_VALUES,:TRUE_VALUES,:BOOLEAN_VALUES,:OPTION_SEP_LINE,:OPTION_SEP_NAME
|
56
58
|
|
57
59
|
class << self
|
58
60
|
def enum_to_bool(enum)
|
data/lib/aspera/cli/plugin.rb
CHANGED
@@ -35,7 +35,9 @@ module Aspera
|
|
35
35
|
options.add_opt_simple(:property,'name of property to set')
|
36
36
|
options.add_opt_simple(:id,"resource identifier (#{INSTANCE_OPS.join(',')})")
|
37
37
|
options.add_opt_boolean(:bulk,'Bulk operation (only some)')
|
38
|
+
options.add_opt_boolean(:bfail,'Bulk operation error handling')
|
38
39
|
options.set_option(:bulk,:no)
|
40
|
+
options.set_option(:bfail,:yes)
|
39
41
|
options.parse_options!
|
40
42
|
@@options_created = true # rubocop:disable Style/ClassVars
|
41
43
|
end
|
@@ -72,6 +74,7 @@ module Aspera
|
|
72
74
|
result = res if param.is_a?(Hash)
|
73
75
|
result['status'] = success_msg
|
74
76
|
rescue StandardError => e
|
77
|
+
raise e if options.get_option(:bfail)
|
75
78
|
result['status'] = e.to_s
|
76
79
|
end
|
77
80
|
result_list.push(result)
|
@@ -140,7 +143,8 @@ module Aspera
|
|
140
143
|
end
|
141
144
|
data = item_list
|
142
145
|
end
|
143
|
-
return {type: :object_list, data: data, fields: display_fields}
|
146
|
+
return {type: :object_list, data: data, fields: display_fields} if data.empty? || data.first.is_a?(Hash)
|
147
|
+
return {type: :value_list, data: data, name: 'id'}
|
144
148
|
when :modify
|
145
149
|
property = options.get_option(:property)
|
146
150
|
parameters = {property => parameters} unless property.nil?
|
@@ -673,7 +673,7 @@ module Aspera
|
|
673
673
|
startdate_persistency&.save
|
674
674
|
if !options.get_option(:notif_to).nil?
|
675
675
|
events.each do |tr_event|
|
676
|
-
config.send_email_template({ev: tr_event})
|
676
|
+
config.send_email_template(values: {ev: tr_event})
|
677
677
|
end
|
678
678
|
end
|
679
679
|
return {type: :object_list,data: events}
|
@@ -4,6 +4,7 @@ require 'aspera/cli/basic_auth_plugin'
|
|
4
4
|
require 'aspera/cli/extended_value'
|
5
5
|
require 'aspera/cli/version'
|
6
6
|
require 'aspera/cli/formater'
|
7
|
+
require 'aspera/cli/info'
|
7
8
|
require 'aspera/fasp/installation'
|
8
9
|
require 'aspera/fasp/parameters'
|
9
10
|
require 'aspera/fasp/transfer_spec'
|
@@ -37,7 +38,6 @@ module Aspera
|
|
37
38
|
CONF_PRESET_VERSION = 'version'
|
38
39
|
CONF_PRESET_DEFAULT = 'default'
|
39
40
|
CONF_PRESET_GLOBAL = 'global_common_defaults'
|
40
|
-
CONF_PRESET_SECRETS = 'default_secrets' # pragma: allowlist secret
|
41
41
|
CONF_PLUGIN_SYM = :config # Plugins::Config.name.split('::').last.downcase.to_sym
|
42
42
|
CONF_GLOBAL_SYM = :config
|
43
43
|
# old tool name
|
@@ -62,13 +62,14 @@ module Aspera
|
|
62
62
|
EMAIL_TEST_TEMPLATE = <<~END_OF_TEMPLATE
|
63
63
|
From: <%=from_name%> <<%=from_email%>>
|
64
64
|
To: <<%=to%>>
|
65
|
-
Subject:
|
65
|
+
Subject: #{GEM_NAME} email test
|
66
66
|
|
67
|
-
|
67
|
+
This email was sent to test #{PROGRAM_NAME}.
|
68
68
|
END_OF_TEMPLATE
|
69
69
|
# special extended values
|
70
70
|
EXTV_INCLUDE_PRESETS = :incps
|
71
71
|
EXTV_PRESET = :preset
|
72
|
+
EXTV_VAULT = :vault
|
72
73
|
PRESET_DIG_SEPARATOR = '.'
|
73
74
|
DEFAULT_CHECK_NEW_VERSION_DAYS = 7
|
74
75
|
DEFAULT_PRIV_KEY_FILENAME = 'aspera_aoc_key' # pragma: allowlist secret
|
@@ -77,7 +78,7 @@ module Aspera
|
|
77
78
|
:CONF_PRESET_GLOBAL,:PROGRAM_NAME_V1,:PROGRAM_NAME_V2,:DEFAULT_REDIRECT,:ASPERA_PLUGINS_FOLDERNAME,
|
78
79
|
:RUBY_FILE_EXT,:AOC_COMMAND_V1,:AOC_COMMAND_V2,:AOC_COMMAND_V3,:AOC_COMMAND_CURRENT,:DEMO,
|
79
80
|
:TRANSFER_SDK_ARCHIVE_URL,:AOC_PATH_API_CLIENTS,:DEMO_SERVER_PRESET,:EMAIL_TEST_TEMPLATE,:EXTV_INCLUDE_PRESETS,
|
80
|
-
:EXTV_PRESET,:DEFAULT_CHECK_NEW_VERSION_DAYS,:DEFAULT_PRIV_KEY_FILENAME,:SERVER_COMMAND
|
81
|
+
:EXTV_PRESET,:EXTV_VAULT,:DEFAULT_CHECK_NEW_VERSION_DAYS,:DEFAULT_PRIV_KEY_FILENAME,:SERVER_COMMAND,
|
81
82
|
:PRESET_DIG_SEPARATOR
|
82
83
|
def initialize(env,params)
|
83
84
|
raise 'env and params must be Hash' unless env.is_a?(Hash) && params.is_a?(Hash)
|
@@ -107,6 +108,7 @@ module Aspera
|
|
107
108
|
# add preset handler (needed for smtp)
|
108
109
|
ExtendedValue.instance.set_handler(EXTV_PRESET,:reader,lambda{|v|preset_by_name(v)})
|
109
110
|
ExtendedValue.instance.set_handler(EXTV_INCLUDE_PRESETS,:decoder,lambda{|v|expanded_with_preset_includes(v)})
|
111
|
+
ExtendedValue.instance.set_handler(EXTV_VAULT,:decoder,lambda{|v|vault_value(v)})
|
110
112
|
# load defaults before it can be overriden
|
111
113
|
add_plugin_default_preset(CONF_GLOBAL_SYM)
|
112
114
|
options.parse_options!
|
@@ -122,18 +124,20 @@ module Aspera
|
|
122
124
|
options.add_opt_boolean(:test_mode,'Wizard: skip private key check step')
|
123
125
|
options.add_opt_simple(:preset,'-PVALUE','load the named option preset from current config file')
|
124
126
|
options.add_opt_simple(:pkeypath,'Wizard: path to private key for JWT')
|
125
|
-
options.add_opt_simple(:ascp_path,'
|
126
|
-
options.add_opt_simple(:use_product,'
|
127
|
-
options.add_opt_simple(:smtp,'
|
128
|
-
options.add_opt_simple(:fpac,'
|
129
|
-
options.add_opt_simple(:
|
130
|
-
options.add_opt_simple(:
|
127
|
+
options.add_opt_simple(:ascp_path,'Path to ascp')
|
128
|
+
options.add_opt_simple(:use_product,'Use ascp from specified product')
|
129
|
+
options.add_opt_simple(:smtp,'SMTP configuration (extended value: hash)')
|
130
|
+
options.add_opt_simple(:fpac,'Proxy auto configuration script')
|
131
|
+
options.add_opt_simple(:proxy_credentials,'HTTP proxy credentials (Array with user and password)')
|
132
|
+
options.add_opt_simple(:secret,'Secret for access keys')
|
133
|
+
options.add_opt_simple(:vault,'Vault for secrets')
|
134
|
+
options.add_opt_simple(:vault_password,'Vault password')
|
131
135
|
options.add_opt_simple(:sdk_url,'URL to get SDK')
|
132
136
|
options.add_opt_simple(:sdk_folder,'SDK folder path')
|
133
|
-
options.add_opt_simple(:notif_to,'
|
134
|
-
options.add_opt_simple(:notif_template,'
|
135
|
-
options.add_opt_simple(:version_check_days,Integer,'
|
136
|
-
options.add_opt_simple(:plugin_folder,'
|
137
|
+
options.add_opt_simple(:notif_to,'Email recipient for notification of transfers')
|
138
|
+
options.add_opt_simple(:notif_template,'Email ERB template for notification of transfers')
|
139
|
+
options.add_opt_simple(:version_check_days,Integer,'Period in days to check new version (zero to disable)')
|
140
|
+
options.add_opt_simple(:plugin_folder,'Folder where to find additional plugins')
|
137
141
|
options.set_option(:use_generic_client,true)
|
138
142
|
options.set_option(:test_mode,false)
|
139
143
|
options.set_option(:default,true)
|
@@ -145,6 +149,13 @@ module Aspera
|
|
145
149
|
pac_script = options.get_option(:fpac)
|
146
150
|
# create PAC executor
|
147
151
|
@pac_exec = Aspera::ProxyAutoConfig.new(pac_script).register_uri_generic unless pac_script.nil?
|
152
|
+
proxy_creds=options.get_option(:proxy_credentials)
|
153
|
+
if !proxy_creds.nil?
|
154
|
+
raise CliBadArgument,'proxy credentials shall be an array (#{proxy_creds.class})' unless proxy_creds.is_a?(Array)
|
155
|
+
raise CliBadArgument,'proxy credentials shall have two elements (#{proxy_creds.length})' unless proxy_creds.length.eql?(2)
|
156
|
+
@pac_exec.proxy_user=Rest.proxy_user=proxy_creds[0]
|
157
|
+
@pac_exec.proxy_pass=Rest.proxy_pass=proxy_creds[1]
|
158
|
+
end
|
148
159
|
end
|
149
160
|
|
150
161
|
# env var name to override the app's main folder
|
@@ -251,9 +262,9 @@ module Aspera
|
|
251
262
|
require 'openssl'
|
252
263
|
priv_key = OpenSSL::PKey::RSA.new(length)
|
253
264
|
File.write(private_key_path,priv_key.to_s)
|
254
|
-
File.chmod(0400,private_key_path)
|
255
265
|
File.write(private_key_path + '.pub',priv_key.public_key.to_s)
|
256
|
-
|
266
|
+
Environment.restrict_file_access(private_key_path)
|
267
|
+
Environment.restrict_file_access(private_key_path + '.pub')
|
257
268
|
nil
|
258
269
|
end
|
259
270
|
|
@@ -479,11 +490,14 @@ module Aspera
|
|
479
490
|
Log.log.error('YAML error in config file')
|
480
491
|
raise e
|
481
492
|
rescue StandardError => e
|
482
|
-
Log.log.debug("-> #{e}")
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
493
|
+
Log.log.debug("-> #{e.class.name} : #{e}")
|
494
|
+
if File.exist?(@option_config_file)
|
495
|
+
# then there is a problem with that file.
|
496
|
+
new_name = "#{@option_config_file}.pre#{@info[:version]}.manual_conversion_needed"
|
497
|
+
File.rename(@option_config_file,new_name)
|
498
|
+
Log.log.warn("Renamed config file to #{new_name}.")
|
499
|
+
Log.log.warn('Manual Conversion is required. Next time, a new empty file will be created.')
|
500
|
+
end
|
487
501
|
raise CliError,e.to_s
|
488
502
|
end
|
489
503
|
end
|
@@ -621,7 +635,8 @@ module Aspera
|
|
621
635
|
last_line = line
|
622
636
|
case line
|
623
637
|
when %r{^DBG Path ([^ ]+) (dir|file) +: (.*)$} then data[Regexp.last_match(1)] = Regexp.last_match(3)
|
624
|
-
when %r{^DBG Added module group:"([^"]+)" name:"([^"]+)", version:"([^"]+)" interface:"([^"]+)"$}
|
638
|
+
when %r{^DBG Added module group:"([^"]+)" name:"([^"]+)", version:"([^"]+)" interface:"([^"]+)"$}
|
639
|
+
data[Regexp.last_match(2)] = "#{Regexp.last_match(4)} #{Regexp.last_match(1)} v#{Regexp.last_match(3)}"
|
625
640
|
when %r{^DBG License result \(/license/(\S+)\): (.+)$} then data[Regexp.last_match(1)] = Regexp.last_match(2)
|
626
641
|
when %r{^LOG (.+) version ([0-9.]+)$} then data['product_name'] = Regexp.last_match(1);data['product_version'] = Regexp.last_match(2)
|
627
642
|
when %r{^LOG Initializing FASP version ([^,]+),} then data['ascp_version'] = Regexp.last_match(1)
|
@@ -891,7 +906,7 @@ module Aspera
|
|
891
906
|
when :file
|
892
907
|
return Main.result_status(@option_config_file)
|
893
908
|
when :email_test
|
894
|
-
send_email_template(
|
909
|
+
send_email_template(email_template_default: EMAIL_TEST_TEMPLATE)
|
895
910
|
return Main.result_nothing
|
896
911
|
when :smtp_settings
|
897
912
|
return {type: :single_object, data: email_settings}
|
@@ -924,46 +939,7 @@ module Aspera
|
|
924
939
|
end
|
925
940
|
save_presets_to_config_file
|
926
941
|
return Main.result_status('Done')
|
927
|
-
when :vault
|
928
|
-
command = options.get_next_command(%i[init list get set delete])
|
929
|
-
case command
|
930
|
-
when :init
|
931
|
-
type = options.get_option(:value)
|
932
|
-
case type
|
933
|
-
when 'config',NilClass
|
934
|
-
raise 'default secrets already exists' if @config_presets.has_key?(CONF_PRESET_SECRETS)
|
935
|
-
@config_presets[CONF_PRESET_SECRETS] = {}
|
936
|
-
set_global_default(:secrets,"@preset:#{CONF_PRESET_SECRETS}")
|
937
|
-
else raise 'no such vault type'
|
938
|
-
end
|
939
|
-
return Main.result_status('Done')
|
940
|
-
when :list
|
941
|
-
return {type: :object_list, data: vault.list}
|
942
|
-
when :set
|
943
|
-
# register url option
|
944
|
-
BasicAuthPlugin.register_options(@agents)
|
945
|
-
username = options.get_option(:username,is_type: :mandatory)
|
946
|
-
url = options.get_option(:url,is_type: :mandatory)
|
947
|
-
description = options.get_option(:value)
|
948
|
-
secret = options.get_next_argument('secret')
|
949
|
-
vault.set(username: username, url: url, description: description, secret: secret)
|
950
|
-
save_presets_to_config_file if vault.is_a?(Keychain::EncryptedHash)
|
951
|
-
return Main.result_status('Done')
|
952
|
-
when :get
|
953
|
-
# register url option
|
954
|
-
BasicAuthPlugin.register_options(@agents)
|
955
|
-
username = options.get_option(:username,is_type: :mandatory)
|
956
|
-
url = options.get_option(:url)
|
957
|
-
result = vault.get(username: username, url: url)
|
958
|
-
return {type: :single_object, data: result}
|
959
|
-
when :delete
|
960
|
-
# register url option
|
961
|
-
BasicAuthPlugin.register_options(@agents)
|
962
|
-
username = options.get_option(:username,is_type: :mandatory)
|
963
|
-
url = options.get_option(:url)
|
964
|
-
vault.delete(username: username, url: url)
|
965
|
-
return Main.result_status('Done')
|
966
|
-
end
|
942
|
+
when :vault then execute_vault
|
967
943
|
else raise 'INTERNAL ERROR: wrong case'
|
968
944
|
end
|
969
945
|
end
|
@@ -992,21 +968,21 @@ module Aspera
|
|
992
968
|
Kernel.binding
|
993
969
|
end
|
994
970
|
|
995
|
-
def send_email_template(
|
996
|
-
|
971
|
+
def send_email_template(email_template_default: nil, values: {})
|
972
|
+
values[:to] ||= options.get_option(:notif_to,is_type: :mandatory)
|
997
973
|
notif_template = options.get_option(:notif_template,is_type: email_template_default.nil? ? :mandatory : :optional) || email_template_default
|
998
974
|
mail_conf = email_settings
|
999
|
-
|
1000
|
-
|
975
|
+
values[:from_name] ||= mail_conf[:from_name]
|
976
|
+
values[:from_email] ||= mail_conf[:from_email]
|
1001
977
|
%i[from_name from_email].each do |n|
|
1002
|
-
raise "Missing email parameter: #{n}" unless
|
978
|
+
raise "Missing email parameter: #{n}" unless values.has_key?(n)
|
1003
979
|
end
|
1004
980
|
start_options = [mail_conf[:domain]]
|
1005
981
|
start_options.push(mail_conf[:username],mail_conf[:password],:login) if mail_conf.has_key?(:username) && mail_conf.has_key?(:password)
|
1006
|
-
# create a binding with only variables defined in
|
982
|
+
# create a binding with only variables defined in values
|
1007
983
|
template_binding = empty_binding
|
1008
984
|
# add variables to binding
|
1009
|
-
|
985
|
+
values.each do |k,v|
|
1010
986
|
raise "key (#{k.class}) must be Symbol" unless k.is_a?(Symbol)
|
1011
987
|
template_binding.local_variable_set(k,v)
|
1012
988
|
end
|
@@ -1016,17 +992,17 @@ module Aspera
|
|
1016
992
|
smtp = Net::SMTP.new(mail_conf[:server], mail_conf[:port])
|
1017
993
|
smtp.enable_starttls if mail_conf[:tls]
|
1018
994
|
smtp.start(*start_options) do |smtp_session|
|
1019
|
-
smtp_session.send_message(msg_with_headers,
|
995
|
+
smtp_session.send_message(msg_with_headers, values[:from_email], values[:to])
|
1020
996
|
end
|
1021
997
|
end
|
1022
998
|
|
1023
999
|
def save_presets_to_config_file
|
1024
1000
|
raise 'no configuration loaded' if @config_presets.nil?
|
1025
1001
|
FileUtils.mkdir_p(@main_folder) unless Dir.exist?(@main_folder)
|
1026
|
-
File.chmod(0700,@main_folder)
|
1027
1002
|
Log.log.debug("Writing #{@option_config_file}")
|
1028
1003
|
File.write(@option_config_file,@config_presets.to_yaml)
|
1029
|
-
|
1004
|
+
Environment.restrict_file_access(@main_folder)
|
1005
|
+
Environment.restrict_file_access(@option_config_file)
|
1030
1006
|
end
|
1031
1007
|
|
1032
1008
|
# returns [String] name if config_presets has default
|
@@ -1051,25 +1027,65 @@ module Aspera
|
|
1051
1027
|
return nil
|
1052
1028
|
end # get_plugin_default_config_name
|
1053
1029
|
|
1030
|
+
ALLOWED_KEYS=%i[password username description].freeze
|
1031
|
+
def execute_vault
|
1032
|
+
command = options.get_next_command(%i[list show create delete password])
|
1033
|
+
case command
|
1034
|
+
when :list
|
1035
|
+
return {type: :object_list, data: vault.list}
|
1036
|
+
when :show
|
1037
|
+
return {type: :single_object, data: vault.get(label: options.get_next_argument('label'))}
|
1038
|
+
when :create
|
1039
|
+
label=options.get_next_argument('label')
|
1040
|
+
info=options.get_next_argument('info Hash')
|
1041
|
+
raise 'info must be Hash' unless info.is_a?(Hash)
|
1042
|
+
info=info.symbolize_keys
|
1043
|
+
info[:label]=label
|
1044
|
+
vault.set(info)
|
1045
|
+
return Main.result_status('Password added')
|
1046
|
+
when :delete
|
1047
|
+
vault.delete(label: options.get_next_argument('label'))
|
1048
|
+
return Main.result_status('Password deleted')
|
1049
|
+
when :password
|
1050
|
+
raise 'Vault does not support password change' unless vault.respond_to?(:password=)
|
1051
|
+
new_password=options.get_next_argument('new_password')
|
1052
|
+
vault.password=new_password
|
1053
|
+
vault.save
|
1054
|
+
return Main.result_status('Password updated')
|
1055
|
+
end
|
1056
|
+
end
|
1057
|
+
|
1058
|
+
def vault_value(name)
|
1059
|
+
m=name.match(/^(.+)\.(.+)$/)
|
1060
|
+
raise 'vault name shall match <name>.<param>' if m.nil?
|
1061
|
+
info=vault.get(label: m[1])
|
1062
|
+
#raise "no such vault entry: #{m[1]}" if info.nil?
|
1063
|
+
value=info[m[2].to_sym]
|
1064
|
+
raise "no such entry value: #{m[2]}" if value.nil?
|
1065
|
+
return value
|
1066
|
+
end
|
1067
|
+
|
1054
1068
|
def vault
|
1055
1069
|
if @vault.nil?
|
1056
|
-
vault_info = options.get_option(:
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1070
|
+
vault_info = options.get_option(:vault) || {'type'=>'file','name'=>'vault.bin'}
|
1071
|
+
vault_password = options.get_option(:vault_password,is_type: :mandatory)
|
1072
|
+
raise 'vault must be Hash' unless vault_info.is_a?(Hash)
|
1073
|
+
vault_type = vault_info['type'] || 'file'
|
1074
|
+
vault_name = vault_info['name'] || (vault_type.eql?('file') ? 'vault.bin' : PROGRAM_NAME)
|
1075
|
+
case vault_type
|
1076
|
+
when 'file'
|
1077
|
+
vault_path=vault_name
|
1078
|
+
@vault = Keychain::EncryptedHash.new(vault_path,vault_password)
|
1079
|
+
when 'system'
|
1062
1080
|
case Environment.os
|
1063
1081
|
when Environment::OS_X
|
1064
|
-
@vault = Keychain::
|
1082
|
+
@vault = Keychain::MacosSystem.new(vault_name,vault_password)
|
1065
1083
|
when Environment::OS_WINDOWS,Environment::OS_LINUX,Environment::OS_AIX
|
1066
1084
|
raise 'not implemented'
|
1067
|
-
else raise 'Error'
|
1085
|
+
else raise 'Error, OS not supported'
|
1068
1086
|
end
|
1069
|
-
when NilClass
|
1070
|
-
# keep nil
|
1071
1087
|
else
|
1072
|
-
raise CliBadArgument,
|
1088
|
+
raise CliBadArgument,"Unknown vault type: #{vault_type}"
|
1073
1089
|
end
|
1074
1090
|
end
|
1075
1091
|
raise 'No vault defined' if @vault.nil?
|
@@ -56,7 +56,7 @@ module Aspera
|
|
56
56
|
# extract elements from anonymous faspex link
|
57
57
|
def get_link_data(publink)
|
58
58
|
publink_uri = URI.parse(publink)
|
59
|
-
raise CliBadArgument, '
|
59
|
+
raise CliBadArgument, 'Public link does not match Faspex format' unless (m = publink_uri.path.match(/^(.*)\/(external.*)$/))
|
60
60
|
base = m[1]
|
61
61
|
subpath = m[2]
|
62
62
|
port_add = publink_uri.port.eql?(publink_uri.default_port) ? '' : ":#{publink_uri.port}"
|
@@ -236,7 +236,7 @@ module Aspera
|
|
236
236
|
begin
|
237
237
|
pkgdatares = JSON.parse("[#{pkgdatares}]")
|
238
238
|
rescue JSON::ParserError # => e
|
239
|
-
raise '
|
239
|
+
raise 'Unexpected response: missing metadata ?'
|
240
240
|
end
|
241
241
|
return pkgdatares.first
|
242
242
|
end
|
@@ -357,7 +357,7 @@ module Aspera
|
|
357
357
|
headers: {'Accept' => 'application/xml'})
|
358
358
|
if !pkgdatares[:http].body.start_with?('<?xml ')
|
359
359
|
OpenApplication.instance.uri(link_url)
|
360
|
-
raise CliError, '
|
360
|
+
raise CliError, 'Unexpected response: package not found ?'
|
361
361
|
end
|
362
362
|
package_entry = XmlSimple.xml_in(pkgdatares[:http].body, {'ForceArray' => false})
|
363
363
|
Log.dump(:package_entry,package_entry)
|
@@ -82,12 +82,14 @@ module Aspera
|
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
85
|
-
ACTIONS = %i[health package admin
|
85
|
+
ACTIONS = %i[health version user bearer_token package admin].freeze
|
86
86
|
|
87
87
|
def execute_action
|
88
88
|
set_api
|
89
89
|
command = options.get_next_command(ACTIONS)
|
90
90
|
case command
|
91
|
+
when :version
|
92
|
+
return { type: :single_object, data: @api_v5.read('version')[:data] }
|
91
93
|
when :health
|
92
94
|
nagios = Nagios.new
|
93
95
|
begin
|
@@ -110,6 +112,8 @@ module Aspera
|
|
110
112
|
return Main.result_status('modified')
|
111
113
|
end
|
112
114
|
end
|
115
|
+
when :bearer_token
|
116
|
+
return {type: :text,data: @api_v5.oauth_token}
|
113
117
|
when :package
|
114
118
|
command = options.get_next_command(%i[list show send receive])
|
115
119
|
case command
|
@@ -427,6 +427,7 @@ module Aspera
|
|
427
427
|
raise 'ERR'
|
428
428
|
end # execute_node_gen4_command
|
429
429
|
|
430
|
+
# This is older API
|
430
431
|
def execute_async
|
431
432
|
command = options.get_next_command(%i[list delete files show counters bandwidth])
|
432
433
|
unless command.eql?(:list)
|
@@ -504,13 +505,27 @@ module Aspera
|
|
504
505
|
end
|
505
506
|
end
|
506
507
|
|
507
|
-
ACTIONS = %i[postprocess stream transfer cleanup forward access_key watch_folder service async central asperabrowser
|
508
|
+
ACTIONS = %i[postprocess stream transfer cleanup forward access_key watch_folder service async sync central asperabrowser
|
509
|
+
basic_token].concat(COMMON_ACTIONS).freeze
|
508
510
|
|
509
511
|
def execute_action(command=nil,prefix_path=nil)
|
510
512
|
command ||= options.get_next_command(ACTIONS)
|
511
513
|
case command
|
512
514
|
when *COMMON_ACTIONS then return execute_simple_common(command,prefix_path)
|
513
515
|
when :async then return execute_async
|
516
|
+
when :sync
|
517
|
+
sync_command = options.get_next_command([Plugin::ALL_OPS,%i[bandwidth counters files start state stop summary]].flatten-%i[modify])
|
518
|
+
case sync_command
|
519
|
+
when *Plugin::ALL_OPS then return entity_command(sync_command,@api_node,'asyncs',item_list_key: 'ids')
|
520
|
+
else
|
521
|
+
parameters = options.get_option(:value)
|
522
|
+
asyncs_id=instance_identifier
|
523
|
+
if %i[start stop].include?(sync_command)
|
524
|
+
@api_node.create("asyncs/#{asyncs_id}/#{sync_command}",parameters)
|
525
|
+
return Main.result_status('ok')
|
526
|
+
end
|
527
|
+
return { type: :single_object, data: @api_node.read("asyncs/#{asyncs_id}/#{sync_command}",parameters)[:data] }
|
528
|
+
end
|
514
529
|
when :stream
|
515
530
|
command = options.get_next_command(%i[list create show modify cancel])
|
516
531
|
case command
|
@@ -545,7 +560,9 @@ module Aspera
|
|
545
560
|
case command
|
546
561
|
when :list
|
547
562
|
# could use ? subpath: 'transfers'
|
548
|
-
|
563
|
+
query=options.get_option(:value) || options.get_option(:query)
|
564
|
+
raise 'Query must be a Hash' unless query.nil? || query.is_a?(Hash)
|
565
|
+
resp = @api_node.read(res_class_path,query)
|
549
566
|
return {
|
550
567
|
type: :object_list,
|
551
568
|
data: resp[:data],
|
@@ -635,8 +652,11 @@ module Aspera
|
|
635
652
|
when :list
|
636
653
|
request_data.deep_merge!({'validation' => validation}) unless validation.nil?
|
637
654
|
resp = @api_node.create('services/rest/transfers/v1/sessions',request_data)
|
638
|
-
return {
|
639
|
-
|
655
|
+
return {
|
656
|
+
type: :object_list,
|
657
|
+
data: resp[:data]['session_info_result']['session_info'],
|
658
|
+
fields: %w[session_uuid status transport direction bytes_transferred]
|
659
|
+
}
|
640
660
|
end
|
641
661
|
when :file
|
642
662
|
command = options.get_next_command(%i[list modify])
|
@@ -3,6 +3,7 @@
|
|
3
3
|
require 'aspera/fasp/transfer_spec'
|
4
4
|
require 'aspera/cli/listener/logger'
|
5
5
|
require 'aspera/cli/listener/progress_multi'
|
6
|
+
require 'aspera/cli/info'
|
6
7
|
|
7
8
|
module Aspera
|
8
9
|
module Cli
|
@@ -230,11 +231,11 @@ module Aspera
|
|
230
231
|
global_status = self.class.session_status(statuses)
|
231
232
|
email_vars = {
|
232
233
|
global_transfer_status: global_status,
|
233
|
-
subject: "
|
234
|
+
subject: "#{PROGRAM_NAME} transfer: #{global_status}",
|
234
235
|
body: "Transfer is: #{global_status}",
|
235
236
|
ts: transfer_spec
|
236
237
|
}
|
237
|
-
@config.send_email_template(email_vars
|
238
|
+
@config.send_email_template(email_template_default: DEFAULT_TRANSFER_NOTIF_TMPL, values: email_vars)
|
238
239
|
end
|
239
240
|
|
240
241
|
# shut down if agent requires it
|