aspera-cli 4.7.0 → 4.8.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 +1 -0
  3. data/README.md +844 -861
  4. data/bin/ascli +20 -1
  5. data/bin/asession +37 -34
  6. data/docs/test_env.conf +11 -3
  7. data/examples/aoc.rb +13 -12
  8. data/examples/dascli +26 -0
  9. data/examples/faspex4.rb +34 -29
  10. data/examples/transfer.rb +30 -29
  11. data/lib/aspera/aoc.rb +151 -143
  12. data/lib/aspera/ascmd.rb +56 -45
  13. data/lib/aspera/ats_api.rb +6 -5
  14. data/lib/aspera/cli/basic_auth_plugin.rb +18 -16
  15. data/lib/aspera/cli/extended_value.rb +32 -30
  16. data/lib/aspera/cli/formater.rb +103 -111
  17. data/lib/aspera/cli/info.rb +2 -1
  18. data/lib/aspera/cli/listener/line_dump.rb +1 -0
  19. data/lib/aspera/cli/listener/logger.rb +1 -0
  20. data/lib/aspera/cli/listener/progress.rb +13 -12
  21. data/lib/aspera/cli/listener/progress_multi.rb +21 -20
  22. data/lib/aspera/cli/main.rb +106 -89
  23. data/lib/aspera/cli/manager.rb +96 -85
  24. data/lib/aspera/cli/plugin.rb +50 -32
  25. data/lib/aspera/cli/plugins/alee.rb +6 -5
  26. data/lib/aspera/cli/plugins/aoc.rb +521 -426
  27. data/lib/aspera/cli/plugins/ats.rb +84 -83
  28. data/lib/aspera/cli/plugins/bss.rb +30 -27
  29. data/lib/aspera/cli/plugins/config.rb +483 -397
  30. data/lib/aspera/cli/plugins/console.rb +17 -15
  31. data/lib/aspera/cli/plugins/cos.rb +26 -35
  32. data/lib/aspera/cli/plugins/faspex.rb +201 -168
  33. data/lib/aspera/cli/plugins/faspex5.rb +109 -74
  34. data/lib/aspera/cli/plugins/node.rb +378 -189
  35. data/lib/aspera/cli/plugins/orchestrator.rb +71 -65
  36. data/lib/aspera/cli/plugins/preview.rb +131 -122
  37. data/lib/aspera/cli/plugins/server.rb +94 -93
  38. data/lib/aspera/cli/plugins/shares.rb +42 -28
  39. data/lib/aspera/cli/plugins/sync.rb +15 -14
  40. data/lib/aspera/cli/transfer_agent.rb +56 -52
  41. data/lib/aspera/cli/version.rb +2 -1
  42. data/lib/aspera/colors.rb +29 -28
  43. data/lib/aspera/command_line_builder.rb +50 -43
  44. data/lib/aspera/cos_node.rb +64 -38
  45. data/lib/aspera/data_repository.rb +1 -0
  46. data/lib/aspera/environment.rb +18 -8
  47. data/lib/aspera/fasp/agent_base.rb +26 -23
  48. data/lib/aspera/fasp/agent_connect.rb +35 -30
  49. data/lib/aspera/fasp/agent_direct.rb +68 -60
  50. data/lib/aspera/fasp/agent_httpgw.rb +71 -64
  51. data/lib/aspera/fasp/agent_node.rb +24 -23
  52. data/lib/aspera/fasp/agent_trsdk.rb +19 -20
  53. data/lib/aspera/fasp/error.rb +2 -1
  54. data/lib/aspera/fasp/error_info.rb +79 -68
  55. data/lib/aspera/fasp/installation.rb +122 -114
  56. data/lib/aspera/fasp/listener.rb +1 -0
  57. data/lib/aspera/fasp/parameters.rb +44 -41
  58. data/lib/aspera/fasp/resume_policy.rb +14 -11
  59. data/lib/aspera/fasp/transfer_spec.rb +6 -5
  60. data/lib/aspera/fasp/uri.rb +25 -24
  61. data/lib/aspera/faspex_gw.rb +83 -72
  62. data/lib/aspera/hash_ext.rb +10 -12
  63. data/lib/aspera/id_generator.rb +8 -7
  64. data/lib/aspera/keychain/encrypted_hash.rb +60 -45
  65. data/lib/aspera/keychain/macos_security.rb +26 -24
  66. data/lib/aspera/log.rb +34 -38
  67. data/lib/aspera/nagios.rb +14 -13
  68. data/lib/aspera/node.rb +19 -19
  69. data/lib/aspera/oauth.rb +121 -101
  70. data/lib/aspera/open_application.rb +6 -5
  71. data/lib/aspera/persistency_action_once.rb +9 -8
  72. data/lib/aspera/persistency_folder.rb +10 -9
  73. data/lib/aspera/preview/file_types.rb +261 -266
  74. data/lib/aspera/preview/generator.rb +74 -73
  75. data/lib/aspera/preview/image_error.png +0 -0
  76. data/lib/aspera/preview/options.rb +7 -6
  77. data/lib/aspera/preview/utils.rb +30 -33
  78. data/lib/aspera/preview/video_error.png +0 -0
  79. data/lib/aspera/proxy_auto_config.rb +25 -23
  80. data/lib/aspera/rest.rb +73 -74
  81. data/lib/aspera/rest_call_error.rb +1 -0
  82. data/lib/aspera/rest_error_analyzer.rb +11 -9
  83. data/lib/aspera/rest_errors_aspera.rb +5 -4
  84. data/lib/aspera/secret_hider.rb +68 -0
  85. data/lib/aspera/ssh.rb +12 -10
  86. data/lib/aspera/sync.rb +49 -47
  87. data/lib/aspera/temp_file_manager.rb +7 -5
  88. data/lib/aspera/timer_limiter.rb +9 -8
  89. data/lib/aspera/uri_reader.rb +11 -14
  90. data/lib/aspera/web_auth.rb +17 -15
  91. data.tar.gz.sig +0 -0
  92. metadata +117 -34
  93. metadata.gz.sig +2 -0
  94. data/bin/dascli +0 -13
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'aspera/cli/basic_auth_plugin'
3
4
  require 'aspera/persistency_action_once'
4
5
  require 'aspera/id_generator'
6
+ require 'aspera/nagios'
5
7
  require 'securerandom'
6
8
 
7
9
  module Aspera
@@ -10,8 +12,8 @@ module Aspera
10
12
  class Faspex5 < BasicAuthPlugin
11
13
  class << self
12
14
  def detect(base_url)
13
- api=Rest.new({base_url: base_url})
14
- result=api.read('api/v5/configuration/ping')
15
+ api = Rest.new(base_url: base_url, redirect_max: 1)
16
+ result = api.read('api/v5/configuration/ping')
15
17
  if result[:http].code.start_with?('2') && result[:http].body.strip.empty?
16
18
  return {version: '5'}
17
19
  end
@@ -19,137 +21,170 @@ module Aspera
19
21
  end
20
22
  end
21
23
 
22
- VAL_ALL='ALL'
23
- TRANSFER_CONNECT='connect'
24
+ VAL_ALL = 'ALL'
25
+ TRANSFER_CONNECT = 'connect'
24
26
  private_constant :VAL_ALL,:TRANSFER_CONNECT
25
27
 
26
28
  def initialize(env)
27
29
  super(env)
28
30
  options.add_opt_simple(:client_id,'OAuth client identifier')
29
31
  options.add_opt_simple(:client_secret,'OAuth client secret')
30
- options.add_opt_simple(:redirect_uri,'OAuth redirect URI')
32
+ options.add_opt_simple(:redirect_uri,'OAuth redirect URI for web authentication')
31
33
  options.add_opt_list(:auth,[Oauth::STD_AUTH_TYPES,:boot].flatten,'OAuth type of authentication')
32
- options.add_opt_simple(:private_key,'Oauth RSA private key PEM value for JWT (prefix file path with @val:@file:)')
34
+ options.add_opt_simple(:private_key,'OAuth JWT RSA private key PEM value (prefix file path with @file:)')
35
+ options.add_opt_simple(:passphrase,'RSA private key passphrase')
33
36
  options.set_option(:auth,:jwt)
34
37
  options.parse_options!
35
38
  end
36
39
 
37
40
  def set_api
38
- faxpex5_api_base_url=options.get_option(:url,:mandatory)
39
- faxpex5_api_v5_url="#{faxpex5_api_base_url}/api/v5"
40
- @faxpex5_api_auth_url="#{faxpex5_api_base_url}/auth"
41
- case options.get_option(:auth,:mandatory)
41
+ @faxpex5_api_base_url = options.get_option(:url,is_type: :mandatory).gsub(%r{/+$},'')
42
+ @faxpex5_api_auth_url = "#{@faxpex5_api_base_url}/auth"
43
+ faxpex5_api_v5_url = "#{@faxpex5_api_base_url}/api/v5"
44
+ case options.get_option(:auth,is_type: :mandatory)
42
45
  when :boot
43
46
  # the password here is the token copied directly from browser in developer mode
44
- @api_v5=Rest.new({
45
- base_url: faxpex5_api_v5_url,
46
- headers: {'Authorization'=>options.get_option(:password,:mandatory)}
47
+ @api_v5 = Rest.new({
48
+ base_url: faxpex5_api_v5_url,
49
+ headers: {'Authorization' => options.get_option(:password,is_type: :mandatory)}
47
50
  })
48
51
  when :web
49
52
  # opens a browser and ask user to auth using web
50
- @api_v5=Rest.new({
51
- base_url: faxpex5_api_v5_url,
52
- auth: {
53
- type: :oauth2,
54
- base_url: @faxpex5_api_auth_url,
55
- crtype: :web,
56
- client_id: options.get_option(:client_id,:mandatory),
57
- web: {redirect_uri: options.get_option(:redirect_uri,:mandatory)}
53
+ @api_v5 = Rest.new({
54
+ base_url: faxpex5_api_v5_url,
55
+ auth: {
56
+ type: :oauth2,
57
+ base_url: @faxpex5_api_auth_url,
58
+ crtype: :web,
59
+ client_id: options.get_option(:client_id,is_type: :mandatory),
60
+ web: {redirect_uri: options.get_option(:redirect_uri,is_type: :mandatory)}
58
61
  }})
59
62
  when :jwt
60
- app_client_id=options.get_option(:client_id,:mandatory)
61
- @api_v5=Rest.new({
62
- base_url: faxpex5_api_v5_url,
63
- auth: {
64
- type: :oauth2,
65
- base_url: @faxpex5_api_auth_url,
66
- crtype: :jwt,
67
- client_id: app_client_id,
68
- jwt: {
69
- payload: {
70
- iss: app_client_id, # issuer
71
- aud: app_client_id, # audience TODO: ???
72
- sub: "user:#{options.get_option(:username,:mandatory)}" # subject also "client:#{app_client_id}" + auth user/pass
73
- },
74
- #auth: {type: :basic, options.get_option(:username,:mandatory), options.get_option(:password,:mandatory),
75
- private_key_obj: OpenSSL::PKey::RSA.new(options.get_option(:private_key,:mandatory)),
76
- headers: {typ: 'JWT'}
77
- }
63
+ app_client_id = options.get_option(:client_id,is_type: :mandatory)
64
+ @api_v5 = Rest.new({
65
+ base_url: faxpex5_api_v5_url,
66
+ auth: {
67
+ type: :oauth2,
68
+ base_url: @faxpex5_api_auth_url,
69
+ crtype: :jwt,
70
+ client_id: app_client_id,
71
+ jwt: {
72
+ payload: {
73
+ iss: app_client_id, # issuer
74
+ aud: app_client_id, # audience TODO: ???
75
+ sub: "user:#{options.get_option(:username,is_type: :mandatory)}" # subject also "client:#{app_client_id}" + auth user/pass
76
+ },
77
+ #auth: {type: :basic, options.get_option(:username,is_type: :mandatory), options.get_option(:password,is_type: :mandatory),
78
+ private_key_obj: OpenSSL::PKey::RSA.new(options.get_option(:private_key,is_type: :mandatory),options.get_option(:passphrase)),
79
+ headers: {typ: 'JWT'}
80
+ }
78
81
  }})
79
82
  end
80
83
  end
81
84
 
82
- ACTIONS=[:package, :admin].freeze
85
+ ACTIONS = %i[health package admin user].freeze
83
86
 
84
87
  def execute_action
85
88
  set_api
86
- command=options.get_next_command(ACTIONS)
89
+ command = options.get_next_command(ACTIONS)
87
90
  case command
91
+ when :health
92
+ nagios = Nagios.new
93
+ begin
94
+ result=Rest.new(base_url: @faxpex5_api_base_url).read('health')[:data]
95
+ result.each do |k,v|
96
+ nagios.add_ok(k,v.to_s)
97
+ end
98
+ rescue StandardError => e
99
+ nagios.add_critical('faspex api',e.to_s)
100
+ end
101
+ return nagios.result
102
+ when :user
103
+ case options.get_next_command(%i[profile])
104
+ when :profile
105
+ case options.get_next_command(%i[show modify])
106
+ when :show
107
+ return { type: :single_object, data: @api_v5.read('account/preferences')[:data] }
108
+ when :modify
109
+ @api_v5.update('account/preferences',options.get_next_argument('modified parameters (Hash)'))
110
+ return Main.result_status('modified')
111
+ end
112
+ end
88
113
  when :package
89
- command=options.get_next_command([:list,:show,:send,:receive])
114
+ command = options.get_next_command(%i[list show send receive])
90
115
  case command
91
116
  when :list
92
- parameters=options.get_option(:value,:optional)
93
- return {type: :object_list, data: @api_v5.read('packages',parameters)[:data]['packages'], fields: %w[id title release_date total_bytes total_files created_time state]}
117
+ parameters = options.get_option(:value)
118
+ return {
119
+ type: :object_list,
120
+ data: @api_v5.read('packages',parameters)[:data]['packages'],
121
+ fields: %w[id title release_date total_bytes total_files created_time state]
122
+ }
94
123
  when :show
95
- id=instance_identifier()
124
+ id = instance_identifier
96
125
  return {type: :single_object, data: @api_v5.read("packages/#{id}")[:data]}
97
126
  when :send
98
- parameters=options.get_option(:value,:mandatory)
127
+ parameters = options.get_option(:value,is_type: :mandatory)
99
128
  raise CliBadArgument,'value must be hash, refer to API' unless parameters.is_a?(Hash)
100
- package=@api_v5.create('packages',parameters)[:data]
101
- transfer_spec=@api_v5.create("packages/#{package['id']}/transfer_spec/upload",{transfer_type: TRANSFER_CONNECT})[:data]
129
+ package = @api_v5.create('packages',parameters)[:data]
130
+ # TODO: option to send from remote source
131
+ transfer_spec = @api_v5.create("packages/#{package['id']}/transfer_spec/upload",{transfer_type: TRANSFER_CONNECT})[:data]
102
132
  transfer_spec.delete('authentication')
103
133
  return Main.result_transfer(transfer.start(transfer_spec,{src: :node_gen3}))
104
134
  when :receive
105
- pkg_type='received'
106
- pack_id=instance_identifier()
107
- package_ids=[pack_id]
108
- skip_ids_data=[]
109
- skip_ids_persistency=nil
110
- if options.get_option(:once_only,:mandatory)
135
+ pkg_type = 'received'
136
+ pack_id = instance_identifier
137
+ package_ids = [pack_id]
138
+ skip_ids_data = []
139
+ skip_ids_persistency = nil
140
+ if options.get_option(:once_only,is_type: :mandatory)
111
141
  # read ids from persistency
112
- skip_ids_persistency=PersistencyActionOnce.new(
113
- manager: @agents[:persistency],
114
- data: skip_ids_data,
115
- id: IdGenerator.from_list(['faspex_recv',options.get_option(:url,:mandatory),options.get_option(:username,:mandatory),pkg_type]))
142
+ skip_ids_persistency = PersistencyActionOnce.new(
143
+ manager: @agents[:persistency],
144
+ data: skip_ids_data,
145
+ id: IdGenerator.from_list(['faspex_recv',options.get_option(:url,is_type: :mandatory),options.get_option(:username,is_type: :mandatory),pkg_type]))
116
146
  end
117
147
  if pack_id.eql?(VAL_ALL)
118
148
  # TODO: if packages have same name, they will overwrite
119
- parameters=options.get_option(:value,:optional)
120
- parameters||={'type'=>'received','subtype'=>'mypackages','limit'=>1000}
149
+ parameters = options.get_option(:value)
150
+ parameters ||= {'type' => 'received','subtype' => 'mypackages','limit' => 1000}
121
151
  raise CliBadArgument,'value filter must be Hash (API GET)' unless parameters.is_a?(Hash)
122
- package_ids=@api_v5.read('packages',parameters)[:data]['packages'].map{|p|p['id']}
152
+ package_ids = @api_v5.read('packages',parameters)[:data]['packages'].map{|p|p['id']}
123
153
  package_ids.reject!{|i|skip_ids_data.include?(i)}
124
154
  end
125
- result_transfer=[]
155
+ result_transfer = []
126
156
  package_ids.each do |pkgid|
127
157
  # TODO: allow from sent as well ?
128
- transfer_spec=@api_v5.create("packages/#{pkgid}/transfer_spec/download",{transfer_type: TRANSFER_CONNECT, type: pkg_type})[:data]
158
+ transfer_spec = @api_v5.create("packages/#{pkgid}/transfer_spec/download",{transfer_type: TRANSFER_CONNECT, type: pkg_type})[:data]
129
159
  transfer_spec.delete('authentication')
130
- statuses=transfer.start(transfer_spec,{src: :node_gen3})
131
- result_transfer.push({'package'=>pkgid,Main::STATUS_FIELD=>statuses})
160
+ statuses = transfer.start(transfer_spec,{src: :node_gen3})
161
+ result_transfer.push({'package' => pkgid,Main::STATUS_FIELD => statuses})
132
162
  # skip only if all sessions completed
133
163
  skip_ids_data.push(pkgid) if TransferAgent.session_status(statuses).eql?(:success)
134
164
  end
135
- skip_ids_persistency.save unless skip_ids_persistency.nil?
165
+ skip_ids_persistency&.save
136
166
  return Main.result_transfer_multiple(result_transfer)
137
167
  end # case package
138
168
  when :admin
139
169
  case options.get_next_command([:resource])
140
170
  when :resource
141
- res_type=options.get_next_command([:accounts, :contacts, :jobs, :workgroups, :shared_inboxes, :nodes, :oauth_clients, :registrations, :saml_configs])
142
- res_path=res_type.to_s
143
- display_fields=
171
+ res_type = options.get_next_command(%i[accounts contacts jobs workgroups shared_inboxes nodes oauth_clients registrations saml_configs metadata_profiles])
172
+ res_path = list_key = res_type.to_s
144
173
  case res_type
145
- when :accounts then [:all_but,'user_profile_data_attributes']
146
- when :oauth_clients then [:all_but,'public_key']
174
+ when :metadata_profiles
175
+ res_path='configuration/metadata_profiles'
176
+ list_key='profiles'
147
177
  end
148
- adm_api=@api_v5
178
+ display_fields =
179
+ case res_type
180
+ when :accounts then [:all_but,'user_profile_data_attributes']
181
+ when :oauth_clients then [:all_but,'public_key']
182
+ end
183
+ adm_api = @api_v5
149
184
  if res_type.eql?(:oauth_clients)
150
- adm_api=Rest.new(@api_v5.params.merge({base_url: @faxpex5_api_auth_url}))
185
+ adm_api = Rest.new(@api_v5.params.merge({base_url: @faxpex5_api_auth_url}))
151
186
  end
152
- return entity_action(adm_api,res_path,use_subkey: true, display_fields: display_fields)
187
+ return entity_action(adm_api,res_path,item_list_key: list_key, display_fields: display_fields)
153
188
  end
154
189
  end # case command
155
190
  end # action