aspera-cli 4.9.0 → 4.10.0
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
- 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
|