aspera-cli 4.4.0 → 4.7.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 (97) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2095 -1503
  3. data/bin/ascli +2 -1
  4. data/bin/asession +4 -5
  5. data/docs/test_env.conf +3 -0
  6. data/examples/aoc.rb +4 -3
  7. data/examples/faspex4.rb +25 -25
  8. data/examples/proxy.pac +1 -1
  9. data/examples/transfer.rb +17 -17
  10. data/lib/aspera/aoc.rb +238 -185
  11. data/lib/aspera/ascmd.rb +93 -83
  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 +142 -108
  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 +18 -21
  21. data/lib/aspera/cli/main.rb +173 -149
  22. data/lib/aspera/cli/manager.rb +163 -168
  23. data/lib/aspera/cli/plugin.rb +43 -31
  24. data/lib/aspera/cli/plugins/alee.rb +6 -6
  25. data/lib/aspera/cli/plugins/aoc.rb +405 -370
  26. data/lib/aspera/cli/plugins/ats.rb +86 -79
  27. data/lib/aspera/cli/plugins/bss.rb +14 -16
  28. data/lib/aspera/cli/plugins/config.rb +580 -362
  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 +201 -158
  32. data/lib/aspera/cli/plugins/faspex5.rb +80 -57
  33. data/lib/aspera/cli/plugins/node.rb +183 -166
  34. data/lib/aspera/cli/plugins/orchestrator.rb +71 -67
  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 +35 -19
  38. data/lib/aspera/cli/plugins/sync.rb +20 -22
  39. data/lib/aspera/cli/transfer_agent.rb +76 -113
  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/{manager.rb → agent_base.rb} +28 -25
  47. data/lib/aspera/fasp/{connect.rb → agent_connect.rb} +52 -43
  48. data/lib/aspera/fasp/{local.rb → agent_direct.rb} +58 -72
  49. data/lib/aspera/fasp/{http_gw.rb → agent_httpgw.rb} +37 -43
  50. data/lib/aspera/fasp/{node.rb → agent_node.rb} +35 -16
  51. data/lib/aspera/fasp/agent_trsdk.rb +104 -0
  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 +152 -124
  55. data/lib/aspera/fasp/listener.rb +1 -0
  56. data/lib/aspera/fasp/parameters.rb +87 -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 -89
  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 +121 -0
  65. data/lib/aspera/keychain/macos_security.rb +90 -0
  66. data/lib/aspera/log.rb +55 -37
  67. data/lib/aspera/nagios.rb +13 -12
  68. data/lib/aspera/node.rb +30 -25
  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 +154 -135
  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 +116 -29
  90. data/docs/Makefile +0 -66
  91. data/docs/README.erb.md +0 -3973
  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/api_detector.rb +0 -60
  96. data/lib/aspera/cli/plugins/shares2.rb +0 -114
  97. data/lib/aspera/secrets.rb +0 -20
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'aspera/cli/basic_auth_plugin'
2
3
  require 'aspera/persistency_action_once'
3
4
  require 'aspera/id_generator'
@@ -7,96 +8,102 @@ module Aspera
7
8
  module Cli
8
9
  module Plugins
9
10
  class Faspex5 < BasicAuthPlugin
11
+ class << self
12
+ def detect(base_url)
13
+ api=Rest.new({base_url: base_url})
14
+ result=api.read('api/v5/configuration/ping')
15
+ if result[:http].code.start_with?('2') && result[:http].body.strip.empty?
16
+ return {version: '5'}
17
+ end
18
+ return nil
19
+ end
20
+ end
21
+
10
22
  VAL_ALL='ALL'
23
+ TRANSFER_CONNECT='connect'
24
+ private_constant :VAL_ALL,:TRANSFER_CONNECT
25
+
11
26
  def initialize(env)
12
27
  super(env)
13
- options.add_opt_simple(:client_id,'API client identifier in application')
14
- options.add_opt_simple(:client_secret,'API client secret in application')
15
- options.add_opt_simple(:redirect_uri,'API client redirect URI')
16
- options.add_opt_list(:auth,Oauth.auth_types.clone.push(:boot),'type of Oauth authentication')
17
- options.add_opt_simple(:private_key,'RSA private key PEM value for JWT (prefix file path with @val:@file:)')
28
+ options.add_opt_simple(:client_id,'OAuth client identifier')
29
+ options.add_opt_simple(:client_secret,'OAuth client secret')
30
+ options.add_opt_simple(:redirect_uri,'OAuth redirect URI')
31
+ 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:)')
18
33
  options.set_option(:auth,:jwt)
19
34
  options.parse_options!
20
35
  end
21
36
 
22
37
  def set_api
23
- @faxpex5_api_base_url=options.get_option(:url,:mandatory)
24
- faxpex5_api_v5_url="#{@faxpex5_api_base_url}/api/v5"
25
- faxpex5_api_auth_url="#{@faxpex5_api_base_url}/auth"
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"
26
41
  case options.get_option(:auth,:mandatory)
27
42
  when :boot
28
43
  # the password here is the token copied directly from browser in developer mode
29
44
  @api_v5=Rest.new({
30
- :base_url => faxpex5_api_v5_url,
31
- :headers => {'Authorization'=>options.get_option(:password,:mandatory)},
45
+ base_url: faxpex5_api_v5_url,
46
+ headers: {'Authorization'=>options.get_option(:password,:mandatory)}
32
47
  })
33
48
  when :web
34
49
  # opens a browser and ask user to auth using web
35
50
  @api_v5=Rest.new({
36
- :base_url => faxpex5_api_v5_url,
37
- :auth => {
38
- :type => :oauth2,
39
- :base_url => faxpex5_api_auth_url,
40
- :grant => :web,
41
- :state => SecureRandom.uuid,
42
- :client_id => options.get_option(:client_id,:mandatory),
43
- :redirect_uri => options.get_option(:redirect_uri,:mandatory),
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)}
44
58
  }})
45
59
  when :jwt
46
- # currently Faspex 5 beta 3 only supports non-user based apis (e.g. jobs)
47
60
  app_client_id=options.get_option(:client_id,:mandatory)
48
61
  @api_v5=Rest.new({
49
- :base_url => faxpex5_api_v5_url,
50
- :auth => {
51
- :type => :oauth2,
52
- :base_url => faxpex5_api_auth_url,
53
- :grant => :jwt,
54
- :f5_username => options.get_option(:username,:mandatory),
55
- :f5_password => options.get_option(:password,:mandatory),
56
- :client_id => app_client_id,
57
- :client_secret => options.get_option(:client_secret,:mandatory),
58
- :jwt_subject => "client:#{app_client_id}", # TODO Mmmm
59
- :jwt_audience => app_client_id, # TODO Mmmm
60
- :jwt_private_key_obj => OpenSSL::PKey::RSA.new(options.get_option(:private_key,:mandatory)),
61
- :jwt_headers => {typ: 'JWT'}
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
+ }
62
78
  }})
63
79
  end
64
80
  end
65
81
 
66
- ACTIONS=[ :node, :package, :auth_client, :jobs ]
82
+ ACTIONS=[:package, :admin].freeze
67
83
 
68
- #
69
84
  def execute_action
70
85
  set_api
71
86
  command=options.get_next_command(ACTIONS)
72
87
  case command
73
- when :auth_client
74
- api_auth=Rest.new(@api_v5.params.merge({base_url: "#{@faxpex5_api_base_url}/auth"}))
75
- return self.entity_action(api_auth,'oauth_clients',nil,:id,nil,true)
76
- when :node
77
- return self.entity_action(@api_v5,'nodes',nil,:id,nil,true)
78
- when :jobs
79
- # to test JWT
80
- return self.entity_action(@api_v5,'jobs',nil,:id,nil,true)
81
88
  when :package
82
89
  command=options.get_next_command([:list,:show,:send,:receive])
83
90
  case command
84
91
  when :list
85
92
  parameters=options.get_option(:value,:optional)
86
- return {:type => :object_list, :data=>@api_v5.read('packages',parameters)[:data]['packages']}
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]}
87
94
  when :show
88
- id=options.get_option(:id,:mandatory)
89
- return {:type => :single_object, :data=>@api_v5.read("packages/#{id}")[:data]}
95
+ id=instance_identifier()
96
+ return {type: :single_object, data: @api_v5.read("packages/#{id}")[:data]}
90
97
  when :send
91
98
  parameters=options.get_option(:value,:mandatory)
92
99
  raise CliBadArgument,'value must be hash, refer to API' unless parameters.is_a?(Hash)
93
100
  package=@api_v5.create('packages',parameters)[:data]
94
- transfer_spec=@api_v5.create("packages/#{package['id']}/transfer_spec/upload",{transfer_type: 'Connect'})[:data]
101
+ transfer_spec=@api_v5.create("packages/#{package['id']}/transfer_spec/upload",{transfer_type: TRANSFER_CONNECT})[:data]
95
102
  transfer_spec.delete('authentication')
96
- return Main.result_transfer(self.transfer.start(transfer_spec,{:src=>:node_gen3}))
103
+ return Main.result_transfer(transfer.start(transfer_spec,{src: :node_gen3}))
97
104
  when :receive
98
105
  pkg_type='received'
99
- pack_id=options.get_option(:id,:mandatory)
106
+ pack_id=instance_identifier()
100
107
  package_ids=[pack_id]
101
108
  skip_ids_data=[]
102
109
  skip_ids_persistency=nil
@@ -113,24 +120,40 @@ module Aspera
113
120
  parameters||={'type'=>'received','subtype'=>'mypackages','limit'=>1000}
114
121
  raise CliBadArgument,'value filter must be Hash (API GET)' unless parameters.is_a?(Hash)
115
122
  package_ids=@api_v5.read('packages',parameters)[:data]['packages'].map{|p|p['id']}
116
- package_ids.select!{|i|!skip_ids_data.include?(i)}
123
+ package_ids.reject!{|i|skip_ids_data.include?(i)}
117
124
  end
118
125
  result_transfer=[]
119
- package_ids.each do |id|
126
+ package_ids.each do |pkgid|
120
127
  # TODO: allow from sent as well ?
121
- transfer_spec=@api_v5.create("packages/#{id}/transfer_spec/download",{transfer_type: 'Connect', type: pkg_type})[:data]
128
+ transfer_spec=@api_v5.create("packages/#{pkgid}/transfer_spec/download",{transfer_type: TRANSFER_CONNECT, type: pkg_type})[:data]
122
129
  transfer_spec.delete('authentication')
123
- statuses=self.transfer.start(transfer_spec,{:src=>:node_gen3})
124
- result_transfer.push({'package'=>id,Main::STATUS_FIELD=>statuses})
130
+ statuses=transfer.start(transfer_spec,{src: :node_gen3})
131
+ result_transfer.push({'package'=>pkgid,Main::STATUS_FIELD=>statuses})
125
132
  # skip only if all sessions completed
126
- skip_ids_data.push(id) if TransferAgent.session_status(statuses).eql?(:success)
133
+ skip_ids_data.push(pkgid) if TransferAgent.session_status(statuses).eql?(:success)
127
134
  end
128
135
  skip_ids_persistency.save unless skip_ids_persistency.nil?
129
136
  return Main.result_transfer_multiple(result_transfer)
137
+ end # case package
138
+ when :admin
139
+ case options.get_next_command([:resource])
140
+ 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=
144
+ case res_type
145
+ when :accounts then [:all_but,'user_profile_data_attributes']
146
+ when :oauth_clients then [:all_but,'public_key']
147
+ end
148
+ adm_api=@api_v5
149
+ if res_type.eql?(:oauth_clients)
150
+ adm_api=Rest.new(@api_v5.params.merge({base_url: @faxpex5_api_auth_url}))
151
+ end
152
+ return entity_action(adm_api,res_path,use_subkey: true, display_fields: display_fields)
130
153
  end
131
- end
132
- end
133
- end
154
+ end # case command
155
+ end # action
156
+ end # Faspex5
134
157
  end # Plugins
135
158
  end # Cli
136
159
  end # Aspera