aspera-cli 4.13.0 → 4.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +81 -7
  4. data/CONTRIBUTING.md +22 -6
  5. data/README.md +2038 -1080
  6. data/bin/ascli +18 -9
  7. data/bin/asession +12 -14
  8. data/examples/dascli +1 -1
  9. data/examples/proxy.pac +1 -1
  10. data/examples/rubyc +24 -0
  11. data/lib/aspera/aoc.rb +219 -159
  12. data/lib/aspera/ascmd.rb +25 -14
  13. data/lib/aspera/cli/basic_auth_plugin.rb +12 -9
  14. data/lib/aspera/cli/error.rb +17 -0
  15. data/lib/aspera/cli/extended_value.rb +47 -12
  16. data/lib/aspera/cli/formatter.rb +260 -179
  17. data/lib/aspera/cli/hints.rb +80 -0
  18. data/lib/aspera/cli/main.rb +104 -156
  19. data/lib/aspera/cli/manager.rb +259 -209
  20. data/lib/aspera/cli/plugin.rb +123 -63
  21. data/lib/aspera/cli/plugins/alee.rb +2 -3
  22. data/lib/aspera/cli/plugins/aoc.rb +341 -261
  23. data/lib/aspera/cli/plugins/ats.rb +22 -21
  24. data/lib/aspera/cli/plugins/bss.rb +5 -5
  25. data/lib/aspera/cli/plugins/config.rb +578 -627
  26. data/lib/aspera/cli/plugins/console.rb +44 -6
  27. data/lib/aspera/cli/plugins/cos.rb +15 -17
  28. data/lib/aspera/cli/plugins/faspex.rb +114 -100
  29. data/lib/aspera/cli/plugins/faspex5.rb +411 -264
  30. data/lib/aspera/cli/plugins/node.rb +354 -259
  31. data/lib/aspera/cli/plugins/orchestrator.rb +61 -29
  32. data/lib/aspera/cli/plugins/preview.rb +82 -90
  33. data/lib/aspera/cli/plugins/server.rb +79 -32
  34. data/lib/aspera/cli/plugins/shares.rb +55 -42
  35. data/lib/aspera/cli/sync_actions.rb +68 -0
  36. data/lib/aspera/cli/transfer_agent.rb +66 -73
  37. data/lib/aspera/cli/transfer_progress.rb +74 -0
  38. data/lib/aspera/cli/version.rb +1 -1
  39. data/lib/aspera/colors.rb +12 -8
  40. data/lib/aspera/command_line_builder.rb +14 -11
  41. data/lib/aspera/cos_node.rb +3 -2
  42. data/lib/aspera/data/6 +0 -0
  43. data/lib/aspera/environment.rb +24 -9
  44. data/lib/aspera/fasp/agent_aspera.rb +126 -0
  45. data/lib/aspera/fasp/agent_base.rb +31 -77
  46. data/lib/aspera/fasp/agent_connect.rb +25 -21
  47. data/lib/aspera/fasp/agent_direct.rb +89 -103
  48. data/lib/aspera/fasp/agent_httpgw.rb +231 -149
  49. data/lib/aspera/fasp/agent_node.rb +41 -34
  50. data/lib/aspera/fasp/agent_trsdk.rb +75 -32
  51. data/lib/aspera/fasp/error_info.rb +4 -2
  52. data/lib/aspera/fasp/faux_file.rb +52 -0
  53. data/lib/aspera/fasp/installation.rb +53 -195
  54. data/lib/aspera/fasp/management.rb +244 -0
  55. data/lib/aspera/fasp/parameters.rb +71 -37
  56. data/lib/aspera/fasp/parameters.yaml +76 -8
  57. data/lib/aspera/fasp/products.rb +162 -0
  58. data/lib/aspera/fasp/resume_policy.rb +3 -3
  59. data/lib/aspera/fasp/transfer_spec.rb +7 -6
  60. data/lib/aspera/fasp/uri.rb +26 -24
  61. data/lib/aspera/faspex_gw.rb +2 -2
  62. data/lib/aspera/faspex_postproc.rb +2 -2
  63. data/lib/aspera/hash_ext.rb +14 -4
  64. data/lib/aspera/json_rpc.rb +49 -0
  65. data/lib/aspera/keychain/macos_security.rb +13 -13
  66. data/lib/aspera/line_logger.rb +23 -0
  67. data/lib/aspera/log.rb +58 -16
  68. data/lib/aspera/node.rb +157 -92
  69. data/lib/aspera/oauth.rb +37 -19
  70. data/lib/aspera/open_application.rb +4 -4
  71. data/lib/aspera/persistency_action_once.rb +1 -1
  72. data/lib/aspera/persistency_folder.rb +2 -2
  73. data/lib/aspera/preview/file_types.rb +4 -2
  74. data/lib/aspera/preview/generator.rb +22 -35
  75. data/lib/aspera/preview/options.rb +2 -0
  76. data/lib/aspera/preview/terminal.rb +73 -16
  77. data/lib/aspera/preview/utils.rb +21 -28
  78. data/lib/aspera/proxy_auto_config.js +2 -2
  79. data/lib/aspera/rest.rb +136 -68
  80. data/lib/aspera/rest_call_error.rb +1 -1
  81. data/lib/aspera/rest_error_analyzer.rb +15 -14
  82. data/lib/aspera/rest_errors_aspera.rb +37 -34
  83. data/lib/aspera/secret_hider.rb +18 -15
  84. data/lib/aspera/ssh.rb +5 -2
  85. data/lib/aspera/sync.rb +127 -119
  86. data/lib/aspera/temp_file_manager.rb +10 -3
  87. data/lib/aspera/web_auth.rb +10 -7
  88. data/lib/aspera/web_server_simple.rb +9 -4
  89. data.tar.gz.sig +0 -0
  90. metadata +34 -17
  91. metadata.gz.sig +0 -0
  92. data/docs/test_env.conf +0 -186
  93. data/lib/aspera/cli/listener/line_dump.rb +0 -19
  94. data/lib/aspera/cli/listener/logger.rb +0 -22
  95. data/lib/aspera/cli/listener/progress.rb +0 -50
  96. data/lib/aspera/cli/listener/progress_multi.rb +0 -84
  97. data/lib/aspera/cli/plugins/sync.rb +0 -44
  98. data/lib/aspera/data/7 +0 -0
  99. data/lib/aspera/fasp/listener.rb +0 -13
@@ -1,9 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # cspell:ignore ascmd zmode zuid zgid fasping
3
4
  require 'aspera/cli/basic_auth_plugin'
4
- require 'aspera/cli/plugins/sync'
5
- require 'aspera/ascmd'
5
+ require 'aspera/cli/sync_actions'
6
6
  require 'aspera/fasp/transfer_spec'
7
+ require 'aspera/ascmd'
7
8
  require 'aspera/ssh'
8
9
  require 'aspera/nagios'
9
10
  require 'tempfile'
@@ -13,19 +14,12 @@ module Aspera
13
14
  module Cli
14
15
  module Plugins
15
16
  # implement basic remote access with FASP/SSH
16
- class SyncSpecServer
17
- def initialize(transfer_spec)
18
- @transfer_spec = transfer_spec
19
- end
20
-
21
- def transfer_spec(direction, local_path, remote_path)
22
- return @transfer_spec
23
- end
24
- end
25
-
26
17
  class Server < Aspera::Cli::BasicAuthPlugin
18
+ include SyncActions
27
19
  SSH_SCHEME = 'ssh'
28
- URI_SCHEMES = %w[https local].push(SSH_SCHEME).freeze
20
+ LOCAL_SCHEME = 'local'
21
+ HTTPS_SCHEME = 'https'
22
+ URI_SCHEMES = [SSH_SCHEME, LOCAL_SCHEME, HTTPS_SCHEME].freeze
29
23
  ASCMD_ALIASES = {
30
24
  browse: :ls,
31
25
  delete: :rm,
@@ -41,36 +35,88 @@ module Aspera
41
35
  cmd = cmd.map{|v|%Q("#{v}")}.join(' ') if cmd.is_a?(Array)
42
36
  Log.log.debug{"Executing: #{cmd} with '#{line}'"}
43
37
  stdout_str, stderr_str, status = Open3.capture3(cmd, stdin_data: line, binmode: true)
44
- Log.log.debug(">> #{status} -> #{stderr_str}")
38
+ Log.log.debug{"exec status: #{status} -> #{stderr_str}"}
45
39
  raise "command #{cmd} failed with code #{status.exitstatus} #{stderr_str}" unless status.success?
46
40
  return stdout_str
47
41
  end
48
42
  end
49
43
 
44
+ class << self
45
+ def application_name
46
+ 'HSTS Fasp/SSH'
47
+ end
48
+
49
+ def detect(address_or_url)
50
+ urls = if address_or_url.match?(%r{^[a-z]{1,6}://})
51
+ [address_or_url]
52
+ else
53
+ [
54
+ "ssh://#{address_or_url}:33001",
55
+ "ssh://#{address_or_url}:22"
56
+ ]
57
+ # wss not practical as it requires a token
58
+ end
59
+
60
+ urls.each do |base_url|
61
+ server_uri = URI.parse(base_url)
62
+ Log.log.debug{"URI=#{server_uri}, host=#{server_uri.hostname}, port=#{server_uri.port}, scheme=#{server_uri.scheme}"}
63
+ next unless server_uri.scheme.eql?(SSH_SCHEME)
64
+ begin
65
+ socket = TCPSocket.new(server_uri.hostname, server_uri.port)
66
+ socket.puts('SSH-2.0-Ascli_0.0')
67
+ version = socket.gets.chomp
68
+ if version.match?(/^SSH-2.0-/)
69
+ return {version: version.gsub(/^SSH-2.0-/, ''), url: base_url}
70
+ end
71
+ rescue StandardError => e
72
+ Log.log.debug{"detect error: #{e}"}
73
+ end
74
+ end
75
+ return nil
76
+ end
77
+
78
+ def wizard(object:, private_key_path: nil, pub_key_pem: nil)
79
+ options = object.options
80
+ return {
81
+ preset_value: {
82
+ url: options.get_option(:url, mandatory: true),
83
+ username: options.get_option(:username, mandatory: true),
84
+ password: options.get_option(:password, mandatory: true)
85
+ },
86
+ test_args: 'files br /'
87
+ }
88
+ end
89
+ end
90
+
50
91
  def initialize(env)
51
92
  super(env)
52
- options.add_opt_simple(:ssh_keys, 'SSH key path list (Array or single)')
53
- options.add_opt_simple(:ssh_options, 'SSH options (Hash)')
93
+ options.declare(:ssh_keys, 'SSH key path list (Array or single)')
94
+ options.declare(:passphrase, 'SSH private key passphrase')
95
+ options.declare(:ssh_options, 'SSH options', types: Hash, default: {})
96
+ SyncActions.declare_options(options)
54
97
  options.parse_options!
55
- @ssh_opts = nil
98
+ @ssh_opts = options.get_option(:ssh_options).symbolize_keys
56
99
  end
57
100
 
58
101
  # Read command line options
59
102
  # @return [Hash] transfer specification
60
103
  def options_to_base_transfer_spec
61
- url = options.get_option(:url, is_type: :mandatory)
104
+ url = options.get_option(:url, mandatory: true)
62
105
  server_transfer_spec = {}
63
106
  server_uri = URI.parse(url)
64
- Log.log.debug{"URI : #{server_uri}, port=#{server_uri.port}, scheme:#{server_uri.scheme}"}
107
+ Log.log.debug{"URI=#{server_uri}, host=#{server_uri.hostname}, port=#{server_uri.port}, scheme=#{server_uri.scheme}"}
65
108
  server_transfer_spec['remote_host'] = server_uri.hostname
66
109
  unless URI_SCHEMES.include?(server_uri.scheme)
67
110
  Log.log.warn{"Scheme [#{server_uri.scheme}] not supported in #{url}, use one of: #{URI_SCHEMES.join(', ')}. Defaulting to #{SSH_SCHEME}."}
68
111
  server_uri.scheme = SSH_SCHEME
69
112
  end
70
- if server_uri.scheme.eql?('local')
113
+ if server_uri.scheme.eql?(LOCAL_SCHEME)
71
114
  # Using local execution (mostly for testing)
115
+ server_transfer_spec['remote_host'] = 'localhost'
116
+ # simulate SSH environment, else ascp will fail
117
+ ENV['SSH_CLIENT'] = 'local 0 0'
72
118
  return server_transfer_spec
73
- elsif transfer.option_transfer_spec['token'].is_a?(String) && server_uri.scheme.eql?('https')
119
+ elsif transfer.option_transfer_spec['token'].is_a?(String) && server_uri.scheme.eql?(HTTPS_SCHEME)
74
120
  server_transfer_spec['wss_enabled'] = true
75
121
  server_transfer_spec['wss_port'] = server_uri.port
76
122
  # Using WSS
@@ -88,11 +134,7 @@ module Aspera
88
134
  options.set_option(:username, Aspera::Fasp::TransferSpec::ACCESS_KEY_TRANSFER_USER)
89
135
  Log.log.info{"No username provided: Assuming default transfer user: #{Aspera::Fasp::TransferSpec::ACCESS_KEY_TRANSFER_USER}"}
90
136
  end
91
- server_transfer_spec['remote_user'] = options.get_option(:username, is_type: :mandatory)
92
- ssh_args = options.get_option(:ssh_options)
93
- ssh_args = {} if ssh_args.nil?
94
- raise 'expecting a Hash for ssh_options' unless ssh_args.is_a?(Hash)
95
- @ssh_opts = ssh_args.symbolize_keys
137
+ server_transfer_spec['remote_user'] = options.get_option(:username, mandatory: true)
96
138
  if !server_uri.port.nil?
97
139
  @ssh_opts[:port] = server_uri.port
98
140
  server_transfer_spec['ssh_port'] = server_uri.port
@@ -119,6 +161,11 @@ module Aspera
119
161
  cred_set = true
120
162
  end
121
163
  end
164
+ ssh_passphrase = options.get_option(:passphrase)
165
+ if !ssh_passphrase.nil?
166
+ @ssh_opts[:passphrase] = ssh_passphrase
167
+ server_transfer_spec['ssh_private_key_passphrase'] = ssh_passphrase
168
+ end
122
169
  # if user provided transfer spec has a token, we will use bypass keys
123
170
  cred_set = true if transfer.option_transfer_spec['token'].is_a?(String)
124
171
  raise 'Either password, key , or transfer spec token must be provided' if !cred_set
@@ -131,8 +178,8 @@ module Aspera
131
178
  Fasp::TransferSpec.action_to_direction(transfer_spec, command)
132
179
  return Main.result_transfer(transfer.start(transfer_spec))
133
180
  when :sync
134
- sync_plugin = Plugins::Sync.new(@agents, sync_spec: SyncSpecServer.new(transfer_spec))
135
- return sync_plugin.execute_action
181
+ # lets ignore the arguments provided by execute_sync_action, we just give the transfer spec
182
+ return execute_sync_action {transfer_spec}
136
183
  end
137
184
  end
138
185
 
@@ -143,7 +190,7 @@ module Aspera
143
190
 
144
191
  def execute_action
145
192
  server_transfer_spec = options_to_base_transfer_spec
146
- ascmd_executor = if !@ssh_opts.nil?
193
+ ascmd_executor = if !@ssh_opts.empty?
147
194
  Ssh.new(server_transfer_spec['remote_host'], server_transfer_spec['remote_user'], @ssh_opts)
148
195
  elsif server_transfer_spec.key?('wss_enabled')
149
196
  nil
@@ -184,10 +231,10 @@ module Aspera
184
231
  when *TRANSFER_COMMANDS
185
232
  return execute_transfer(command, server_transfer_spec)
186
233
  when *Aspera::AsCmd::OPERATIONS
187
- args = options.get_next_argument('ascmd command arguments', expected: :multiple, mandatory: false)
234
+ command_arguments = options.get_next_argument('ascmd command arguments', expected: :multiple, mandatory: false)
188
235
  ascmd = Aspera::AsCmd.new(ascmd_executor)
189
236
  begin
190
- result = ascmd.send(:execute_single, command, args)
237
+ result = ascmd.send(:execute_single, command, command_arguments)
191
238
  case command
192
239
  when :mkdir, :mv, :cp, :rm
193
240
  return Main.result_success
@@ -199,7 +246,7 @@ module Aspera
199
246
  return {type: :single_object, data: result.stringify_keys}
200
247
  end
201
248
  rescue Aspera::AsCmd::Error => e
202
- raise CliBadArgument, e.extended_message
249
+ raise Cli::BadArgument, e.extended_message
203
250
  end
204
251
  else raise 'internal error: unexpected action'
205
252
  end
@@ -7,43 +7,67 @@ module Aspera
7
7
  module Plugins
8
8
  # Plugin for Aspera Shares v1
9
9
  class Shares < Aspera::Cli::BasicAuthPlugin
10
+ API_BASE = 'node_api'
10
11
  class << self
11
- def detect(base_url)
12
- api = Rest.new({base_url: base_url})
13
- # Shares
12
+ def detect(address_or_url)
13
+ address_or_url = "https://#{address_or_url}" unless address_or_url.match?(%r{^[a-z]{1,6}://})
14
+ api = Rest.new(base_url: address_or_url, redirect_max: 1)
15
+ found = false
14
16
  begin
15
17
  # shall fail: shares requires auth, but we check error message
16
18
  # TODO: use ping instead ?
17
- api.read('node_api/app')
19
+ api.read("#{API_BASE}/app")
18
20
  rescue RestCallError => e
19
21
  if e.response.code.to_s.eql?('401') && e.response.body.eql?('{"error":{"user_message":"API user authentication failed"}}')
20
- return {version: 'unknown'}
22
+ found = true
21
23
  end
22
24
  end
23
- nil
25
+ return nil unless found
26
+ version = 'unknown'
27
+ test_page = api.call({ operation: 'GET', subpath: 'login' })
28
+ if (m = test_page[:http].body.match(/\(v(1\..*)\)/))
29
+ version = m[1]
30
+ end
31
+ return {
32
+ version: version,
33
+ url: address_or_url
34
+ }
35
+ end
36
+
37
+ def wizard(object:, private_key_path: nil, pub_key_pem: nil)
38
+ options = object.options
39
+ return {
40
+ preset_value: {
41
+ url: options.get_option(:url, mandatory: true),
42
+ username: options.get_option(:username, mandatory: true),
43
+ password: options.get_option(:password, mandatory: true)
44
+ },
45
+ test_args: 'files br /'
46
+ }
24
47
  end
25
48
  end
26
49
 
27
50
  def initialize(env)
28
51
  super(env)
29
- options.add_opt_list(:type, %i[any local ldap saml], 'Type of user/group for operations')
30
- options.set_option(:type, :any)
52
+ options.declare(:type, 'Type of user/group for operations', values: %i[any local ldap saml], default: :any)
31
53
  options.parse_options!
32
54
  end
33
55
 
34
56
  SAML_IMPORT_MANDATORY = %w[id name_id].freeze
35
57
  SAML_IMPORT_ALLOWED = %w[email given_name surname].concat(SAML_IMPORT_MANDATORY).freeze
36
58
 
37
- ACTIONS = %i[health repository admin].freeze
59
+ ACTIONS = %i[health files admin].freeze
60
+ # common to users and groups
61
+ USR_GRP_SETTINGS = %i[transfer_settings app_authorizations share_permissions].freeze
38
62
 
39
63
  def execute_action
40
- command = options.get_next_command(ACTIONS)
64
+ command = options.get_next_command(ACTIONS, aliases: {repository: :files})
41
65
  case command
42
66
  when :health
43
67
  nagios = Nagios.new
44
68
  begin
45
69
  Rest
46
- .new(base_url: options.get_option(:url, is_type: :mandatory) + '/node_api')
70
+ .new(base_url: "#{options.get_option(:url, mandatory: true)}/#{API_BASE}")
47
71
  .call(
48
72
  operation: 'GET',
49
73
  subpath: 'ping',
@@ -54,25 +78,28 @@ module Aspera
54
78
  nagios.add_critical('node api', e.to_s)
55
79
  end
56
80
  return nagios.result
57
- when :repository
58
- api_shares_node = basic_auth_api('node_api')
81
+ when :repository, :files
82
+ api_shares_node = basic_auth_api(API_BASE)
59
83
  repo_command = options.get_next_command(Node::COMMANDS_SHARES)
60
- return Node.new(@agents.merge(skip_basic_auth_options: true, node_api: api_shares_node)).execute_action(repo_command)
84
+ return Node.new(@agents, api: api_shares_node).execute_action(repo_command)
61
85
  when :admin
62
86
  api_shares_admin = basic_auth_api('api/v1')
63
- admin_command = options.get_next_command(%i[user group share node])
87
+ admin_command = options.get_next_command(%i[user group share node].freeze)
64
88
  case admin_command
65
89
  when :node
66
90
  return entity_action(api_shares_admin, 'data/nodes')
67
91
  when :user, :group
68
92
  entity_type = admin_command
69
- entities_location = options.get_option(:type, is_type: :mandatory)
93
+ entities_location = options.get_option(:type, mandatory: true)
70
94
  entities_path = "data/#{entities_location}_#{entity_type}s"
71
95
  entity_action = nil
72
96
  case entities_location
73
97
  when :any
74
98
  entities_path = "data/#{entity_type}s"
75
- entity_action = %i[list show delete share_permissions app_authorizations].freeze
99
+ entity_action = %i[list show delete]
100
+ entity_action.concat(USR_GRP_SETTINGS)
101
+ entity_action.push(:users) if entity_type.eql?(:group)
102
+ entity_action.freeze
76
103
  when :local
77
104
  entity_action = %i[list show create modify delete].freeze
78
105
  when :ldap
@@ -80,31 +107,15 @@ module Aspera
80
107
  when :saml
81
108
  entity_action = %i[import].freeze
82
109
  end
83
- entity_command = options.get_next_command(entity_action)
84
- entity_path = "#{entities_path}/#{instance_identifier}" if %i[app_authorizations share_permissions].include?(entity_command)
85
- case entity_command
86
- when :list, :show, :create, :delete, :modify
110
+ entity_verb = options.get_next_command(entity_action)
111
+ # entity_path = "#{entities_path}/#{instance_identifier}" if %i[app_authorizations share_permissions].include?(entity_verb)
112
+ case entity_verb
113
+ when *Plugin::ALL_OPS
87
114
  display_fields = entity_type.eql?(:user) ? %w[id username first_name last_name email] : nil
88
115
  display_fields.push(:directory_user) if entity_type.eql?(:user) && entities_location.eql?(:any)
89
- return entity_command(entity_command, api_shares_admin, entities_path, display_fields: display_fields)
90
- when :app_authorizations
91
- case options.get_next_command(%i[modify show])
92
- when :show
93
- return {type: :single_object, data: api_shares_admin.read("#{entity_path}/app_authorizations")[:data]}
94
- when :modify
95
- parameters = options.get_option(:value, is_type: :mandatory)
96
- return {type: :single_object, data: api_shares_admin.update("#{entity_path}/app_authorizations", parameters)[:data]}
97
- end
98
- when :share_permissions
99
- case options.get_next_command(%i[list show])
100
- when :list
101
- return {type: :object_list, data: api_shares_admin.read("#{entity_path}/share_permissions")[:data]}
102
- when :show
103
- return {type: :single_object, data: api_shares_admin.read("#{entity_path}/share_permissions/#{instance_identifier}")[:data]}
104
- end
116
+ return entity_command(entity_verb, api_shares_admin, entities_path, display_fields: display_fields)
105
117
  when :import
106
- parameters = options.get_option(:value, is_type: :mandatory)
107
- return do_bulk_operation(parameters, 'created') do |entity_parameters|
118
+ return do_bulk_operation(command: entity_verb, descr: 'user information') do |entity_parameters|
108
119
  entity_parameters = entity_parameters.transform_keys{|k|k.gsub(/\s+/, '_').downcase}
109
120
  raise 'expecting Hash' unless entity_parameters.is_a?(Hash)
110
121
  SAML_IMPORT_MANDATORY.each{|p|raise "missing mandatory field: #{p}" if entity_parameters[p].nil?}
@@ -114,11 +125,13 @@ module Aspera
114
125
  api_shares_admin.create("#{entities_path}/import", entity_parameters)[:data]
115
126
  end
116
127
  when :add
117
- parameters = options.get_option(:value)
118
- return do_bulk_operation(parameters, 'created') do |entity_name|
119
- raise "expecting string (name), have #{entity_name.class}" unless entity_name.is_a?(String)
128
+ return do_bulk_operation(command: entity_verb, descr: "#{entity_type} name", values: String) do |entity_name|
120
129
  api_shares_admin.create(entities_path, {entity_type=>entity_name})[:data]
121
130
  end
131
+ when *USR_GRP_SETTINGS
132
+ group_id = instance_identifier
133
+ entities_path = "#{entities_path}/#{group_id}/#{entity_verb}"
134
+ return entity_action(api_shares_admin, entities_path, is_singleton: !entity_verb.eql?(:share_permissions))
122
135
  end
123
136
  when :share
124
137
  share_command = options.get_next_command(%i[user_permissions group_permissions].concat(Plugin::ALL_OPS))
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'aspera/sync'
4
+
5
+ module Aspera
6
+ module Cli
7
+ # Module for sync actions
8
+ module SyncActions
9
+ SIMPLE_ARGUMENTS_SYNC = {
10
+ direction: Aspera::Sync::DIRECTIONS,
11
+ local_dir: String,
12
+ remote_dir: String
13
+ }.stringify_keys.freeze
14
+
15
+ class << self
16
+ def declare_options(options)
17
+ options.declare(:sync_info, 'Information for sync instance and sessions', types: Hash)
18
+ end
19
+ end
20
+
21
+ def execute_sync_action(&block)
22
+ # options = Aspera::Cli::Manager.new
23
+ raise 'Internal Error: No block given' unless block
24
+ command = options.get_next_command(%i[start admin])
25
+ # try to get 3 arguments as simple arguments
26
+ case command
27
+ when :start
28
+ simple_session_args = {}
29
+ SIMPLE_ARGUMENTS_SYNC.each do |arg, check|
30
+ value = options.get_next_argument(
31
+ arg,
32
+ type: check.is_a?(Class) ? check : nil,
33
+ expected: check.is_a?(Class) ? :single : check,
34
+ mandatory: false)
35
+ break if value.nil?
36
+ simple_session_args[arg] = value.to_s
37
+ end
38
+ async_params = nil
39
+ if simple_session_args.empty?
40
+ async_params = options.get_option(:sync_info, mandatory: true)
41
+ else
42
+ raise Cli::BadArgument,
43
+ "Provide zero or 3 arguments: #{SIMPLE_ARGUMENTS_SYNC.keys.join(',')}" unless simple_session_args.keys.sort == SIMPLE_ARGUMENTS_SYNC.keys.sort
44
+ async_params = options.get_option(
45
+ :sync_info,
46
+ mandatory: false,
47
+ default: {'sessions' => [{'name' => File.basename(simple_session_args['local_dir'])}]})
48
+ raise "sync_info shall be a Hash with key 'sessions' with Array of Hash: #{async_params}" unless async_params.is_a?(Hash) &&
49
+ async_params['sessions']&.is_a?(Array) &&
50
+ async_params['sessions'].first.is_a?(Hash)
51
+ async_params['sessions'].first.merge!(simple_session_args)
52
+ end
53
+ Log.log.debug{Log.dump('async_params', async_params)}
54
+ Aspera::Sync.start(async_params, &block)
55
+ return Main.result_success
56
+ when :admin
57
+ command2 = options.get_next_command([:status])
58
+ case command2
59
+ when :status
60
+ sync_session_name = options.get_next_argument('name of sync session', mandatory: false, type: String)
61
+ async_params = options.get_option(:sync_info, mandatory: true)
62
+ return {type: :single_object, data: Aspera::Sync.admin_status(async_params, sync_session_name)}
63
+ end # command2
64
+ end # command
65
+ end # execute_action
66
+ end # SyncActions
67
+ end # Cli
68
+ end # Aspera