aspera-cli 4.10.0 → 4.11.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.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/BUGS.md +20 -0
  4. data/CHANGELOG.md +509 -0
  5. data/CONTRIBUTING.md +118 -0
  6. data/README.md +621 -378
  7. data/bin/ascli +4 -4
  8. data/bin/asession +11 -11
  9. data/docs/test_env.conf +28 -19
  10. data/examples/aoc.rb +4 -4
  11. data/examples/dascli +11 -9
  12. data/examples/faspex4.rb +8 -8
  13. data/examples/node.rb +11 -11
  14. data/examples/server.rb +9 -9
  15. data/lib/aspera/aoc.rb +273 -266
  16. data/lib/aspera/ascmd.rb +56 -54
  17. data/lib/aspera/ats_api.rb +4 -4
  18. data/lib/aspera/cli/basic_auth_plugin.rb +15 -12
  19. data/lib/aspera/cli/extended_value.rb +5 -5
  20. data/lib/aspera/cli/formater.rb +64 -64
  21. data/lib/aspera/cli/listener/line_dump.rb +1 -1
  22. data/lib/aspera/cli/listener/logger.rb +1 -1
  23. data/lib/aspera/cli/listener/progress.rb +5 -6
  24. data/lib/aspera/cli/listener/progress_multi.rb +14 -19
  25. data/lib/aspera/cli/main.rb +66 -67
  26. data/lib/aspera/cli/manager.rb +110 -110
  27. data/lib/aspera/cli/plugin.rb +54 -37
  28. data/lib/aspera/cli/plugins/alee.rb +4 -4
  29. data/lib/aspera/cli/plugins/aoc.rb +308 -669
  30. data/lib/aspera/cli/plugins/ats.rb +44 -46
  31. data/lib/aspera/cli/plugins/bss.rb +10 -10
  32. data/lib/aspera/cli/plugins/config.rb +447 -344
  33. data/lib/aspera/cli/plugins/console.rb +12 -12
  34. data/lib/aspera/cli/plugins/cos.rb +18 -20
  35. data/lib/aspera/cli/plugins/faspex.rb +110 -112
  36. data/lib/aspera/cli/plugins/faspex5.rb +67 -46
  37. data/lib/aspera/cli/plugins/node.rb +364 -288
  38. data/lib/aspera/cli/plugins/orchestrator.rb +46 -46
  39. data/lib/aspera/cli/plugins/preview.rb +122 -114
  40. data/lib/aspera/cli/plugins/server.rb +137 -83
  41. data/lib/aspera/cli/plugins/shares.rb +30 -29
  42. data/lib/aspera/cli/plugins/sync.rb +13 -33
  43. data/lib/aspera/cli/transfer_agent.rb +57 -57
  44. data/lib/aspera/cli/version.rb +1 -1
  45. data/lib/aspera/colors.rb +3 -3
  46. data/lib/aspera/command_line_builder.rb +27 -27
  47. data/lib/aspera/cos_node.rb +22 -20
  48. data/lib/aspera/data_repository.rb +1 -1
  49. data/lib/aspera/environment.rb +30 -28
  50. data/lib/aspera/fasp/agent_base.rb +15 -15
  51. data/lib/aspera/fasp/agent_connect.rb +23 -21
  52. data/lib/aspera/fasp/agent_direct.rb +65 -67
  53. data/lib/aspera/fasp/agent_httpgw.rb +72 -68
  54. data/lib/aspera/fasp/agent_node.rb +23 -21
  55. data/lib/aspera/fasp/agent_trsdk.rb +20 -20
  56. data/lib/aspera/fasp/error.rb +3 -2
  57. data/lib/aspera/fasp/error_info.rb +11 -8
  58. data/lib/aspera/fasp/installation.rb +78 -78
  59. data/lib/aspera/fasp/listener.rb +1 -1
  60. data/lib/aspera/fasp/parameters.rb +75 -72
  61. data/lib/aspera/fasp/parameters.yaml +2 -2
  62. data/lib/aspera/fasp/resume_policy.rb +8 -8
  63. data/lib/aspera/fasp/transfer_spec.rb +35 -2
  64. data/lib/aspera/fasp/uri.rb +7 -7
  65. data/lib/aspera/faspex_gw.rb +7 -5
  66. data/lib/aspera/hash_ext.rb +3 -3
  67. data/lib/aspera/id_generator.rb +5 -5
  68. data/lib/aspera/keychain/encrypted_hash.rb +23 -28
  69. data/lib/aspera/keychain/macos_security.rb +21 -20
  70. data/lib/aspera/log.rb +7 -7
  71. data/lib/aspera/nagios.rb +19 -18
  72. data/lib/aspera/node.rb +209 -35
  73. data/lib/aspera/oauth.rb +37 -36
  74. data/lib/aspera/open_application.rb +19 -11
  75. data/lib/aspera/persistency_action_once.rb +4 -4
  76. data/lib/aspera/persistency_folder.rb +13 -13
  77. data/lib/aspera/preview/file_types.rb +8 -8
  78. data/lib/aspera/preview/generator.rb +67 -67
  79. data/lib/aspera/preview/utils.rb +27 -27
  80. data/lib/aspera/proxy_auto_config.js +41 -41
  81. data/lib/aspera/proxy_auto_config.rb +16 -16
  82. data/lib/aspera/rest.rb +56 -60
  83. data/lib/aspera/rest_call_error.rb +2 -1
  84. data/lib/aspera/rest_error_analyzer.rb +18 -17
  85. data/lib/aspera/rest_errors_aspera.rb +16 -16
  86. data/lib/aspera/secret_hider.rb +15 -13
  87. data/lib/aspera/ssh.rb +11 -10
  88. data/lib/aspera/sync.rb +158 -44
  89. data/lib/aspera/temp_file_manager.rb +2 -2
  90. data/lib/aspera/uri_reader.rb +4 -4
  91. data/lib/aspera/web_auth.rb +14 -13
  92. data.tar.gz.sig +0 -0
  93. metadata +8 -5
  94. metadata.gz.sig +0 -0
@@ -16,10 +16,43 @@ module Aspera
16
16
  'fasp_port' => UDP_PORT
17
17
  }.freeze
18
18
  # define constants for enums of parameters: <paramater>_<enum>, e.g. CIPHER_AES_128
19
- Aspera::Fasp::Parameters.description.each do |k,v|
19
+ Aspera::Fasp::Parameters.description.each do |k, v|
20
20
  next unless v[:enum].is_a?(Array)
21
21
  v[:enum].each do |enum|
22
- TransferSpec.const_set("#{k.to_s.upcase}_#{enum.upcase.gsub(/[^A-Z0-9]/,'_')}", enum.freeze)
22
+ TransferSpec.const_set("#{k.to_s.upcase}_#{enum.upcase.gsub(/[^A-Z0-9]/, '_')}", enum.freeze)
23
+ end
24
+ end
25
+ class << self
26
+ def ascp_opts_to_ts(tspec, opts)
27
+ return if opts.nil?
28
+ raise 'ascp options must be an Array' unless opts.is_a?(Array)
29
+ raise 'transfer spec must be a Hash' unless tspec.is_a?(Hash)
30
+ raise 'ascp options must be an Array or Strings' if opts.any?{|o|!o.is_a?(String)}
31
+ tspec['EX_ascp_args'] ||= []
32
+ raise 'EX_ascp_args must be an Array' unless tspec['EX_ascp_args'].is_a?(Array)
33
+ # TODO: translate command line args into transfer spec
34
+ # non translatable args are left in special ts parameter
35
+ tspec['EX_ascp_args'] = tspec['EX_ascp_args'].concat(opts)
36
+ return tspec
37
+ end
38
+
39
+ def action_to_direction(tspec, command)
40
+ raise 'transfer spec must be a Hash' unless tspec.is_a?(Hash)
41
+ tspec['direction'] = case command.to_sym
42
+ when :upload then DIRECTION_SEND
43
+ when :download then DIRECTION_RECEIVE
44
+ else raise 'Error: upload or download only'
45
+ end
46
+ return tspec
47
+ end
48
+
49
+ def action(tspec)
50
+ raise 'transfer spec must be a Hash' unless tspec.is_a?(Hash)
51
+ return case tspec['direction']
52
+ when DIRECTION_SEND then :upload
53
+ when DIRECTION_RECEIVE then :download
54
+ else raise 'Error: upload or download only'
55
+ end
23
56
  end
24
57
  end
25
58
  end
@@ -5,10 +5,10 @@ require 'aspera/command_line_builder'
5
5
 
6
6
  module Aspera
7
7
  module Fasp
8
- # translates a "faspe:" URI (used in Faspex) into transfer spec hash
8
+ # translates a "faspe:" URI (used in Faspex 4) into transfer spec hash
9
9
  class Uri
10
10
  def initialize(fasplink)
11
- @fasp_uri = URI.parse(fasplink.gsub(' ','%20'))
11
+ @fasp_uri = URI.parse(fasplink.gsub(' ', '%20'))
12
12
  # TODO: check scheme is faspe
13
13
  end
14
14
 
@@ -34,16 +34,16 @@ module Aspera
34
34
  when 'minrate' then result_ts['min_rate_kbps'] = value.to_i
35
35
  when 'port' then result_ts['fasp_port'] = value.to_i
36
36
  when 'bwcap' then result_ts['target_rate_cap_kbps'] = value.to_i
37
- when 'enc' then result_ts['cipher'] = value.gsub(/^aes/,'aes-').gsub(/cfb$/,'-cfb').gsub(/gcm$/,'-gcm').gsub(/--/,'-')
37
+ when 'enc' then result_ts['cipher'] = value.gsub(/^aes/, 'aes-').gsub(/cfb$/, '-cfb').gsub(/gcm$/, '-gcm').gsub(/--/, '-')
38
38
  when 'tags64' then result_ts['tags'] = JSON.parse(Base64.strict_decode64(value))
39
39
  when 'createpath' then result_ts['create_dir'] = CommandLineBuilder.yes_to_true(value)
40
40
  when 'fallback' then result_ts['http_fallback'] = CommandLineBuilder.yes_to_true(value)
41
41
  when 'lockpolicy' then result_ts['lock_rate_policy'] = CommandLineBuilder.yes_to_true(value)
42
42
  when 'lockminrate' then result_ts['lock_min_rate'] = CommandLineBuilder.yes_to_true(value)
43
- when 'auth' then Log.log.debug("ignoring auth #{name}=#{value}") # TODO: translate into transfer spec ? yes/no
44
- when 'v' then Log.log.debug("ignoring v #{name}=#{value}") # TODO: translate into transfer spec ? 2
45
- when 'protect' then Log.log.debug("ignoring protect #{name}=#{value}") # TODO: translate into transfer spec ?
46
- else Log.log.warn("URI parameter ignored: #{name} = #{value}")
43
+ when 'auth' then Log.log.debug{"ignoring auth #{name}=#{value}"} # TODO: translate into transfer spec ? yes/no
44
+ when 'v' then Log.log.debug{"ignoring v #{name}=#{value}"} # TODO: translate into transfer spec ? 2
45
+ when 'protect' then Log.log.debug{"ignoring protect #{name}=#{value}"} # TODO: translate into transfer spec ?
46
+ else Log.log.warn{"URI parameter ignored: #{name} = #{value}"}
47
47
  end
48
48
  end
49
49
  return result_ts
@@ -37,12 +37,13 @@ module Aspera
37
37
 
38
38
  faspex_pkg_parameters = JSON.parse(request.body)
39
39
  faspex_pkg_delivery = faspex_pkg_parameters['delivery']
40
- Log.log.debug("faspex pkg create parameters=#{faspex_pkg_parameters}")
40
+ Log.log.debug{"faspex pkg create parameters=#{faspex_pkg_parameters}"}
41
41
 
42
42
  # get recipient ids
43
43
  files_pkg_recipients = []
44
44
  faspex_pkg_delivery['recipients'].each do |recipient_email|
45
- user_lookup = @aoc_api_user.read('contacts',
45
+ user_lookup = @aoc_api_user.read(
46
+ 'contacts',
46
47
  { 'current_workspace_id' => @aoc_workspace_id, 'q' => recipient_email })[:data]
47
48
  raise StandardError,
48
49
  "no such unique user: #{recipient_email} / #{user_lookup}" unless !user_lookup.nil? && user_lookup.length.eql?(1)
@@ -67,7 +68,8 @@ module Aspera
67
68
  node_info = @aoc_api_user.read("nodes/#{the_package['node_id']}")[:data]
68
69
 
69
70
  # get transfer token (for node)
70
- node_auth_bearer_token = @aoc_api_user.oauth_token(scope: AoC.node_scope(node_info['access_key'],
71
+ node_auth_bearer_token = @aoc_api_user.oauth_token(scope: AoC.node_scope(
72
+ node_info['access_key'],
71
73
  AoC::SCOPE_NODE_USER))
72
74
 
73
75
  # tell Files what to expect in package: 1 transfer (can also be done after transfer)
@@ -123,7 +125,7 @@ module Aspera
123
125
  'links' => { 'status' => 'unused' },
124
126
  'xfer_sessions' => [faspex_transfer_spec]
125
127
  }
126
- Log.log.info("faspex_package_create_result=#{faspex_package_create_result}")
128
+ Log.log.info{"faspex_package_create_result=#{faspex_package_create_result}"}
127
129
  response.status = 200
128
130
  response.content_type = 'application/json'
129
131
  response.body = JSON.generate(faspex_package_create_result)
@@ -160,7 +162,7 @@ module Aspera
160
162
  SSLEnable: true,
161
163
  SSLCertName: [['CN', WEBrick::Utils.getservername]]
162
164
  }
163
- Log.log.info("Server started on port #{webrick_options[:Port]}")
165
+ Log.log.info{"Server started on port #{webrick_options[:Port]}"}
164
166
  @server = WEBrick::HTTPServer.new(webrick_options)
165
167
  @server.mount('/aspera/faspex', FxGwServlet, a_aoc_api_user, a_workspace_id)
166
168
  @server.mount('/newuser', NewUserServlet)
@@ -2,11 +2,11 @@
2
2
 
3
3
  class ::Hash
4
4
  def deep_merge(second)
5
- merge(second){|_key,v1,v2|Hash === v1 && Hash === v2 ? v1.deep_merge(v2) : v2}
5
+ merge(second){|_key, v1, v2|Hash === v1 && Hash === v2 ? v1.deep_merge(v2) : v2}
6
6
  end
7
7
 
8
8
  def deep_merge!(second)
9
- merge!(second){|_key,v1,v2|Hash === v1 && Hash === v2 ? v1.deep_merge!(v2) : v2}
9
+ merge!(second){|_key, v1, v2|Hash === v1 && Hash === v2 ? v1.deep_merge!(v2) : v2}
10
10
  end
11
11
  end
12
12
 
@@ -14,7 +14,7 @@ end
14
14
  unless Hash.method_defined?(:transform_keys)
15
15
  class Hash
16
16
  def transform_keys
17
- return each_with_object({}){|(k,v),memo|memo[yield(k)]=v} if block_given?
17
+ return each_with_object({}){|(k, v), memo|memo[yield(k)] = v} if block_given?
18
18
  raise 'missing block'
19
19
  end
20
20
  end
@@ -7,7 +7,7 @@ module Aspera
7
7
  ID_SEPARATOR = '_'
8
8
  WINDOWS_PROTECTED_CHAR = %r{[/:"<>\\*?]}.freeze
9
9
  PROTECTED_CHAR_REPLACE = '_'
10
- private_constant :ID_SEPARATOR,:PROTECTED_CHAR_REPLACE,:WINDOWS_PROTECTED_CHAR
10
+ private_constant :ID_SEPARATOR, :PROTECTED_CHAR_REPLACE, :WINDOWS_PROTECTED_CHAR
11
11
  class << self
12
12
  def from_list(object_id)
13
13
  if object_id.is_a?(Array)
@@ -16,10 +16,10 @@ module Aspera
16
16
  end.join(ID_SEPARATOR)
17
17
  end
18
18
  raise 'id must be a String' unless object_id.is_a?(String)
19
- return object_id.
20
- gsub(WINDOWS_PROTECTED_CHAR,PROTECTED_CHAR_REPLACE). # remove windows forbidden chars
21
- gsub('.',PROTECTED_CHAR_REPLACE). # keep dot for extension only (nicer)
22
- downcase
19
+ return object_id
20
+ .gsub(WINDOWS_PROTECTED_CHAR, PROTECTED_CHAR_REPLACE) # remove windows forbidden chars
21
+ .gsub('.', PROTECTED_CHAR_REPLACE) # keep dot for extension only (nicer)
22
+ .downcase
23
23
  end
24
24
  end
25
25
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'aspera/hash_ext'
4
+ require 'aspera/environment'
4
5
  require 'symmetric_encryption/core'
5
6
  require 'yaml'
6
7
 
@@ -8,65 +9,59 @@ module Aspera
8
9
  module Keychain
9
10
  # Manage secrets in a simple Hash
10
11
  class EncryptedHash
11
- CIPHER_NAME='aes-256-cbc'
12
- ACCEPTED_KEYS = %i[label username password url description].freeze
13
- def initialize(path,current_password)
14
- @path=path
15
- self.password=current_password
12
+ CIPHER_NAME = 'aes-256-cbc'
13
+ CONTENT_KEYS = %i[label username password url description].freeze
14
+ def initialize(path, current_password)
15
+ @path = path
16
+ self.password = current_password
16
17
  raise 'path to vault file shall be String' unless @path.is_a?(String)
17
- @all_secrets=File.exist?(@path) ? YAML.load_stream(@cipher.decrypt(File.read(@path))).first : {}
18
+ @all_secrets = File.exist?(@path) ? YAML.load_stream(@cipher.decrypt(File.read(@path))).first : {}
18
19
  end
19
20
 
20
21
  def password=(new_password)
21
- key_bytes=CIPHER_NAME.split('-')[1].to_i/8
22
- # derive key from passphrase
23
- key="#{new_password}#{"\x0"*key_bytes}"[0..(key_bytes-1)]
24
- Log.log.debug("key=[#{key}],#{key.length}")
25
- SymmetricEncryption.cipher=@cipher = SymmetricEncryption::Cipher.new(cipher_name: CIPHER_NAME,key: key,encoding: :none)
22
+ # number of bits in second position
23
+ key_bytes = CIPHER_NAME.split('-')[1].to_i / Environment::BITS_PER_BYTE
24
+ # derive key from passphrase, add trailing zeros
25
+ key = "#{new_password}#{"\x0" * key_bytes}"[0..(key_bytes - 1)]
26
+ Log.log.debug{"key=[#{key}],#{key.length}"}
27
+ SymmetricEncryption.cipher = @cipher = SymmetricEncryption::Cipher.new(cipher_name: CIPHER_NAME, key: key, encoding: :none)
26
28
  end
27
29
 
28
30
  def save
29
- File.write(@path, @cipher.encrypt(YAML.dump(@all_secrets)),encoding: 'BINARY')
31
+ File.write(@path, @cipher.encrypt(YAML.dump(@all_secrets)), encoding: 'BINARY')
30
32
  end
31
33
 
32
34
  def set(options)
33
35
  raise 'options shall be Hash' unless options.is_a?(Hash)
34
- unsupported = options.keys - ACCEPTED_KEYS
36
+ unsupported = options.keys - CONTENT_KEYS
37
+ options.each_value {|v| raise 'value must be String' unless v.is_a?(String)}
35
38
  raise "unsupported options: #{unsupported}" unless unsupported.empty?
36
39
  label = options.delete(:label)
37
- raise "secret #{label} already exist, delete first" if @all_secrets.has_key?(label)
40
+ raise "secret #{label} already exist, delete first" if @all_secrets.key?(label)
38
41
  @all_secrets[label] = options.symbolize_keys
39
42
  save
40
43
  end
41
44
 
42
45
  def list
43
46
  result = []
44
- @all_secrets.each do |label,values|
47
+ @all_secrets.each do |label, values|
45
48
  normal = values.symbolize_keys
46
49
  normal[:label] = label
47
- ACCEPTED_KEYS.each{|k|normal[k] = '' unless normal.has_key?(k)}
50
+ CONTENT_KEYS.each{|k|normal[k] = '' unless normal.key?(k)}
48
51
  result.push(normal)
49
52
  end
50
53
  return result
51
54
  end
52
55
 
53
- def delete(options)
54
- raise 'options shall be Hash' unless options.is_a?(Hash)
55
- unsupported = options.keys - %i[label]
56
- raise "unsupported options: #{unsupported}" unless unsupported.empty?
57
- label=options[:label]
56
+ def delete(label:)
58
57
  @all_secrets.delete(label)
59
58
  save
60
59
  end
61
60
 
62
- def get(options)
63
- raise 'options shall be Hash' unless options.is_a?(Hash)
64
- unsupported = options.keys - %i[label]
65
- raise "unsupported options: #{unsupported}" unless unsupported.empty?
66
- label=options[:label]
61
+ def get(label:, exception: true)
62
+ raise "Label not found: #{label}" unless @all_secrets.key?(label) || !exception
67
63
  result = @all_secrets[label].clone
68
- raise "no such entry #{label}" if result.nil?
69
- result[:label]=label
64
+ result[:label] = label if result.is_a?(Hash)
70
65
  return result
71
66
  end
72
67
  end
@@ -10,10 +10,10 @@ module Aspera
10
10
  # keychain based on macOS keychain, using `security` cmmand line
11
11
  class Keychain
12
12
  DOMAINS = %i[user system common dynamic].freeze
13
- LIST_OPTIONS={
13
+ LIST_OPTIONS = {
14
14
  domain: :c
15
15
  }
16
- ADD_PASS_OPTIONS={
16
+ ADD_PASS_OPTIONS = {
17
17
  account: :a,
18
18
  creator: :c,
19
19
  type: :C,
@@ -32,7 +32,7 @@ module Aspera
32
32
  getpass: :g
33
33
  }.freeze
34
34
  class << self
35
- def execute(command,options=nil,supported=nil,lastopt=nil)
35
+ def execute(command, options=nil, supported=nil, lastopt=nil)
36
36
  url = options&.delete(:url)
37
37
  if !url.nil?
38
38
  uri = URI.parse(url)
@@ -40,20 +40,20 @@ module Aspera
40
40
  options[:protocol] = 'htps'
41
41
  raise 'host required in URL' if uri.host.nil?
42
42
  options[:server] = uri.host
43
- options[:path] = uri.path unless ['','/'].include?(uri.path)
43
+ options[:path] = uri.path unless ['', '/'].include?(uri.path)
44
44
  options[:port] = uri.port unless uri.port.eql?(443) && !url.include?(':443/')
45
45
  end
46
- cmd=['security',command]
47
- options&.each do |k,v|
48
- raise "unknown option: #{k}" unless supported.has_key?(k)
46
+ cmd = ['security', command]
47
+ options&.each do |k, v|
48
+ raise "unknown option: #{k}" unless supported.key?(k)
49
49
  next if v.nil?
50
50
  cmd.push("-#{supported[k]}")
51
51
  cmd.push(v.shellescape) unless v.empty?
52
52
  end
53
53
  cmd.push(lastopt) unless lastopt.nil?
54
- Log.log.debug("executing>>#{cmd.join(' ')}")
55
- result=%x(#{cmd.join(' ')} 2>&1)
56
- Log.log.debug("result>>[#{result}]")
54
+ Log.log.debug{"executing>>#{cmd.join(' ')}"}
55
+ result = %x(#{cmd.join(' ')} 2>&1)
56
+ Log.log.debug{"result>>[#{result}]"}
57
57
  return result
58
58
  end
59
59
 
@@ -70,8 +70,8 @@ module Aspera
70
70
  end
71
71
 
72
72
  def list(options={})
73
- raise ArgumentError,"Invalid domain #{options[:domain]}, expected one of: #{DOMAINS}" unless options[:domain].nil? || DOMAINS.include?(options[:domain])
74
- keychains(execute('list-keychains',options,LIST_OPTIONS))
73
+ raise ArgumentError, "Invalid domain #{options[:domain]}, expected one of: #{DOMAINS}" unless options[:domain].nil? || DOMAINS.include?(options[:domain])
74
+ keychains(execute('list-keychains', options, LIST_OPTIONS))
75
75
  end
76
76
 
77
77
  def by_name(name)
@@ -88,15 +88,15 @@ module Aspera
88
88
  [string].pack('H*').force_encoding('UTF-8')
89
89
  end
90
90
 
91
- def password(operation,passtype,options)
91
+ def password(operation, passtype, options)
92
92
  raise "wrong operation: #{operation}" unless %i[add find delete].include?(operation)
93
93
  raise "wrong passtype: #{passtype}" unless %i[generic internet].include?(passtype)
94
94
  raise 'options shall be Hash' unless options.is_a?(Hash)
95
- missing=(operation.eql?(:add) ? %i[account service password] : %i[label])-options.keys
95
+ missing = (operation.eql?(:add) ? %i[account service password] : %i[label]) - options.keys
96
96
  raise "missing options: #{missing}" unless missing.empty?
97
- options[:getpass]='' if operation.eql?(:find)
98
- output=self.class.execute("#{operation}-#{passtype}-password",options,ADD_PASS_OPTIONS,@path)
99
- raise output.gsub(/^.*: /,'') if output.start_with?('security: ')
97
+ options[:getpass] = '' if operation.eql?(:find)
98
+ output = self.class.execute("#{operation}-#{passtype}-password", options, ADD_PASS_OPTIONS, @path)
99
+ raise output.gsub(/^.*: /, '') if output.start_with?('security: ')
100
100
  return nil unless operation.eql?(:find)
101
101
  attributes = {}
102
102
  output.split("\n").each do |line|
@@ -121,7 +121,7 @@ module Aspera
121
121
  end
122
122
 
123
123
  class MacosSystem
124
- def initialize(name=nil,password=nil)
124
+ def initialize(name=nil, _password=nil)
125
125
  @keychain = name.nil? ? MacosSecurity::Keychain.default_keychain : MacosSecurity::Keychain.by_name(name)
126
126
  raise "no such keychain #{name}" if @keychain.nil?
127
127
  end
@@ -130,7 +130,8 @@ module Aspera
130
130
  raise 'options shall be Hash' unless options.is_a?(Hash)
131
131
  unsupported = options.keys - %i[label username password url description]
132
132
  raise "unsupported options: #{unsupported}" unless unsupported.empty?
133
- @keychain.password(:add,:generic, service: options[:label],
133
+ @keychain.password(
134
+ :add, :generic, service: options[:label],
134
135
  account: options[:username] || 'none', password: options[:password], comment: options[:description])
135
136
  end
136
137
 
@@ -138,7 +139,7 @@ module Aspera
138
139
  raise 'options shall be Hash' unless options.is_a?(Hash)
139
140
  unsupported = options.keys - %i[label]
140
141
  raise "unsupported options: #{unsupported}" unless unsupported.empty?
141
- info = @keychain.password(:find,:generic,label: options[:label])
142
+ info = @keychain.password(:find, :generic, label: options[:label])
142
143
  raise 'not found' if info.nil?
143
144
  result = options.clone
144
145
  result[:secret] = info['password']
data/lib/aspera/log.rb CHANGED
@@ -14,25 +14,25 @@ module Aspera
14
14
  # class methods
15
15
  class << self
16
16
  # levels are :debug,:info,:warn,:error,fatal,:unknown
17
- def levels; Logger::Severity.constants.sort{|a,b|Logger::Severity.const_get(a) <=> Logger::Severity.const_get(b)}.map{|c|c.downcase.to_sym};end
17
+ def levels; Logger::Severity.constants.sort{|a, b|Logger::Severity.const_get(a) <=> Logger::Severity.const_get(b)}.map{|c|c.downcase.to_sym}; end
18
18
 
19
19
  # where logs are sent to
20
- def logtypes; %i[stderr stdout syslog];end
20
+ def logtypes; %i[stderr stdout syslog]; end
21
21
 
22
22
  # get the logger object of singleton
23
- def log; instance.logger;end
23
+ def log; instance.logger; end
24
24
 
25
25
  # dump object in debug mode
26
26
  # @param name string or symbol
27
27
  # @param format either pp or json format
28
- def dump(name,object,format=:json)
28
+ def dump(name, object, format=:json)
29
29
  log.debug do
30
30
  result =
31
31
  case format
32
32
  when :json
33
- JSON.pretty_generate(object) rescue PP.pp(object,+'')
33
+ JSON.pretty_generate(object) rescue PP.pp(object, +'')
34
34
  when :ruby
35
- PP.pp(object,+'')
35
+ PP.pp(object, +'')
36
36
  else
37
37
  raise 'wrong parameter, expect pp or json'
38
38
  end
@@ -70,7 +70,7 @@ module Aspera
70
70
  # change underlying logger, but keep log level
71
71
  def logger_type=(new_logtype)
72
72
  current_severity_integer = @logger.level unless @logger.nil?
73
- current_severity_integer = ENV['AS_LOG_LEVEL'] if current_severity_integer.nil? && ENV.has_key?('AS_LOG_LEVEL')
73
+ current_severity_integer = ENV['AS_LOG_LEVEL'] if current_severity_integer.nil? && ENV.key?('AS_LOG_LEVEL')
74
74
  current_severity_integer = Logger::Severity::WARN if current_severity_integer.nil?
75
75
  case new_logtype
76
76
  when :stderr
data/lib/aspera/nagios.rb CHANGED
@@ -10,32 +10,32 @@ module Aspera
10
10
  # date offset levels
11
11
  DATE_WARN_OFFSET = 2
12
12
  DATE_CRIT_OFFSET = 5
13
- private_constant :LEVELS,:ADD_PREFIX,:DATE_WARN_OFFSET,:DATE_CRIT_OFFSET
13
+ private_constant :LEVELS, :ADD_PREFIX, :DATE_WARN_OFFSET, :DATE_CRIT_OFFSET
14
14
 
15
15
  # add methods to add nagios error levels, each take component name and message
16
16
  LEVELS.each_index do |code|
17
17
  name = "#{ADD_PREFIX}#{LEVELS[code]}".to_sym
18
- define_method(name){|comp,msg|@data.push({code: code,comp: comp,msg: msg})}
18
+ define_method(name){|comp, msg|@data.push({code: code, comp: comp, msg: msg})}
19
19
  end
20
20
 
21
21
  class << self
22
22
  # process results of a analysis and display status and exit with code
23
23
  def process(data)
24
24
  raise 'INTERNAL ERROR, result must be list and not empty' unless data.is_a?(Array) && !data.empty?
25
- %w[status component message].each{|c|raise "INTERNAL ERROR, result must have #{c}" unless data.first.has_key?(c)}
25
+ %w[status component message].each{|c|raise "INTERNAL ERROR, result must have #{c}" unless data.first.key?(c)}
26
26
  res_errors = data.reject{|s|s['status'].eql?('ok')}
27
27
  # keep only errors in case of problem, other ok are assumed so
28
28
  data = res_errors unless res_errors.empty?
29
29
  # first is most critical
30
- data.sort!{|a,b|LEVELS.index(a['status'].to_sym) <=> LEVELS.index(b['status'].to_sym)}
30
+ data.sort!{|a, b|LEVELS.index(a['status'].to_sym) <=> LEVELS.index(b['status'].to_sym)}
31
31
  # build message: if multiple components: concatenate
32
- #message = data.map{|i|"#{i['component']}:#{i['message']}"}.join(', ').gsub("\n",' ')
33
- message = data.
34
- map{|i|i['component']}.
35
- uniq.
36
- map{|comp|comp + ':' + data.select{|d|d['component'].eql?(comp)}.map{|d|d['message']}.join(',')}.
37
- join(', ').
38
- tr("\n",' ')
32
+ # message = data.map{|i|"#{i['component']}:#{i['message']}"}.join(', ').gsub("\n",' ')
33
+ message = data
34
+ .map{|i|i['component']}
35
+ .uniq
36
+ .map{|comp|comp + ':' + data.select{|d|d['component'].eql?(comp)}.map{|d|d['message']}.join(',')}
37
+ .join(', ')
38
+ .tr("\n", ' ')
39
39
  status = data.first['status'].upcase
40
40
  # display status for nagios
41
41
  puts("#{status} - [#{message}]\n")
@@ -45,6 +45,7 @@ module Aspera
45
45
  end
46
46
 
47
47
  attr_reader :data
48
+
48
49
  def initialize
49
50
  @data = []
50
51
  end
@@ -55,26 +56,26 @@ module Aspera
55
56
  rtime = DateTime.strptime(remote_date)
56
57
  diff_time = (rtime - DateTime.now).abs
57
58
  diff_disp = diff_time.round(-2)
58
- Log.log.debug("DATE: #{remote_date} #{rtime} diff=#{diff_disp}")
59
+ Log.log.debug{"DATE: #{remote_date} #{rtime} diff=#{diff_disp}"}
59
60
  msg = "offset #{diff_disp} sec"
60
61
  if diff_time >= DATE_CRIT_OFFSET
61
- add_critical(component,msg)
62
+ add_critical(component, msg)
62
63
  elsif diff_time >= DATE_WARN_OFFSET
63
- add_warning(component,msg)
64
+ add_warning(component, msg)
64
65
  else
65
- add_ok(component,msg)
66
+ add_ok(component, msg)
66
67
  end
67
68
  end
68
69
 
69
70
  def check_product_version(component, _product, version)
70
- add_ok(component,"version #{version}")
71
- # TODO check on database if latest version
71
+ add_ok(component, "version #{version}")
72
+ # TODO: check on database if latest version
72
73
  end
73
74
 
74
75
  # translate for display
75
76
  def result
76
77
  raise 'missing result' if @data.empty?
77
- {type: :object_list,data: @data.map{|i|{'status' => LEVELS[i[:code]].to_s,'component' => i[:comp],'message' => i[:msg]}}}
78
+ {type: :object_list, data: @data.map{|i|{'status' => LEVELS[i[:code]].to_s, 'component' => i[:comp], 'message' => i[:msg]}}}
78
79
  end
79
80
  end
80
81
  end