aspera-cli 4.6.0 → 4.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +427 -300
  3. data/bin/ascli +2 -1
  4. data/bin/asession +1 -0
  5. data/docs/test_env.conf +2 -0
  6. data/examples/aoc.rb +4 -3
  7. data/examples/faspex4.rb +21 -19
  8. data/examples/proxy.pac +1 -1
  9. data/examples/transfer.rb +15 -15
  10. data/lib/aspera/aoc.rb +135 -124
  11. data/lib/aspera/ascmd.rb +85 -75
  12. data/lib/aspera/ats_api.rb +11 -10
  13. data/lib/aspera/cli/basic_auth_plugin.rb +13 -14
  14. data/lib/aspera/cli/extended_value.rb +42 -33
  15. data/lib/aspera/cli/formater.rb +138 -111
  16. data/lib/aspera/cli/info.rb +17 -0
  17. data/lib/aspera/cli/listener/line_dump.rb +3 -2
  18. data/lib/aspera/cli/listener/logger.rb +2 -1
  19. data/lib/aspera/cli/listener/progress.rb +16 -18
  20. data/lib/aspera/cli/listener/progress_multi.rb +13 -16
  21. data/lib/aspera/cli/main.rb +122 -130
  22. data/lib/aspera/cli/manager.rb +146 -154
  23. data/lib/aspera/cli/plugin.rb +38 -34
  24. data/lib/aspera/cli/plugins/alee.rb +6 -6
  25. data/lib/aspera/cli/plugins/aoc.rb +273 -276
  26. data/lib/aspera/cli/plugins/ats.rb +82 -76
  27. data/lib/aspera/cli/plugins/bss.rb +14 -16
  28. data/lib/aspera/cli/plugins/config.rb +350 -306
  29. data/lib/aspera/cli/plugins/console.rb +23 -19
  30. data/lib/aspera/cli/plugins/cos.rb +18 -18
  31. data/lib/aspera/cli/plugins/faspex.rb +180 -159
  32. data/lib/aspera/cli/plugins/faspex5.rb +64 -54
  33. data/lib/aspera/cli/plugins/node.rb +147 -140
  34. data/lib/aspera/cli/plugins/orchestrator.rb +68 -66
  35. data/lib/aspera/cli/plugins/preview.rb +92 -96
  36. data/lib/aspera/cli/plugins/server.rb +79 -75
  37. data/lib/aspera/cli/plugins/shares.rb +23 -24
  38. data/lib/aspera/cli/plugins/sync.rb +20 -22
  39. data/lib/aspera/cli/transfer_agent.rb +40 -39
  40. data/lib/aspera/cli/version.rb +2 -1
  41. data/lib/aspera/colors.rb +35 -27
  42. data/lib/aspera/command_line_builder.rb +48 -34
  43. data/lib/aspera/cos_node.rb +29 -21
  44. data/lib/aspera/data_repository.rb +3 -2
  45. data/lib/aspera/environment.rb +50 -45
  46. data/lib/aspera/fasp/agent_base.rb +22 -20
  47. data/lib/aspera/fasp/agent_connect.rb +13 -11
  48. data/lib/aspera/fasp/agent_direct.rb +48 -59
  49. data/lib/aspera/fasp/agent_httpgw.rb +33 -39
  50. data/lib/aspera/fasp/agent_node.rb +15 -13
  51. data/lib/aspera/fasp/agent_trsdk.rb +12 -14
  52. data/lib/aspera/fasp/error.rb +2 -1
  53. data/lib/aspera/fasp/error_info.rb +68 -52
  54. data/lib/aspera/fasp/installation.rb +106 -94
  55. data/lib/aspera/fasp/listener.rb +1 -0
  56. data/lib/aspera/fasp/parameters.rb +83 -92
  57. data/lib/aspera/fasp/parameters.yaml +305 -249
  58. data/lib/aspera/fasp/resume_policy.rb +11 -14
  59. data/lib/aspera/fasp/transfer_spec.rb +26 -0
  60. data/lib/aspera/fasp/uri.rb +22 -21
  61. data/lib/aspera/faspex_gw.rb +55 -90
  62. data/lib/aspera/hash_ext.rb +4 -3
  63. data/lib/aspera/id_generator.rb +8 -7
  64. data/lib/aspera/keychain/encrypted_hash.rb +17 -16
  65. data/lib/aspera/keychain/macos_security.rb +6 -10
  66. data/lib/aspera/log.rb +25 -20
  67. data/lib/aspera/nagios.rb +13 -12
  68. data/lib/aspera/node.rb +30 -22
  69. data/lib/aspera/oauth.rb +175 -226
  70. data/lib/aspera/open_application.rb +4 -3
  71. data/lib/aspera/persistency_action_once.rb +6 -6
  72. data/lib/aspera/persistency_folder.rb +5 -9
  73. data/lib/aspera/preview/file_types.rb +6 -5
  74. data/lib/aspera/preview/generator.rb +25 -24
  75. data/lib/aspera/preview/options.rb +16 -14
  76. data/lib/aspera/preview/utils.rb +98 -98
  77. data/lib/aspera/{proxy_auto_config.erb.js → proxy_auto_config.js} +23 -31
  78. data/lib/aspera/proxy_auto_config.rb +111 -20
  79. data/lib/aspera/rest.rb +115 -113
  80. data/lib/aspera/rest_call_error.rb +2 -2
  81. data/lib/aspera/rest_error_analyzer.rb +23 -25
  82. data/lib/aspera/rest_errors_aspera.rb +15 -14
  83. data/lib/aspera/ssh.rb +12 -10
  84. data/lib/aspera/sync.rb +42 -41
  85. data/lib/aspera/temp_file_manager.rb +18 -14
  86. data/lib/aspera/timer_limiter.rb +2 -1
  87. data/lib/aspera/uri_reader.rb +7 -5
  88. data/lib/aspera/web_auth.rb +79 -76
  89. metadata +64 -21
  90. data/docs/Makefile +0 -65
  91. data/docs/README.erb.md +0 -4424
  92. data/docs/README.md +0 -13
  93. data/docs/diagrams.txt +0 -49
  94. data/docs/doc_tools.rb +0 -58
  95. data/lib/aspera/cli/plugins/shares2.rb +0 -114
  96. data/lib/aspera/fasp/default.rb +0 -17
data/lib/aspera/log.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'aspera/colors'
2
3
  require 'logger'
3
4
  require 'pp'
@@ -7,6 +8,9 @@ require 'singleton'
7
8
  module Aspera
8
9
  # Singleton object for logging
9
10
  class Log
11
+ # display string for hidden secrets
12
+ HIDDEN_PASSWORD='🔑'
13
+ private_constant :HIDDEN_PASSWORD
10
14
  include Singleton
11
15
  # class methods
12
16
  class << self
@@ -23,24 +27,24 @@ module Aspera
23
27
  # @param name string or symbol
24
28
  # @param format either pp or json format
25
29
  def dump(name,object,format=:json)
26
- self.log.debug() do
27
- result=case format
30
+ log.debug() do
31
+ result=
32
+ case format
28
33
  when :json
29
34
  JSON.pretty_generate(object) rescue PP.pp(object,'')
30
35
  when :ruby
31
36
  PP.pp(object,'')
32
37
  else
33
- raise "wrong parameter, expect pp or json"
38
+ raise 'wrong parameter, expect pp or json'
34
39
  end
35
40
  "#{name.to_s.green} (#{format})=\n#{result}"
36
41
  end
37
42
  end
38
- end
43
+ end # class
39
44
 
40
- attr_reader :logger_type
41
- attr_reader :logger
45
+ attr_reader :logger_type, :logger
42
46
  attr_writer :program_name
43
- attr_accessor :log_passwords
47
+ attr_accessor :log_secrets
44
48
 
45
49
  # set log level of underlying logger given symbol level
46
50
  def level=(new_level)
@@ -53,19 +57,19 @@ module Aspera
53
57
  return name.downcase.to_sym if @logger.level.eql?(Logger::Severity.const_get(name))
54
58
  end
55
59
  # should not happen
56
- raise "error"
60
+ raise "INTERNAL ERROR: unexpected level #{@logger.level}"
57
61
  end
58
62
 
59
63
  # change underlying logger, but keep log level
60
64
  def logger_type=(new_logtype)
61
65
  current_severity_integer=@logger.level unless @logger.nil?
62
- current_severity_integer=ENV['AS_LOG_LEVEL'] if current_severity_integer.nil? and ENV.has_key?('AS_LOG_LEVEL')
66
+ current_severity_integer=ENV['AS_LOG_LEVEL'] if current_severity_integer.nil? && ENV.has_key?('AS_LOG_LEVEL')
63
67
  current_severity_integer=Logger::Severity::WARN if current_severity_integer.nil?
64
68
  case new_logtype
65
69
  when :stderr
66
- @logger = Logger.new(STDERR)
70
+ @logger = Logger.new($stderr)
67
71
  when :stdout
68
- @logger = Logger.new(STDOUT)
72
+ @logger = Logger.new($stdout)
69
73
  when :syslog
70
74
  require 'syslog/logger'
71
75
  @logger = Syslog::Logger.new(@program_name)
@@ -75,12 +79,14 @@ module Aspera
75
79
  @logger.level=current_severity_integer
76
80
  @logger_type=new_logtype
77
81
  original_formatter = @logger.formatter || Logger::Formatter.new
78
- # update formatter with password hiding
79
- @logger.formatter=proc do |severity, datetime, progname, msg|
80
- unless @log_passwords
81
- msg=msg.gsub(/(["':][^"]*(password|secret|private_key)[^"]*["']?[=>: ]+")([^"]+)(")/){"#{$1}***#{$4}"}
82
- msg=msg.gsub(/("[^"]*(secret)[^"]*"=>{)([^}]+)(})/){"#{$1}***#{$4}"}
83
- msg=msg.gsub(/((secrets)={)([^}]+)(})/){"#{$1}***#{$4}"}
82
+ # update formatter with password hiding, note that @log_secrets may be set AFTER this init is done, so it's done at runtime
83
+ @logger.formatter=lambda do |severity, datetime, progname, msg|
84
+ if msg.is_a?(String) && !@log_secrets
85
+ msg=msg
86
+ .gsub(/(["':][^"]*(password|secret|private_key)[^"]*["']?[=>: ]+")([^"]+)(")/){"#{Regexp.last_match(1)}#{HIDDEN_PASSWORD}#{Regexp.last_match(4)}"}
87
+ .gsub(/("[^"]*(secret)[^"]*"=>{)([^}]+)(})/){"#{Regexp.last_match(1)}#{HIDDEN_PASSWORD}#{Regexp.last_match(4)}"}
88
+ .gsub(/((secrets)={)([^}]+)(})/){"#{Regexp.last_match(1)}#{HIDDEN_PASSWORD}#{Regexp.last_match(4)}"}
89
+ .gsub(/--+BEGIN[A-Z ]+KEY--+.+--+END[A-Z ]+KEY--+/m){HIDDEN_PASSWORD}
84
90
  end
85
91
  original_formatter.call(severity, datetime, progname, msg)
86
92
  end
@@ -91,11 +97,10 @@ module Aspera
91
97
  def initialize
92
98
  @logger=nil
93
99
  @program_name='aspera'
94
- @log_passwords=false
100
+ @log_secrets=false
95
101
  # this sets @logger and @logger_type (self needed to call method instead of local var)
96
102
  self.logger_type=:stderr
97
- raise "error logger shall be defined" if @logger.nil?
103
+ raise 'error logger shall be defined' if @logger.nil?
98
104
  end
99
-
100
105
  end
101
106
  end
data/lib/aspera/nagios.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'date'
2
3
 
3
4
  module Aspera
@@ -5,24 +6,24 @@ module Aspera
5
6
  # nagios levels
6
7
  LEVELS=[:ok,:warning,:critical,:unknown,:dependent]
7
8
  ADD_PREFIX='add_'
8
- # add methods to add nagios error levels, each take component name and message
9
- LEVELS.each_index do |code|
10
- name="#{ADD_PREFIX}#{LEVELS[code]}".to_sym
11
- define_method(name){|comp,msg|@data.push({:code=>code,:comp=>comp,:msg=>msg})}
12
- public name
13
- end
14
9
  # date offset levels
15
10
  DATE_WARN_OFFSET=2
16
11
  DATE_CRIT_OFFSET=5
17
12
  private_constant :LEVELS,:ADD_PREFIX,:DATE_WARN_OFFSET,:DATE_CRIT_OFFSET
18
13
 
14
+ # add methods to add nagios error levels, each take component name and message
15
+ LEVELS.each_index do |code|
16
+ name="#{ADD_PREFIX}#{LEVELS[code]}".to_sym
17
+ define_method(name){|comp,msg|@data.push({code: code,comp: comp,msg: msg})}
18
+ end
19
+
19
20
  attr_reader :data
20
21
  def initialize
21
22
  @data=[]
22
23
  end
23
24
 
24
25
  # comparte remote time with local time
25
- def check_time_offset( remote_date, component )
26
+ def check_time_offset(remote_date, component)
26
27
  # check date if specified : 2015-10-13T07:32:01Z
27
28
  rtime = DateTime.strptime(remote_date)
28
29
  diff_time = (rtime - DateTime.now).abs
@@ -38,22 +39,22 @@ module Aspera
38
39
  end
39
40
  end
40
41
 
41
- def check_product_version( component, product, version )
42
+ def check_product_version(component, _product, version)
42
43
  add_ok(component,"version #{version}")
43
44
  # TODO check on database if latest version
44
45
  end
45
46
 
46
47
  # translate for display
47
48
  def result
48
- raise "missing result" if @data.empty?
49
- {:type=>:object_list,:data=>@data.map{|i|{'status'=>LEVELS[i[:code]].to_s,'component'=>i[:comp],'message'=>i[:msg]}}}
49
+ raise 'missing result' if @data.empty?
50
+ {type: :object_list,data: @data.map{|i|{'status'=>LEVELS[i[:code]].to_s,'component'=>i[:comp],'message'=>i[:msg]}}}
50
51
  end
51
52
 
52
53
  # process results of a analysis and display status and exit with code
53
54
  def self.process(data)
54
- raise "INTERNAL ERROR, result must be list and not empty" unless data.is_a?(Array) and !data.empty?
55
+ raise 'INTERNAL ERROR, result must be list and not empty' unless data.is_a?(Array) && !data.empty?
55
56
  ['status','component','message'].each{|c|raise "INTERNAL ERROR, result must have #{c}" unless data.first.has_key?(c)}
56
- res_errors = data.select{|s|!s['status'].eql?('ok')}
57
+ res_errors = data.reject{|s|s['status'].eql?('ok')}
57
58
  # keep only errors in case of problem, other ok are assumed so
58
59
  data = res_errors unless res_errors.empty?
59
60
  # first is most critical
data/lib/aspera/node.rb CHANGED
@@ -1,4 +1,5 @@
1
- require 'aspera/fasp/default'
1
+ # frozen_string_literal: true
2
+ require 'aspera/fasp/transfer_spec'
2
3
  require 'aspera/rest'
3
4
  require 'aspera/oauth'
4
5
  require 'aspera/log'
@@ -9,33 +10,40 @@ module Aspera
9
10
  # Provides additional functions using node API.
10
11
  class Node < Rest
11
12
  # permissions
12
- ACCESS_LEVELS=['delete','list','mkdir','preview','read','rename','write']
13
+ ACCESS_LEVELS=%w[delete list mkdir preview read rename write].freeze
14
+ # prefix for ruby code for filter
13
15
  MATCH_EXEC_PREFIX='exec:'
14
16
 
15
17
  # register node special token decoder
16
18
  Oauth.register_decoder(lambda{|token|JSON.parse(Zlib::Inflate.inflate(Base64.decode64(token)).partition('==SIGNATURE==').first)})
17
19
 
18
- def self.set_ak_basic_token(ts,ak,secret)
19
- raise "ERROR: expected xfer" unless ts['remote_user'].eql?(Fasp::Default::ACCESS_KEY_TRANSFER_USER)
20
- ts['token']="Basic #{Base64.strict_encode64("#{ak}:#{secret}")}"
21
- end
20
+ class<<self
21
+ def set_ak_basic_token(ts,ak,secret)
22
+ Log.log.warn("Expected transfer user: #{Fasp::TransferSpec::ACCESS_KEY_TRANSFER_USER}, but have #{ts['remote_user']}") unless ts['remote_user'].eql?(Fasp::TransferSpec::ACCESS_KEY_TRANSFER_USER)
23
+ ts['token']="Basic #{Base64.strict_encode64("#{ak}:#{secret}")}"
24
+ end
22
25
 
23
- # for access keys: provide expression to match entry in folder
24
- # if no prefix: regex
25
- # if prefix: ruby code
26
- # if filder is nil, then always match
27
- def self.file_matcher(match_expression)
28
- match_expression||="#{MATCH_EXEC_PREFIX}true"
29
- if match_expression.start_with?(MATCH_EXEC_PREFIX)
30
- return eval("lambda{|f|#{match_expression[MATCH_EXEC_PREFIX.length..-1]}}")
26
+ def empty_binding
27
+ return Kernel.binding
31
28
  end
32
- return lambda{|f|f['name'].match(/#{match_expression}/)}
33
- end
34
29
 
35
- def initialize(rest_params)
36
- super(rest_params)
30
+ # for access keys: provide expression to match entry in folder
31
+ # if no prefix: regex
32
+ # if prefix: ruby code
33
+ # if filder is nil, then always match
34
+ def file_matcher(match_expression)
35
+ match_expression||="#{MATCH_EXEC_PREFIX}true"
36
+ if match_expression.start_with?(MATCH_EXEC_PREFIX)
37
+ return eval("lambda{|f|#{match_expression[MATCH_EXEC_PREFIX.length..-1]}}", empty_binding, __FILE__, __LINE__)
38
+ end
39
+ return lambda{|f|f['name'].match(/#{match_expression}/)}
40
+ end
37
41
  end
38
42
 
43
+ # def initialize(rest_params)
44
+ # super(rest_params)
45
+ # end
46
+
39
47
  # recursively crawl in a folder.
40
48
  # subfolders a processed if the processing method returns true
41
49
  # @param processor must provide a method to process each entry
@@ -54,13 +62,13 @@ module Aspera
54
62
  #top_info=read("files/#{opt[:top_file_id]}")[:data]
55
63
  folders_to_explore=[{id: opt[:top_file_id], relpath: opt[:top_file_path]}]
56
64
  Log.dump(:folders_to_explore,folders_to_explore)
57
- while !folders_to_explore.empty? do
65
+ while !folders_to_explore.empty?
58
66
  current_item = folders_to_explore.shift
59
67
  Log.log.debug("searching #{current_item[:relpath]}".bg_green)
60
68
  # get folder content
61
69
  folder_contents = begin
62
70
  read("files/#{current_item[:id]}/files")[:data]
63
- rescue => e
71
+ rescue StandardError => e
64
72
  Log.log.warn("#{current_item[:relpath]}: #{e.class} #{e.message}")
65
73
  []
66
74
  end
@@ -69,8 +77,8 @@ module Aspera
69
77
  relative_path=File.join(current_item[:relpath],entry['name'])
70
78
  Log.log.debug("looking #{relative_path}".bg_green)
71
79
  # entry type is file, folder or link
72
- if processor.send(opt[:method],entry,relative_path) and entry['type'].eql?('folder')
73
- folders_to_explore.push({:id=>entry['id'],:relpath=>relative_path})
80
+ if processor.send(opt[:method],entry,relative_path) && entry['type'].eql?('folder')
81
+ folders_to_explore.push({id: entry['id'],relpath: relative_path})
74
82
  end
75
83
  end
76
84
  end