aspera-cli 4.0.0.pre3 → 4.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +695 -205
  3. data/bin/dascli +13 -0
  4. data/docs/README.erb.md +615 -157
  5. data/docs/test_env.conf +23 -5
  6. data/docs/transfer_spec.html +1 -1
  7. data/examples/aoc.rb +14 -3
  8. data/examples/faspex4.rb +78 -0
  9. data/lib/aspera/aoc.rb +87 -108
  10. data/lib/aspera/cli/formater.rb +2 -0
  11. data/lib/aspera/cli/main.rb +46 -34
  12. data/lib/aspera/cli/plugin.rb +9 -4
  13. data/lib/aspera/cli/plugins/alee.rb +1 -1
  14. data/lib/aspera/cli/plugins/aoc.rb +207 -182
  15. data/lib/aspera/cli/plugins/ats.rb +2 -2
  16. data/lib/aspera/cli/plugins/config.rb +173 -117
  17. data/lib/aspera/cli/plugins/console.rb +2 -2
  18. data/lib/aspera/cli/plugins/faspex.rb +51 -36
  19. data/lib/aspera/cli/plugins/faspex5.rb +82 -41
  20. data/lib/aspera/cli/plugins/node.rb +3 -3
  21. data/lib/aspera/cli/plugins/preview.rb +35 -25
  22. data/lib/aspera/cli/plugins/server.rb +23 -8
  23. data/lib/aspera/cli/transfer_agent.rb +7 -6
  24. data/lib/aspera/cli/version.rb +1 -1
  25. data/lib/aspera/cos_node.rb +33 -28
  26. data/lib/aspera/environment.rb +2 -2
  27. data/lib/aspera/fasp/connect.rb +28 -21
  28. data/lib/aspera/fasp/http_gw.rb +140 -28
  29. data/lib/aspera/fasp/installation.rb +101 -53
  30. data/lib/aspera/fasp/local.rb +88 -45
  31. data/lib/aspera/fasp/manager.rb +15 -0
  32. data/lib/aspera/fasp/node.rb +4 -4
  33. data/lib/aspera/fasp/parameters.rb +6 -18
  34. data/lib/aspera/fasp/resume_policy.rb +13 -12
  35. data/lib/aspera/log.rb +1 -1
  36. data/lib/aspera/node.rb +61 -1
  37. data/lib/aspera/oauth.rb +49 -46
  38. data/lib/aspera/persistency_folder.rb +9 -4
  39. data/lib/aspera/preview/file_types.rb +53 -21
  40. data/lib/aspera/preview/generator.rb +3 -3
  41. data/lib/aspera/rest.rb +29 -18
  42. data/lib/aspera/secrets.rb +20 -0
  43. data/lib/aspera/temp_file_manager.rb +19 -0
  44. data/lib/aspera/web_auth.rb +105 -0
  45. metadata +42 -22
@@ -107,7 +107,7 @@ module Aspera
107
107
  :auth => {
108
108
  :type => :basic,
109
109
  :username => access_key_id,
110
- :password => self.config.get_secret(access_key_id)}})
110
+ :password => @agents[:secret].get_secret(access_key_id)}})
111
111
  command=self.options.get_next_command(Node::COMMON_ACTIONS)
112
112
  return Node.new(@agents.merge(skip_basic_auth_options: true, node_api: api_node)).execute_action(command)
113
113
  when :cluster
@@ -116,7 +116,7 @@ module Aspera
116
116
  :auth => {
117
117
  :type => :basic,
118
118
  :username => access_key_id,
119
- :password => self.config.get_secret(access_key_id)
119
+ :password => @agents[:secret].get_secret(access_key_id)
120
120
  }}
121
121
  api_ak_auth=Rest.new(rest_params)
122
122
  return {:type=>:single_object, :data=>api_ak_auth.read("servers")[:data]}
@@ -7,10 +7,12 @@ require 'aspera/aoc'
7
7
  require 'aspera/proxy_auto_config'
8
8
  require 'aspera/uri_reader'
9
9
  require 'aspera/rest'
10
+ require 'aspera/persistency_action_once'
10
11
  require 'xmlsimple'
11
12
  require 'base64'
12
13
  require 'net/smtp'
13
14
  require 'open3'
15
+ require 'date'
14
16
 
15
17
  module Aspera
16
18
  module Cli
@@ -25,6 +27,7 @@ module Aspera
25
27
  CONF_PRESET_CONFIG='config'
26
28
  CONF_PRESET_VERSION='version'
27
29
  CONF_PRESET_DEFAULT='default'
30
+ CONF_PRESET_GLOBAL='global_common_defaults'
28
31
  CONF_PLUGIN_SYM = :config # Plugins::Config.name.split('::').last.downcase.to_sym
29
32
  CONF_GLOBAL_SYM = :config
30
33
  # old tool name
@@ -41,20 +44,21 @@ module Aspera
41
44
  AOC_COMMAND_CURRENT=AOC_COMMAND_V3
42
45
  CONNECT_WEB_URL = 'https://d3gcli72yxqn2z.cloudfront.net/connect'
43
46
  CONNECT_VERSIONS = 'connectversions.js'
47
+ TRANSFER_SDK_ARCHIVE_URL = 'https://ibm.biz/aspera_sdk'
44
48
  DEMO='demo'
49
+ DEMO_SERVER_PRESET='demoserver'
50
+ AOC_PATH_API_CLIENTS='admin/api-clients'
45
51
  def option_preset; nil; end
46
52
 
47
53
  def option_preset=(value)
48
54
  self.options.add_option_preset(preset_by_name(value))
49
55
  end
50
56
 
51
- private_constant :ASPERA_HOME_FOLDER_NAME,:DEFAULT_CONFIG_FILENAME,:CONF_PRESET_CONFIG,:CONF_PRESET_VERSION,:CONF_PRESET_DEFAULT,:PROGRAM_NAME_V1,:PROGRAM_NAME_V2,:DEFAULT_REDIRECT,:ASPERA_PLUGINS_FOLDERNAME,:RUBY_FILE_EXT,:AOC_COMMAND_V1,:AOC_COMMAND_V2,:AOC_COMMAND_V3,:AOC_COMMAND_CURRENT,:DEMO
52
- attr_accessor :option_ak_secret,:option_secrets
57
+ private_constant :DEFAULT_CONFIG_FILENAME,:CONF_PRESET_CONFIG,:CONF_PRESET_VERSION,:CONF_PRESET_DEFAULT,:CONF_PRESET_GLOBAL,:PROGRAM_NAME_V1,:PROGRAM_NAME_V2,:DEFAULT_REDIRECT,:ASPERA_PLUGINS_FOLDERNAME,:RUBY_FILE_EXT,:AOC_COMMAND_V1,:AOC_COMMAND_V2,:AOC_COMMAND_V3,:AOC_COMMAND_CURRENT,:DEMO,:TRANSFER_SDK_ARCHIVE_URL,:AOC_PATH_API_CLIENTS,:DEMO_SERVER_PRESET
53
58
 
54
- def initialize(env,tool_name,help_url,version)
59
+ def initialize(env,tool_name,help_url,version,main_folder)
55
60
  super(env)
56
- @option_ak_secret=nil
57
- @option_secrets={}
61
+ raise 'missing secret manager' if @agents[:secret].nil?
58
62
  @plugins={}
59
63
  @plugin_lookup_folders=[]
60
64
  @use_plugin_defaults=true
@@ -63,19 +67,11 @@ module Aspera
63
67
  @program_version=version
64
68
  @tool_name=tool_name
65
69
  @help_url=help_url
66
- tool_main_env_var="#{tool_name.upcase}_HOME"
67
- if ENV.has_key?(tool_main_env_var)
68
- @main_folder=ENV[tool_main_env_var]
69
- else
70
- user_home_folder=Dir.home
71
- raise CliError,"Home folder does not exist: #{user_home_folder}. Check your user environment or use #{tool_main_env_var}." unless Dir.exist?(user_home_folder)
72
- @main_folder=File.join(user_home_folder,ASPERA_HOME_FOLDER_NAME,tool_name)
73
- end
70
+ @main_folder=main_folder
74
71
  @conf_file_default=File.join(@main_folder,DEFAULT_CONFIG_FILENAME)
75
72
  @option_config_file=@conf_file_default
76
73
  Log.log.debug("#{tool_name} folder: #{@main_folder}")
77
74
  # set folder for FASP SDK
78
- Fasp::Installation.instance.folder=File.join(@main_folder,'sdk')
79
75
  add_plugin_lookup_folder(File.join(@main_folder,ASPERA_PLUGINS_FOLDERNAME))
80
76
  add_plugin_lookup_folder(self.class.gem_plugins_folder)
81
77
  # do file parameter first
@@ -91,35 +87,74 @@ module Aspera
91
87
  self.options.set_obj_attr(:ascp_path,self,:option_ascp_path)
92
88
  self.options.set_obj_attr(:use_product,self,:option_use_product)
93
89
  self.options.set_obj_attr(:preset,self,:option_preset)
94
- self.options.set_obj_attr(:secret,self,:option_ak_secret)
95
- self.options.set_obj_attr(:secrets,self,:option_secrets)
96
- self.options.add_opt_boolean(:override,"override existing value")
97
- self.options.add_opt_switch(:no_default,"-N","do not load default configuration for plugin") { @use_plugin_defaults=false }
90
+ self.options.set_obj_attr(:secret,@agents[:secret],:default_secret)
91
+ self.options.set_obj_attr(:secrets,@agents[:secret],:all_secrets)
92
+ self.options.add_opt_boolean(:override,'override existing value')
93
+ self.options.add_opt_switch(:no_default,'-N','do not load default configuration for plugin') { @use_plugin_defaults=false }
98
94
  self.options.add_opt_boolean(:use_generic_client,'wizard: AoC: use global or org specific jwt client id')
99
- self.options.add_opt_simple(:pkeypath,"path to private key for JWT (wizard)")
100
- self.options.add_opt_simple(:ascp_path,"path to ascp")
101
- self.options.add_opt_simple(:use_product,"use ascp from specified product")
102
- self.options.add_opt_simple(:smtp,"smtp configuration (extended value: hash)")
103
- self.options.add_opt_simple(:fpac,"proxy auto configuration URL")
104
- self.options.add_opt_simple(:preset,"-PVALUE","load the named option preset from current config file")
105
- self.options.add_opt_simple(:default,"set as default configuration for specified plugin")
106
- self.options.add_opt_simple(:secret,"access key secret for node")
107
- self.options.add_opt_simple(:secrets,"access key secret for node")
108
- self.options.add_opt_boolean(:test_mode,"skip user validation in wizard mode")
95
+ self.options.add_opt_simple(:pkeypath,'path to private key for JWT (wizard)')
96
+ self.options.add_opt_simple(:ascp_path,'path to ascp')
97
+ self.options.add_opt_simple(:use_product,'use ascp from specified product')
98
+ self.options.add_opt_simple(:smtp,'smtp configuration (extended value: hash)')
99
+ self.options.add_opt_simple(:fpac,'proxy auto configuration URL')
100
+ self.options.add_opt_simple(:preset,'-PVALUE','load the named option preset from current config file')
101
+ self.options.add_opt_simple(:default,'set as default configuration for specified plugin')
102
+ self.options.add_opt_simple(:secret,'default secret')
103
+ self.options.add_opt_simple(:secrets,'secret repository (Hash)')
104
+ self.options.add_opt_simple(:sdk_url,'URL to get SDK')
105
+ self.options.add_opt_simple(:sdk_folder,'SDK folder location')
106
+ self.options.add_opt_boolean(:test_mode,'skip user validation in wizard mode')
107
+ self.options.add_opt_simple(:version_check_days,Integer,'period to check neew version in days (zero to disable)')
109
108
  self.options.set_option(:use_generic_client,true)
110
109
  self.options.set_option(:test_mode,false)
110
+ self.options.set_option(:version_check_days,7)
111
+ self.options.set_option(:sdk_url,TRANSFER_SDK_ARCHIVE_URL)
112
+ self.options.set_option(:sdk_folder,File.join(@main_folder,'sdk'))
111
113
  self.options.parse_options!
112
- raise CliBadArgument,"secrets shall be Hash" unless @option_secrets.is_a?(Hash)
114
+ raise CliBadArgument,'secrets shall be Hash' unless @agents[:secret].all_secrets.is_a?(Hash)
115
+ Fasp::Installation.instance.folder=self.options.get_option(:sdk_folder,:mandatory)
113
116
  end
114
117
 
115
- def get_secret(id=nil,mandatory=true)
116
- secret=self.options.get_option(:secret,:optional) || @option_secrets[id]
117
- raise "please provide secret for #{id}" if secret.nil? and mandatory
118
- return secret
118
+ def check_gem_version
119
+ this_gem_name=File.basename(File.dirname(self.class.gem_root)).gsub(/-[0-9].*$/,'')
120
+ latest_version=begin
121
+ Rest.new(base_url: 'https://rubygems.org/api/v1').read("versions/#{this_gem_name}/latest.json")[:data]['version']
122
+ rescue
123
+ Log.log.warn('Could not retrieve latest gem version on rubygems.')
124
+ '0'
125
+ end
126
+ return {name: this_gem_name, current: Aspera::Cli::VERSION, latest: latest_version, need_update: Gem::Version.new(Aspera::Cli::VERSION) < Gem::Version.new(latest_version)}
119
127
  end
120
128
 
121
- def get_secrets
122
- return @option_secrets
129
+ def periodic_check_newer_gem_version
130
+ # get verification period
131
+ delay_days=options.get_option(:version_check_days,:mandatory)
132
+ Log.log.info("check days: #{delay_days}")
133
+ # check only if not zero day
134
+ if !delay_days.eql?(0)
135
+ # get last date from persistency
136
+ last_check_array=[]
137
+ check_date_persist=PersistencyActionOnce.new(
138
+ manager: persistency,
139
+ data: last_check_array,
140
+ ids: ['version_last_check'])
141
+ # get persisted date or nil
142
+ last_check_date = begin
143
+ Date.strptime(last_check_array.first, '%Y/%m/%d')
144
+ rescue
145
+ nil
146
+ end
147
+ current_date=Date.today
148
+ Log.log.debug("days elapsed: #{last_check_date.is_a?(Date) ? current_date - last_check_date : last_check_date.class.name}")
149
+ if last_check_date.nil? or (current_date - last_check_date) > delay_days
150
+ last_check_array[0]=current_date.strftime('%Y/%m/%d')
151
+ check_date_persist.save
152
+ check_data=check_gem_version
153
+ if check_data[:need_update]
154
+ Log.log.warn("A new version is available: #{check_data[:latest]}. You have #{check_data[:current]}. Upgrade with: gem update #{check_data[:name]}")
155
+ end
156
+ end
157
+ end
123
158
  end
124
159
 
125
160
  # retrieve structure from cloud (CDN) with all versions available
@@ -155,7 +190,7 @@ module Aspera
155
190
  require 'openssl'
156
191
  priv_key = OpenSSL::PKey::RSA.new(4096)
157
192
  File.write(private_key_path,priv_key.to_s)
158
- File.write(private_key_path+".pub",priv_key.public_key.to_s)
193
+ File.write(private_key_path+'.pub',priv_key.public_key.to_s)
159
194
  nil
160
195
  end
161
196
 
@@ -181,7 +216,7 @@ module Aspera
181
216
  r=[]
182
217
  t.each do |k,v|
183
218
  v.each do |kk,vv|
184
- r.push({"config"=>k,"parameter"=>kk,"value"=>vv})
219
+ r.push({'config'=>k,'parameter'=>kk,'value'=>vv})
185
220
  end
186
221
  end
187
222
  return r
@@ -191,12 +226,12 @@ module Aspera
191
226
  # creates one if none already created
192
227
  # @return preset that contains global default
193
228
  def set_global_default(key,value)
194
- global_default_preset_name=get_plugin_default_config_name(CONF_GLOBAL_SYM)
195
- if global_default_preset_name.nil?
196
- global_default_preset_name='global_common_defaults'
197
- @config_presets[global_default_preset_name]={}
198
- end
229
+ # get default preset if it exists
230
+ global_default_preset_name=get_plugin_default_config_name(CONF_GLOBAL_SYM) || CONF_PRESET_GLOBAL
231
+ @config_presets[global_default_preset_name]||={}
199
232
  @config_presets[global_default_preset_name][key.to_s]=value
233
+ self.format.display_status("Updated: #{global_default_preset_name}: #{key} <- #{value}")
234
+ save_presets_to_config_file
200
235
  return global_default_preset_name
201
236
  end
202
237
 
@@ -215,7 +250,7 @@ module Aspera
215
250
  # @return the hash from name (also expands possible includes)
216
251
  def preset_by_name(config_name, include_path=[])
217
252
  raise CliError,"no such config preset: #{config_name}" unless @config_presets.has_key?(config_name)
218
- raise CliError,"loop in include" if include_path.include?(config_name)
253
+ raise CliError,'loop in include' if include_path.include?(config_name)
219
254
  return expanded_with_preset_includes(@config_presets[config_name],include_path.clone.push(config_name))
220
255
  end
221
256
 
@@ -250,7 +285,7 @@ module Aspera
250
285
  end
251
286
 
252
287
  def option_use_product
253
- "write-only value"
288
+ 'write-only value'
254
289
  end
255
290
 
256
291
  def convert_preset_path(old_name,new_name,files_to_copy)
@@ -294,22 +329,21 @@ module Aspera
294
329
  # if no file found, create default config
295
330
  if conf_file_to_load.nil?
296
331
  Log.log.warn("No config file found. Creating empty configuration file: #{@option_config_file}")
297
- @config_presets={CONF_PRESET_CONFIG=>{CONF_PRESET_VERSION=>@program_version},CONF_PRESET_DEFAULT=>{'server'=>'demoserver'},
298
- 'demoserver'=>{'url'=>'ssh://'+DEMO+'.asperasoft.com:33001','username'=>AOC_COMMAND_V2,'ssAP'.downcase.reverse+'drow'.reverse=>DEMO+AOC_COMMAND_V2}}
332
+ @config_presets={CONF_PRESET_CONFIG=>{CONF_PRESET_VERSION=>@program_version}}
299
333
  else
300
334
  Log.log.debug "loading #{@option_config_file}"
301
335
  @config_presets=YAML.load_file(conf_file_to_load)
302
336
  end
303
337
  files_to_copy=[]
304
338
  Log.log.debug "Available_presets: #{@config_presets}"
305
- raise "Expecting YAML Hash" unless @config_presets.is_a?(Hash)
339
+ raise 'Expecting YAML Hash' unless @config_presets.is_a?(Hash)
306
340
  # check there is at least the config section
307
341
  if !@config_presets.has_key?(CONF_PRESET_CONFIG)
308
342
  raise "Cannot find key: #{CONF_PRESET_CONFIG}"
309
343
  end
310
344
  version=@config_presets[CONF_PRESET_CONFIG][CONF_PRESET_VERSION]
311
345
  if version.nil?
312
- raise "No version found in config section."
346
+ raise 'No version found in config section.'
313
347
  end
314
348
  # oldest compatible conf file format, update to latest version when an incompatible change is made
315
349
  # check compatibility of version of conf file
@@ -338,24 +372,24 @@ module Aspera
338
372
  end
339
373
  # Place new compatibility code here
340
374
  if save_required
341
- Log.log.warn("Saving automatic conversion.")
375
+ Log.log.warn('Saving automatic conversion.')
342
376
  @config_presets[CONF_PRESET_CONFIG][CONF_PRESET_VERSION]=@program_version
343
377
  save_presets_to_config_file
344
- Log.log.warn("Copying referenced files")
378
+ Log.log.warn('Copying referenced files')
345
379
  files_to_copy.each do |file|
346
380
  FileUtils.cp(file,@main_folder)
347
381
  Log.log.warn("..#{file} -> #{@main_folder}")
348
382
  end
349
383
  end
350
384
  rescue Psych::SyntaxError => e
351
- Log.log.error("YAML error in config file")
385
+ Log.log.error('YAML error in config file')
352
386
  raise e
353
387
  rescue => e
354
388
  Log.log.debug("-> #{e}")
355
389
  new_name="#{@option_config_file}.pre#{@program_version}.manual_conversion_needed"
356
390
  File.rename(@option_config_file,new_name)
357
391
  Log.log.warn("Renamed config file to #{new_name}.")
358
- Log.log.warn("Manual Conversion is required. Next time, a new empty file will be created.")
392
+ Log.log.warn('Manual Conversion is required. Next time, a new empty file will be created.')
359
393
  raise CliError,e.to_s
360
394
  end
361
395
  end
@@ -420,10 +454,10 @@ module Aspera
420
454
  fileurl = one_link['href']
421
455
  filename=fileurl.gsub(%r{.*/},'')
422
456
  api_connect_cdn.call({:operation=>'GET',:subpath=>fileurl,:save_to_file=>File.join(folder_dest,filename)})
423
- return Main.result_status("downloaded: #{filename}")
457
+ return Main.result_status("Downloaded: #{filename}")
424
458
  when :open #
425
459
  OpenApplication.instance.uri(one_link['href'])
426
- return Main.result_status("opened: #{one_link['href']}")
460
+ return Main.result_status("Opened: #{one_link['href']}")
427
461
  end
428
462
  end
429
463
  end
@@ -436,24 +470,24 @@ module Aspera
436
470
  when :connect
437
471
  return execute_connect_action
438
472
  when :use
439
- default_ascp=self.options.get_next_argument('path to ascp')
440
- raise "file name must be ascp" unless File.basename(default_ascp).eql?('ascp')
441
- raise "no such file: #{default_ascp}" unless File.exist?(default_ascp)
442
- raise "not executable: #{default_ascp}" unless File.executable?(default_ascp)
443
- preset_name=set_global_default(:ascp_path,default_ascp)
444
- save_presets_to_config_file
445
- return {:type=>:status, :data=>"saved to default global preset #{preset_name}"}
473
+ ascp_path=self.options.get_next_argument('path to ascp')
474
+ ascp_version=Fasp::Installation.instance.get_ascp_version(ascp_path)
475
+ self.format.display_status("ascp version: #{ascp_version}")
476
+ preset_name=set_global_default(:ascp_path,ascp_path)
477
+ return Main.result_status("Saved to default global preset #{preset_name}")
446
478
  when :show # shows files used
447
479
  return {:type=>:status, :data=>Fasp::Installation.instance.path(:ascp)}
448
480
  when :info # shows files used
449
481
  data=Fasp::Installation::FILES.inject({}) do |m,v|
450
- m[v.to_s]=Fasp::Installation.instance.path(v) rescue "Not Found"
482
+ m[v.to_s]=Fasp::Installation.instance.path(v) rescue 'Not Found'
451
483
  m
452
484
  end
453
485
  # read PATHs from ascp directly, and pvcl modules as well
454
486
  Open3.popen3(Fasp::Installation.instance.path(:ascp),'-DDL-') do |stdin, stdout, stderr, thread|
487
+ last_line=''
455
488
  while line=stderr.gets do
456
489
  line.chomp!
490
+ last_line=line
457
491
  case line
458
492
  when %r{^DBG Path ([^ ]+) (dir|file) +: (.*)$};data[$1]=$3
459
493
  when %r{^DBG Added module group:"([^"]+)" name:"([^"]+)", version:"([^"]+)" interface:"([^"]+)"$};data[$2]=$4
@@ -462,6 +496,9 @@ module Aspera
462
496
  when %r{^LOG Initializing FASP version ([^,]+),};data['ascp_version']=$1
463
497
  end
464
498
  end
499
+ if !thread.value.exitstatus.eql?(1) and !data.has_key?('root')
500
+ raise last_line
501
+ end
465
502
  end
466
503
  data['keypass']=Fasp::Installation.instance.bypass_pass
467
504
  return {:type=>:single_object, :data=>data}
@@ -474,17 +511,16 @@ module Aspera
474
511
  default_product=self.options.get_next_argument('product name')
475
512
  Fasp::Installation.instance.use_ascp_from_product(default_product)
476
513
  preset_name=set_global_default(:ascp_path,Fasp::Installation.instance.path(:ascp))
477
- save_presets_to_config_file
478
- return {:type=>:status, :data=>"saved to default global preset #{preset_name}"}
514
+ return Main.result_status("Saved to default global preset #{preset_name}")
479
515
  end
480
516
  when :install
481
- v=Fasp::Installation.instance.install_sdk
482
- return {:type=>:status, :data=>"Installed version #{v}"}
517
+ v=Fasp::Installation.instance.install_sdk(self.options.get_option(:sdk_url,:mandatory))
518
+ return Main.result_status("Installed version #{v}")
483
519
  end
484
520
  raise "unexpected case: #{command}"
485
521
  end
486
522
 
487
- ACTIONS=[:gem_path, :genkey,:plugins,:flush_tokens,:list,:overview,:open,:echo,:id,:documentation,:wizard,:export_to_cli,:detect,:coffee,:ascp,:email_test,:smtp_settings,:proxy_check,:folder,:file]
523
+ ACTIONS=[:gem_path, :genkey,:plugins,:flush_tokens,:list,:overview,:open,:echo,:id,:documentation,:wizard,:export_to_cli,:detect,:coffee,:ascp,:email_test,:smtp_settings,:proxy_check,:folder,:file,:check_update,:initdemo]
488
524
 
489
525
  # "config" plugin
490
526
  def execute_action
@@ -503,7 +539,7 @@ module Aspera
503
539
  when :delete
504
540
  @config_presets.delete(config_name)
505
541
  save_presets_to_config_file
506
- return Main.result_status("deleted: #{config_name}")
542
+ return Main.result_status("Deleted: #{config_name}")
507
543
  when :get
508
544
  param_name=self.options.get_next_argument('parameter name')
509
545
  value=selected_preset[param_name]
@@ -516,7 +552,7 @@ module Aspera
516
552
  param_name=self.options.get_next_argument('parameter name')
517
553
  selected_preset.delete(param_name)
518
554
  save_presets_to_config_file
519
- return Main.result_status("removed: #{config_name}: #{param_name}")
555
+ return Main.result_status("Removed: #{config_name}: #{param_name}")
520
556
  when :set
521
557
  param_name=self.options.get_next_argument('parameter name')
522
558
  param_value=self.options.get_next_argument('parameter value')
@@ -529,7 +565,7 @@ module Aspera
529
565
  end
530
566
  selected_preset[param_name]=param_value
531
567
  save_presets_to_config_file
532
- return Main.result_status("updated: #{config_name}: #{param_name} <- #{param_value}")
568
+ return Main.result_status("Updated: #{config_name}: #{param_name} <- #{param_value}")
533
569
  when :initialize
534
570
  config_value=self.options.get_next_argument('extended value (Hash)')
535
571
  if @config_presets.has_key?(config_name)
@@ -537,7 +573,7 @@ module Aspera
537
573
  end
538
574
  @config_presets[config_name]=config_value
539
575
  save_presets_to_config_file
540
- return Main.result_status("modified: #{@option_config_file}")
576
+ return Main.result_status("Modified: #{@option_config_file}")
541
577
  when :update
542
578
  default_for_plugin=self.options.get_option(:default,:optional)
543
579
  # get unprocessed options
@@ -550,7 +586,7 @@ module Aspera
550
586
  @config_presets[CONF_PRESET_DEFAULT][default_for_plugin]=config_name
551
587
  end
552
588
  save_presets_to_config_file
553
- return Main.result_status("updated: #{config_name}")
589
+ return Main.result_status("Updated: #{config_name}")
554
590
  when :ask
555
591
  self.options.ask_missing_mandatory=:yes
556
592
  @config_presets[config_name]||={}
@@ -559,10 +595,12 @@ module Aspera
559
595
  @config_presets[config_name][optionname]=option_value
560
596
  end
561
597
  save_presets_to_config_file
562
- return Main.result_status("updated: #{config_name}")
598
+ return Main.result_status("Updated: #{config_name}")
563
599
  end
564
600
  when :documentation
565
- OpenApplication.instance.uri(@help_url)
601
+ section=options.get_next_argument('private key file path',:single,:optional)
602
+ section='#'+section unless section.nil?
603
+ OpenApplication.instance.uri("#{@help_url}#{section}")
566
604
  return Main.result_nothing
567
605
  when :open
568
606
  OpenApplication.instance.uri("#{@option_config_file}") #file://
@@ -570,9 +608,9 @@ module Aspera
570
608
  when :genkey # generate new rsa key
571
609
  private_key_path=self.options.get_next_argument('private key file path')
572
610
  generate_new_key(private_key_path)
573
- return Main.result_status('generated key: '+private_key_path)
611
+ return Main.result_status('Generated key: '+private_key_path)
574
612
  when :echo # display the content of a value given on command line
575
- result={:type=>:other_struct, :data=>self.options.get_next_argument("value")}
613
+ result={:type=>:other_struct, :data=>self.options.get_next_argument('value')}
576
614
  # special for csv
577
615
  result[:type]=:object_list if result[:data].is_a?(Array) and result[:data].first.is_a?(Hash)
578
616
  return result
@@ -587,14 +625,13 @@ module Aspera
587
625
  return {:type=>:object_list,:data=>self.class.flatten_all_config(@config_presets)}
588
626
  when :wizard
589
627
  self.options.ask_missing_mandatory=true
590
- #self.options.set_option(:interactive,:yes)
591
628
  # register url option
592
629
  BasicAuthPlugin.new(@agents.merge(skip_option_header: true))
593
630
  instance_url=self.options.get_option(:url,:mandatory)
594
631
  appli=ApiDetector.discover_product(instance_url)
595
632
  case appli[:product]
596
633
  when :aoc
597
- self.format.display_status("Detected: Aspera on Cloud".bold)
634
+ self.format.display_status('Detected: Aspera on Cloud'.bold)
598
635
  organization,instance_domain=AoC.parse_url(instance_url)
599
636
  aspera_preset_name='aoc_'+organization
600
637
  self.format.display_status("Preparing preset: #{aspera_preset_name}")
@@ -608,7 +645,7 @@ module Aspera
608
645
  private_key_path=self.options.get_option(:pkeypath,:optional)
609
646
  # give a chance to provide
610
647
  if private_key_path.nil?
611
- self.format.display_status("Please provide path to your private RSA key, or empty to generate one:")
648
+ self.format.display_status('Please provide path to your private RSA key, or empty to generate one:')
612
649
  private_key_path=self.options.get_option(:pkeypath,:mandatory).to_s
613
650
  end
614
651
  # else generate path
@@ -616,69 +653,69 @@ module Aspera
616
653
  private_key_path=File.join(@main_folder,'aspera_aoc_key')
617
654
  end
618
655
  if File.exist?(private_key_path)
619
- self.format.display_status("Using existing key:")
656
+ self.format.display_status('Using existing key:')
620
657
  else
621
- self.format.display_status("Generating key...")
658
+ self.format.display_status('Generating key...')
622
659
  generate_new_key(private_key_path)
623
- self.format.display_status("Created:")
660
+ self.format.display_status('Created:')
624
661
  end
625
662
  self.format.display_status("#{private_key_path}")
626
663
  pub_key_pem=OpenSSL::PKey::RSA.new(File.read(private_key_path)).public_key.to_s
627
- # define options
664
+ # declare command line options for AoC
628
665
  require 'aspera/cli/plugins/aoc'
629
666
  # make username mandatory for jwt, this triggers interactive input
630
667
  self.options.get_option(:username,:mandatory)
631
- # instanciate AoC plugin
668
+ # instanciate AoC plugin, so that command line options are known
632
669
  files_plugin=self.class.plugin_new(AOC_COMMAND_CURRENT,@agents.merge({skip_basic_auth_options: true, private_key_path: private_key_path}))
670
+ aoc_api=files_plugin.get_api
633
671
  auto_set_pub_key=false
634
672
  auto_set_jwt=false
635
673
  use_browser_authentication=false
636
674
  if self.options.get_option(:use_generic_client)
637
- self.format.display_status("Using global client_id.")
638
- self.format.display_status("Please Login to your Aspera on Cloud instance.".red)
639
- self.format.display_status("Navigate to your \"Account Settings\"".red)
640
- self.format.display_status("Check or update the value of \"Public Key\" to be:".red.blink)
675
+ self.format.display_status('Using global client_id.')
676
+ self.format.display_status('Please Login to your Aspera on Cloud instance.'.red)
677
+ self.format.display_status('Navigate to your "Account Settings"'.red)
678
+ self.format.display_status('Check or update the value of "Public Key" to be:'.red.blink)
641
679
  self.format.display_status("#{pub_key_pem}")
642
680
  if ! self.options.get_option(:test_mode)
643
- self.format.display_status("Once updated or validated, press enter.")
681
+ self.format.display_status('Once updated or validated, press enter.')
644
682
  OpenApplication.instance.uri(instance_url)
645
683
  STDIN.gets
646
684
  end
647
685
  else
648
- self.format.display_status("Using organization specific client_id.")
686
+ self.format.display_status('Using organization specific client_id.')
649
687
  if self.options.get_option(:client_id,:optional).nil? or self.options.get_option(:client_secret,:optional).nil?
650
- self.format.display_status("Please login to your Aspera on Cloud instance.".red)
651
- self.format.display_status("Go to: Apps->Admin->Organization->Integrations")
652
- self.format.display_status("Create or check if there is an existing integration named:")
688
+ self.format.display_status('Please login to your Aspera on Cloud instance.'.red)
689
+ self.format.display_status('Go to: Apps->Admin->Organization->Integrations')
690
+ self.format.display_status('Create or check if there is an existing integration named:')
653
691
  self.format.display_status("- name: #{@tool_name}")
654
692
  self.format.display_status("- redirect uri: #{DEFAULT_REDIRECT}")
655
- self.format.display_status("- origin: localhost")
656
- self.format.display_status("Once created or identified,")
657
- self.format.display_status("Please enter:".red)
693
+ self.format.display_status('- origin: localhost')
694
+ self.format.display_status('Once created or identified,')
695
+ self.format.display_status('Please enter:'.red)
658
696
  end
659
- OpenApplication.instance.uri(instance_url+"/admin/org/integrations")
697
+ OpenApplication.instance.uri("#{instance_url}/#{AOC_PATH_API_CLIENTS}")
660
698
  self.options.get_option(:client_id,:mandatory)
661
699
  self.options.get_option(:client_secret,:mandatory)
662
700
  use_browser_authentication=true
663
701
  end
664
702
  if use_browser_authentication
665
- self.format.display_status("We will use web authentication to bootstrap.")
666
- self.options.set_option(:auth,:web)
667
- self.options.set_option(:redirect_uri,DEFAULT_REDIRECT)
703
+ self.format.display_status('We will use web authentication to bootstrap.')
668
704
  auto_set_pub_key=true
669
705
  auto_set_jwt=true
670
- self.options.set_option(:scope,AoC::SCOPE_FILES_ADMIN)
706
+ @api_aoc.oauth.params[:auth]=:web
707
+ @api_aoc.oauth.params[:redirect_uri]=DEFAULT_REDIRECT
708
+ @api_aoc.oauth.params[:scope]=AoC::SCOPE_FILES_ADMIN
671
709
  end
672
- files_plugin.update_aoc_api
673
- myself=files_plugin.api_aoc.read('self')[:data]
710
+ myself=aoc_api.read('self')[:data]
674
711
  if auto_set_pub_key
675
- raise CliError,"public key is already set in profile (use --override=yes)" unless myself['public_key'].empty? or option_override
676
- self.format.display_status("Updating profile with new key")
677
- files_plugin.api_aoc.update("users/#{myself['id']}",{'public_key'=>pub_key_pem})
712
+ raise CliError,'public key is already set in profile (use --override=yes)' unless myself['public_key'].empty? or option_override
713
+ self.format.display_status('Updating profile with new key')
714
+ aoc_api.update("users/#{myself['id']}",{'public_key'=>pub_key_pem})
678
715
  end
679
716
  if auto_set_jwt
680
- self.format.display_status("Enabling JWT for client")
681
- files_plugin.api_aoc.update("clients/#{self.options.get_option(:client_id)}",{'jwt_grant_enabled'=>true,'explicit_authorization_required'=>false})
717
+ self.format.display_status('Enabling JWT for client')
718
+ aoc_api.update("clients/#{self.options.get_option(:client_id)}",{'jwt_grant_enabled'=>true,'explicit_authorization_required'=>false})
682
719
  end
683
720
  self.format.display_status("creating new config preset: #{aspera_preset_name}")
684
721
  @config_presets[aspera_preset_name]={
@@ -694,14 +731,14 @@ module Aspera
694
731
  end
695
732
  self.format.display_status("Setting config preset as default for #{AOC_COMMAND_CURRENT}")
696
733
  @config_presets[CONF_PRESET_DEFAULT][AOC_COMMAND_CURRENT]=aspera_preset_name
697
- self.format.display_status("saving config file")
734
+ self.format.display_status('saving config file')
698
735
  save_presets_to_config_file
699
736
  return Main.result_status("Done.\nYou can test with:\n#{@tool_name} #{AOC_COMMAND_CURRENT} user info show")
700
737
  else
701
738
  raise CliBadArgument,"Supports only: aoc. Detected: #{appli}"
702
739
  end
703
740
  when :export_to_cli
704
- self.format.display_status("Exporting: Aspera on Cloud")
741
+ self.format.display_status('Exporting: Aspera on Cloud')
705
742
  require 'aspera/cli/plugins/aoc'
706
743
  # need url / username
707
744
  add_plugin_default_preset(AOC_COMMAND_V3.to_sym)
@@ -734,11 +771,11 @@ module Aspera
734
771
  entry.merge!(new_conf)
735
772
  end
736
773
  File.write(cli_conf_file,JSON.pretty_generate(data))
737
- return Main.result_status("updated: #{cli_conf_file}")
774
+ return Main.result_status("Updated: #{cli_conf_file}")
738
775
  when :detect
739
776
  # need url / username
740
777
  BasicAuthPlugin.new(@agents)
741
- return Main.result_status("found: #{ApiDetector.discover_product(self.options.get_option(:url,:mandatory))}")
778
+ return Main.result_status("Found: #{ApiDetector.discover_product(self.options.get_option(:url,:mandatory))}")
742
779
  when :coffee
743
780
  OpenApplication.instance.uri('https://enjoyjava.com/wp-content/uploads/2018/01/How-to-make-strong-coffee.jpg')
744
781
  return Main.result_nothing
@@ -751,7 +788,7 @@ module Aspera
751
788
  when :file
752
789
  return Main.result_status(@option_config_file)
753
790
  when :email_test
754
- dest_email=self.options.get_next_argument("destination email")
791
+ dest_email=self.options.get_next_argument('destination email')
755
792
  send_email({
756
793
  to: dest_email,
757
794
  subject: 'Amelia email test',
@@ -762,9 +799,28 @@ module Aspera
762
799
  return {:type=>:single_object,:data=>email_settings}
763
800
  when :proxy_check
764
801
  pac_url=self.options.get_option(:fpac,:mandatory)
765
- server_url=self.options.get_next_argument("server url")
802
+ server_url=self.options.get_next_argument('server url')
766
803
  return Main.result_status(Aspera::ProxyAutoConfig.new(UriReader.read(pac_url)).get_proxy(server_url))
767
- else raise "error"
804
+ when :check_update
805
+ return {:type=>:single_object, :data=>check_gem_version}
806
+ when :initdemo
807
+ if @config_presets.has_key?(DEMO_SERVER_PRESET)
808
+ Log.log.warn("Demo server preset already present: #{DEMO_SERVER_PRESET}")
809
+ else
810
+ Log.log.info("Creating Demo server preset: #{DEMO_SERVER_PRESET}")
811
+ @config_presets[DEMO_SERVER_PRESET]={'url'=>'ssh://'+DEMO+'.asperasoft.com:33001','username'=>AOC_COMMAND_V2,'ssAP'.downcase.reverse+'drow'.reverse=>DEMO+AOC_COMMAND_V2}
812
+ end
813
+ @config_presets[CONF_PRESET_DEFAULT]||={}
814
+ if @config_presets[CONF_PRESET_DEFAULT].has_key?('server')
815
+ Log.log.warn("server default preset already set to: #{@config_presets[CONF_PRESET_DEFAULT]['server']}")
816
+ Log.log.warn("use #{DEMO_SERVER_PRESET} for demo: -P#{DEMO_SERVER_PRESET}") unless DEMO_SERVER_PRESET.eql?(@config_presets[CONF_PRESET_DEFAULT]['server'])
817
+ else
818
+ @config_presets[CONF_PRESET_DEFAULT]['server']=DEMO_SERVER_PRESET
819
+ Log.log.info("setting server default preset to : #{DEMO_SERVER_PRESET}")
820
+ end
821
+ save_presets_to_config_file
822
+ return Main.result_status("Done")
823
+ else raise 'error'
768
824
  end
769
825
  end
770
826
 
@@ -812,7 +868,7 @@ END_OF_MESSAGE
812
868
  end
813
869
 
814
870
  def save_presets_to_config_file
815
- raise "no configuration loaded" if @config_presets.nil?
871
+ raise 'no configuration loaded' if @config_presets.nil?
816
872
  FileUtils.mkdir_p(@main_folder) unless Dir.exist?(@main_folder)
817
873
  Log.log.debug "writing #{@option_config_file}"
818
874
  File.write(@option_config_file,@config_presets.to_yaml)
@@ -823,7 +879,7 @@ END_OF_MESSAGE
823
879
  def get_plugin_default_config_name(plugin_sym)
824
880
  raise "internal error: config_presets shall be defined" if @config_presets.nil?
825
881
  if !@use_plugin_defaults
826
- Log.log.debug("skip default config")
882
+ Log.log.debug('skip default config')
827
883
  return nil
828
884
  end
829
885
  if @config_presets.has_key?(CONF_PRESET_DEFAULT) and