asperalm 0.8.9 → 0.8.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 28815454e807c413dac67c774100773380b2f157b33a2acdff7e7ae98a07cc03
4
- data.tar.gz: 01c769c6eeb3787232626261a9258d3cb6acf63b9b13b0dadcd6bca66fa98434
3
+ metadata.gz: 1c27eddfbfc538d221dec82b0afcb7943fce33887ccfb03f8d12f504d0bbf03e
4
+ data.tar.gz: 4c78e96a41a69314b94fe41c2869a463a515e37de8c51293d62ccf9557fca4fb
5
5
  SHA512:
6
- metadata.gz: 79ade6aa5fec5760a9ab59eec5e3aa18bf4aced0c9bb788425defc2421fc51f91d3510af939b9f317b3f320b3294b7c4d7036d38586d3abbe040a6036af91fe7
7
- data.tar.gz: 98bd4b6ea28438e56e0987f9871e2b267026f6b48316af63f8ed04f86af11d807e3bc934a63d4fbb5f77b6b4e8a66bc6c620d86114e497fc036f19da6abd46c4
6
+ metadata.gz: bfab0b8e7552254c511fc5765f17bda97cd7f2608b7e2e173f5a1196031fa27430a494f0ab06148c98bb2519c02cfcac915c62f6359d9632825699d1852e9ea2
7
+ data.tar.gz: 9f84387700cd9b71f2b837220a0dbc065f88bc7c997c0c828aa8ebe1ed54d36d83841ad2d0995ea598d6f3d4fb8c438446cd5f1f510e8a6e79031cf69a909fa9
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Asperalm - Laurent's Aspera Command Line Interface and Ruby Library
2
2
 
3
- Version : 0.8.9
3
+ Version : 0.8.10
4
4
 
5
5
 
6
6
  _Laurent/2016-2018_
@@ -35,7 +35,7 @@ Once the gem is installed, the `aslmcli` shall be accessible:
35
35
 
36
36
  ```bash
37
37
  $ aslmcli --version
38
- 0.8.9
38
+ 0.8.10
39
39
 
40
40
  ```
41
41
 
@@ -927,9 +927,9 @@ aslmcli server rm /Upload/123
927
927
  aslmcli server upload sample_file.bin --to-folder=/Upload
928
928
  aslmcli server upload source_hot --to-folder=/Upload/target_hot --lock-port=12345 --ts=@json:'{"EX_ascp_args":["--remove-after-transfer","--remove-empty-directories","--exclude-newer-than=-8","--src-base","source_hot"]}'
929
929
  aslmcli shares repository browse /
930
- aslmcli shares repository delete /n8-sh1/200KB.1
931
- aslmcli shares repository download /n8-sh1/200KB.1 --to-folder=sample_dest_folder
932
- aslmcli shares repository upload sample_file.bin --to-folder=/n8-sh1
930
+ aslmcli shares repository delete /$(TEST_SHARE)/200KB.1
931
+ aslmcli shares repository download /$(TEST_SHARE)/200KB.1 --to-folder=sample_dest_folder
932
+ aslmcli shares repository upload sample_file.bin --to-folder=/$(TEST_SHARE)
933
933
  aslmcli shares2 appinfo
934
934
  aslmcli shares2 organization list
935
935
  aslmcli shares2 project list --organization=Sport
@@ -945,7 +945,7 @@ aslmcli sync start --parameters=@json:'{"sessions":[{"name":"test","reset":true,
945
945
  ```bash
946
946
  $ aslmcli -h
947
947
  NAME
948
- aslmcli -- a command line tool for Aspera Applications (v0.8.9)
948
+ aslmcli -- a command line tool for Aspera Applications (v0.8.10)
949
949
 
950
950
  SYNOPSIS
951
951
  aslmcli COMMANDS [OPTIONS] [ARGS]
@@ -971,32 +971,38 @@ ARGS
971
971
  OPTIONS: global
972
972
  --interactive=ENUM use interactive input of missing params: yes, no
973
973
  --ask-options=ENUM ask even optional options: yes, no
974
- --config-file=VALUE read parameters from file in YAML format, current=/Users/laurent/.aspera/aslmcli/config.yaml
975
974
  --table-style=VALUE table display style, current=:.:
976
975
  -h, --help Show this message.
977
976
  --show-config Display parameters used for the provided action.
978
977
  -r, --rest-debug more debug for HTTP calls
979
- -N, --no-default do not load default configuration for plugin
980
978
  -v, --version display version
979
+ --config-file=VALUE read parameters from file in YAML format, current=/Users/laurent/.aspera/aslmcli/config.yaml
980
+ -N, --no-default do not load default configuration for plugin
981
981
  --ui=ENUM method to start browser: text, graphical
982
- --log-level=ENUM Log level: fatal, unknown, debug, info, warn, error
982
+ --log-level=ENUM Log level: error, fatal, unknown, debug, info, warn
983
983
  --logger=ENUM log method: stderr, stdout, syslog
984
984
  --format=ENUM output format: table, ruby, json, jsonpp, yaml, csv
985
- --transfer=ENUM type of transfer: direct, connect, node
986
985
  -P, --presetVALUE load the named option preset from current config file
987
- --transfer-node=VALUE name of configuration used to transfer when using --transfer=node
988
986
  --fields=VALUE comma separated list of fields, or ALL, or DEF
989
987
  --select=VALUE select only some items in lists, extended value: hash (colum, value)
990
988
  --fasp-proxy=VALUE URL of FASP proxy (dnat / dnats)
991
989
  --http-proxy=VALUE URL of HTTP proxy (for http fallback)
992
- --ts=VALUE override transfer spec values (Hash, use @json: prefix), current={}
993
- --to-folder=VALUE destination folder for downloaded files
994
990
  --lock-port=VALUE prevent dual execution of a command, e.g. in cron
995
991
  --use-product=VALUE which local product to use for ascp, current=FIRST
996
992
  --query=VALUE additional filter for API calls (extended value)
997
993
  --insecure=ENUM do not validate HTTPS certificate: yes, no
998
994
  --flat-hash=ENUM display hash values as additional keys: yes, no
999
995
  --override=ENUM override existing value: yes, no
996
+ --ts=VALUE override transfer spec values (Hash, use @json: prefix), current={}
997
+ --to-folder=VALUE destination folder for downloaded files
998
+ --transfer=ENUM type of transfer: direct, connect, node
999
+ --transfer-node=VALUE name of configuration used to transfer when using --transfer=node
1000
+
1001
+ COMMAND: config
1002
+ SUBCOMMANDS: todo
1003
+ OPTIONS:
1004
+ --config-file=VALUE read parameters from file in YAML format, current=/Users/laurent/.aspera/aslmcli/config.yaml
1005
+ -N, --no-default do not load default configuration for plugin
1000
1006
 
1001
1007
  COMMAND: shares
1002
1008
  SUBCOMMANDS: repository, admin
@@ -1 +1 @@
1
- 0.8.9
1
+ 0.8.10
@@ -1,11 +1,9 @@
1
1
  require 'asperalm/cli/manager'
2
- require 'asperalm/cli/plugin'
2
+ require 'asperalm/cli/plugins/config'
3
3
  require 'asperalm/cli/extended_value'
4
4
  require 'asperalm/cli/listener/logger'
5
5
  require 'asperalm/cli/listener/progress_multi'
6
- require 'asperalm/fasp/local'
7
- require 'asperalm/fasp/connect'
8
- require 'asperalm/fasp/node'
6
+ require 'asperalm/cli/transfer_agent'
9
7
  require 'asperalm/open_application'
10
8
  require 'asperalm/temp_file_manager'
11
9
  require 'asperalm/log'
@@ -20,7 +18,7 @@ require 'pp'
20
18
  module Asperalm
21
19
  module Cli
22
20
  # The main CLI class
23
- class Main < Plugin
21
+ class Main
24
22
  include Singleton
25
23
  # "tool" class method is an alias to "instance" of singleton
26
24
  singleton_class.send(:alias_method, :tool, :instance)
@@ -30,86 +28,35 @@ module Asperalm
30
28
 
31
29
  private
32
30
  # first level command for the main tool
33
- @@MAIN_PLUGIN_NAME_SYM=:config
31
+ @@CONFIG_PLUGIN_NAME_SYM=:config
34
32
  # name of application, also foldername where config is stored
35
33
  @@PROGRAM_NAME = 'aslmcli'
36
34
  @@GEM_NAME = 'asperalm'
37
- # folder in $HOME for application files (config, cache)
38
- @@ASPERA_HOME_FOLDER_NAME='.aspera'
39
35
  # folder containing custom plugins in `config_folder`
40
36
  @@ASPERA_PLUGINS_FOLDERNAME='plugins'
41
- # main config file
42
- @@DEFAULT_CONFIG_FILENAME = 'config.yaml'
43
37
  # folder containing plugins in the gem's main folder
44
38
  @@GEM_PLUGINS_FOLDER='asperalm/cli/plugins'
45
39
  # Container module of current class : Asperalm::Cli
46
40
  @@CLI_MODULE=Module.nesting[1].to_s
47
41
  # Path to Plugin classes: Asperalm::Cli::Plugins
48
42
  @@PLUGINS_MODULE=@@CLI_MODULE+'::Plugins'
49
- @@CONFIG_PRESET_VERSION='version'
50
- @@CONFIG_PRESET_DEFAULT='default'
51
- @@HELP_URL='http://www.rubydoc.info/gems/'+@@GEM_NAME
52
- @@GEM_URL='https://rubygems.org/gems/'+@@GEM_NAME
53
43
  RUBY_FILE_EXT='.rb'
54
44
  FIELDS_ALL='ALL'
55
45
  FIELDS_DEFAULT='DEF'
56
- ASPERA_PLUGIN_S=:aspera.to_s
57
46
 
58
47
  # find the root folder of gem where this class is
59
48
  def self.gem_root
60
49
  File.expand_path(@@CLI_MODULE.to_s.gsub('::','/').gsub(%r([^/]+),'..'),File.dirname(__FILE__))
61
50
  end
62
51
 
63
- def save_presets_to_config_file
64
- raise "no configuration loaded" if @available_presets.nil?
65
- FileUtils::mkdir_p(config_folder) unless Dir.exist?(config_folder)
66
- Log.log.debug "writing #{@option_config_file}"
67
- File.write(@option_config_file,@available_presets.to_yaml)
68
- end
69
-
70
- # returns name if @available_presets has default
71
- # returns nil if there is no config or bypass default params
72
- def get_plugin_default_config_name(plugin_sym)
73
- default_config_name=nil
74
- return nil if @available_presets.nil? or !@use_plugin_defaults
75
- if @available_presets.has_key?(@@CONFIG_PRESET_DEFAULT) and
76
- @available_presets[@@CONFIG_PRESET_DEFAULT].has_key?(plugin_sym.to_s)
77
- default_config_name=@available_presets[@@CONFIG_PRESET_DEFAULT][plugin_sym.to_s]
78
- if !@available_presets.has_key?(default_config_name)
79
- Log.log.error("Default config name [#{default_config_name}] specified for plugin [#{plugin_sym.to_s}], but it does not exist in config file.\nPlease fix the issue: either create preset with one parameter (aslmcli config id #{default_config_name} init @json:'{}') or remove default (aslmcli config id default remove #{plugin_sym.to_s}).")
80
- end
81
- raise CliError,"Config name [#{default_config_name}] must be a hash, check config file." if !@available_presets[default_config_name].is_a?(Hash)
82
- end
83
-
84
- return default_config_name
85
- end
86
-
87
- # returns default parameters for a plugin from loaded config file
88
- # try to find: conffile[conffile["default"][plugin_str]]
89
- def add_plugin_default_preset(plugin_sym)
90
- default_config_name=get_plugin_default_config_name(plugin_sym)
91
- Log.log.debug("add_plugin_default_preset:#{plugin_sym}:#{default_config_name}")
92
- return if default_config_name.nil?
93
- @opt_mgr.add_option_preset(@available_presets[default_config_name],:unshift)
94
- end
95
-
96
52
  # =============================================================
97
53
  # Parameter handlers
98
54
  #
99
- attr_accessor :option_override
100
55
 
101
56
  def option_insecure; Rest.insecure ; end
102
57
 
103
58
  def option_insecure=(value); Rest.insecure = value; end
104
59
 
105
- def option_transfer_spec; @transfer_spec_default; end
106
-
107
- def option_transfer_spec=(value); @transfer_spec_default.merge!(value); end
108
-
109
- def option_to_folder; @transfer_spec_default['destination_root']; end
110
-
111
- def option_to_folder=(value); @transfer_spec_default.merge!({'destination_root'=>value}); end
112
-
113
60
  def option_ui; OpenApplication.instance.url_method; end
114
61
 
115
62
  def option_ui=(value); OpenApplication.instance.url_method=value; end
@@ -117,16 +64,14 @@ module Asperalm
117
64
  def option_preset; nil; end
118
65
 
119
66
  def option_preset=(value)
120
- raise CliError,"no such preset defined: #{value}" unless @available_presets.has_key?(value)
121
- @opt_mgr.add_option_preset(@available_presets[value])
67
+ raise CliError,"no such preset defined: #{value}" unless config_presets.has_key?(value)
68
+ @opt_mgr.add_option_preset(config_presets[value])
122
69
  end
123
70
 
124
- # returns the list of plugins from plugin folder
125
- def plugin_sym_list
126
- return @plugins.keys
127
- end
71
+ attr_accessor :option_flat_hash
72
+ attr_accessor :option_table_style
128
73
 
129
- def action_list; plugin_sym_list; end
74
+ def config_presets; Plugins::Config.instance.config_presets; end
130
75
 
131
76
  # find plugins in defined paths
132
77
  def add_plugins_from_lookup_folders
@@ -141,92 +86,27 @@ module Asperalm
141
86
  end
142
87
  end
143
88
 
144
- # transfer agent singleton
145
- def transfer_manager
146
- if @transfer_manager_singleton.nil?
147
- # by default use local ascp
148
- case @opt_mgr.get_option(:transfer,:mandatory)
149
- when :direct
150
- @transfer_manager_singleton=Fasp::Local.instance
151
- if !@opt_mgr.get_option(:fasp_proxy,:optional).nil?
152
- @transfer_spec_default['EX_fasp_proxy_url']=@opt_mgr.get_option(:fasp_proxy,:optional)
153
- end
154
- if !@opt_mgr.get_option(:http_proxy,:optional).nil?
155
- @transfer_spec_default['EX_http_proxy_url']=@opt_mgr.get_option(:http_proxy,:optional)
156
- end
157
- # TODO: option to choose progress format
158
- # here we disable native stdout progress
159
- @transfer_manager_singleton.quiet=true
160
- Log.log.debug(">>>>#{@transfer_spec_default}".red)
161
- when :connect
162
- @transfer_manager_singleton=Fasp::Connect.instance
163
- when :node
164
- # support: @param:<name>
165
- # support extended values
166
- transfer_node_spec=@opt_mgr.get_option(:transfer_node,:optional)
167
- # of not specified, use default node
168
- case transfer_node_spec
169
- when nil
170
- param_set_name=get_plugin_default_config_name(:node)
171
- raise CliBadArgument,"No default node configured, Please specify --transfer-node" if param_set_name.nil?
172
- node_config=@available_presets[param_set_name]
173
- when /^@param:/
174
- param_set_name=transfer_node_spec.gsub!(/^@param:/,'')
175
- Log.log.debug("param_set_name=#{param_set_name}")
176
- raise CliBadArgument,"no such parameter set: [#{param_set_name}] in config file" if !@available_presets.has_key?(param_set_name)
177
- node_config=@available_presets[param_set_name]
178
- else
179
- node_config=ExtendedValue.parse(:transfer_node,transfer_node_spec)
180
- end
181
- Log.log.debug("node=#{node_config}")
182
- raise CliBadArgument,"the node configuration shall be a hash, use either @json:<json> or @param:<parameter set name>" if !node_config.is_a?(Hash)
183
- # now check there are required parameters
184
- sym_config={}
185
- [:url,:username,:password].each do |param|
186
- raise CliBadArgument,"missing parameter [#{param}] in node specification: #{node_config}" if !node_config.has_key?(param.to_s)
187
- sym_config[param]=node_config[param.to_s]
188
- end
189
- @transfer_manager_singleton=Fasp::Node.instance
190
- Fasp::Node.instance.node_api=Rest.new({:base_url=>sym_config[:url],:auth_type=>:basic,:basic_username=>sym_config[:username], :basic_password=>sym_config[:password]})
191
- else raise "ERROR"
192
- end
193
- @transfer_manager_singleton.add_listener(Listener::Logger.new)
194
- @transfer_manager_singleton.add_listener(Listener::ProgressMulti.new)
195
- end
196
- return @transfer_manager_singleton
197
- end
198
-
199
- attr_accessor :option_flat_hash
200
- attr_accessor :option_config_file
201
- attr_accessor :option_table_style
202
-
203
89
  # minimum initialization
204
90
  def initialize
205
91
  # overriding parameters on transfer spec
206
- @transfer_spec_default={}
207
92
  @option_help=false
208
93
  @option_show_config=false
209
94
  @option_flat_hash=true
210
- @available_presets=nil
211
- @transfer_manager_singleton=nil
212
- @use_plugin_defaults=true
213
- @plugins={@@MAIN_PLUGIN_NAME_SYM=>{:source=>__FILE__,:require_stanza=>nil}}
95
+ @plugins={@@CONFIG_PLUGIN_NAME_SYM=>{:source=>__FILE__,:require_stanza=>nil}}
214
96
  @plugin_lookup_folders=[]
215
- @config_folder=File.join(Dir.home,@@ASPERA_HOME_FOLDER_NAME,@@PROGRAM_NAME)
216
- @option_config_file=File.join(@config_folder,@@DEFAULT_CONFIG_FILENAME)
217
97
  @option_table_style=':.:'
98
+ @opt_mgr=Manager.new(@@PROGRAM_NAME)
99
+ # define program name, sets default config folder. Must be first call to "Config.instance"
100
+ Plugins::Config.instance.set_program_info(@@PROGRAM_NAME,@@GEM_NAME,self.class.gem_version)
101
+ Oauth.persistency_folder=config_folder
218
102
  # set folders for temp files
219
- Fasp::Parameters.file_list_folder=File.join(@config_folder,'filelists')
220
- Oauth.persistency_folder=@config_folder
221
- # option manager is created later
222
- @opt_mgr=nil
223
- add_plugin_lookup_folder(File.join(self.class.gem_root,@@GEM_PLUGINS_FOLDER))
103
+ Fasp::Parameters.file_list_folder=File.join(config_folder,'filelists')
224
104
  add_plugin_lookup_folder(File.join(config_folder,@@ASPERA_PLUGINS_FOLDERNAME))
105
+ add_plugin_lookup_folder(File.join(self.class.gem_root,@@GEM_PLUGINS_FOLDER))
225
106
  end
226
107
 
227
108
  # local options
228
- def create_opt_mgr
229
- @opt_mgr=Manager.new(@@PROGRAM_NAME)
109
+ def init_options
230
110
  @opt_mgr.parser.banner = "NAME\n\t#{@@PROGRAM_NAME} -- a command line tool for Aspera Applications (v#{self.class.gem_version})\n\n"
231
111
  @opt_mgr.parser.separator "SYNOPSIS"
232
112
  @opt_mgr.parser.separator "\t#{@@PROGRAM_NAME} COMMANDS [OPTIONS] [ARGS]"
@@ -234,11 +114,11 @@ module Asperalm
234
114
  @opt_mgr.parser.separator "DESCRIPTION"
235
115
  @opt_mgr.parser.separator "\tUse Aspera application to perform operations on command line."
236
116
  @opt_mgr.parser.separator "\tOAuth 2.0 is used for authentication in Files, Several authentication methods are provided."
237
- @opt_mgr.parser.separator "\tDocumentation and examples: #{@@GEM_URL}"
117
+ @opt_mgr.parser.separator "\tDocumentation and examples: #{Plugins::Config.instance.gem_url}"
238
118
  @opt_mgr.parser.separator "\texecute: #{@@PROGRAM_NAME} conf doc"
239
119
  @opt_mgr.parser.separator ""
240
120
  @opt_mgr.parser.separator "COMMANDS"
241
- @opt_mgr.parser.separator "\tFirst level commands: #{action_list.map {|x| x.to_s}.join(', ')}"
121
+ @opt_mgr.parser.separator "\tFirst level commands: #{@plugins.keys.map {|x| x.to_s}.join(', ')}"
242
122
  @opt_mgr.parser.separator "\tNote that commands can be written shortened (provided it is unique)."
243
123
  @opt_mgr.parser.separator ""
244
124
  @opt_mgr.parser.separator "OPTIONS"
@@ -251,25 +131,19 @@ module Asperalm
251
131
  @opt_mgr.parser.separator ""
252
132
  @opt_mgr.parser.separator "OPTIONS: global"
253
133
  @opt_mgr.declare_options_scan_env
254
- @opt_mgr.set_obj_attr(:config_file,self,:option_config_file)
255
134
  @opt_mgr.set_obj_attr(:table_style,self,:option_table_style)
256
- @opt_mgr.add_opt_simple(:config_file,"read parameters from file in YAML format, current=#{@option_config_file}")
257
135
  @opt_mgr.add_opt_simple(:table_style,"table display style, current=#{@option_table_style}")
258
136
  @opt_mgr.add_opt_switch(:help,"Show this message.","-h") { @option_help=true }
259
137
  @opt_mgr.add_opt_switch(:show_config, "Display parameters used for the provided action.") { @option_show_config=true }
260
138
  @opt_mgr.add_opt_switch(:rest_debug,"-r","more debug for HTTP calls") { Rest.debug=true }
261
- @opt_mgr.add_opt_switch(:no_default,"-N","do not load default configuration for plugin") { @use_plugin_defaults=false }
262
139
  @opt_mgr.add_opt_switch(:version,"-v","display version") { puts self.class.gem_version;Process.exit(0) }
263
140
  end
264
141
 
265
- def declare_options
142
+ def declare_global_options
266
143
  # handler must be set before declaration
267
144
  @opt_mgr.set_obj_attr(:log_level,Log.instance,:level)
268
145
  @opt_mgr.set_obj_attr(:insecure,self,:option_insecure,:no)
269
- @opt_mgr.set_obj_attr(:override,self,:option_override,:no)
270
146
  @opt_mgr.set_obj_attr(:flat_hash,self,:option_flat_hash)
271
- @opt_mgr.set_obj_attr(:ts,self,:option_transfer_spec)
272
- @opt_mgr.set_obj_attr(:to_folder,self,:option_to_folder)
273
147
  @opt_mgr.set_obj_attr(:logger,Log.instance,:logger_type)
274
148
  @opt_mgr.set_obj_attr(:ui,self,:option_ui)
275
149
  @opt_mgr.set_obj_attr(:preset,self,:option_preset)
@@ -279,15 +153,11 @@ module Asperalm
279
153
  @opt_mgr.add_opt_list(:log_level,Log.levels,"Log level")
280
154
  @opt_mgr.add_opt_list(:logger,Log.logtypes,"log method")
281
155
  @opt_mgr.add_opt_list(:format,self.class.display_formats,"output format")
282
- @opt_mgr.add_opt_list(:transfer,[:direct,:connect,:node],"type of transfer")
283
156
  @opt_mgr.add_opt_simple(:preset,"-PVALUE","load the named option preset from current config file")
284
- @opt_mgr.add_opt_simple(:transfer_node,"name of configuration used to transfer when using --transfer=node")
285
157
  @opt_mgr.add_opt_simple(:fields,"comma separated list of fields, or #{FIELDS_ALL}, or #{FIELDS_DEFAULT}")
286
158
  @opt_mgr.add_opt_simple(:select,"select only some items in lists, extended value: hash (colum, value)")
287
159
  @opt_mgr.add_opt_simple(:fasp_proxy,"URL of FASP proxy (dnat / dnats)")
288
160
  @opt_mgr.add_opt_simple(:http_proxy,"URL of HTTP proxy (for http fallback)")
289
- @opt_mgr.add_opt_simple(:ts,"override transfer spec values (Hash, use @json: prefix), current=#{@opt_mgr.get_option(:ts,:optional)}")
290
- @opt_mgr.add_opt_simple(:to_folder,"destination folder for downloaded files")
291
161
  @opt_mgr.add_opt_simple(:lock_port,"prevent dual execution of a command, e.g. in cron")
292
162
  @opt_mgr.add_opt_simple(:use_product,"which local product to use for ascp, current=#{Fasp::Installation.instance.activated}")
293
163
  @opt_mgr.add_opt_simple(:query,"additional filter for API calls (extended value)")
@@ -297,16 +167,27 @@ module Asperalm
297
167
 
298
168
  @opt_mgr.set_option(:ui,OpenApplication.default_gui_mode)
299
169
  @opt_mgr.set_option(:fields,FIELDS_DEFAULT)
300
- @opt_mgr.set_option(:transfer,:direct)
301
170
  @opt_mgr.set_option(:format,:table)
302
171
  end
303
172
 
304
- # plugin_name_sym is symbol
305
- # loads default parameters if no -P parameter
306
- def get_plugin_instance(plugin_name_sym)
307
- Log.log.debug("get_plugin_instance -> #{plugin_name_sym}")
173
+ # loads default parameters of plugin if no -P parameter
174
+ # and if there is a section defined for the plugin in the "default" section
175
+ # try to find: conffile[conffile["default"][plugin_str]]
176
+ # @param plugin_name_sym : symbol for plugin name
177
+ def add_plugin_default_preset(plugin_name_sym)
178
+ default_config_name=Plugins::Config.instance.get_plugin_default_config_name(plugin_name_sym)
179
+ Log.log.debug("add_plugin_default_preset:#{plugin_name_sym}:#{default_config_name}")
180
+ @opt_mgr.add_option_preset(config_presets[default_config_name],:unshift) unless default_config_name.nil?
181
+ return nil
182
+ end
183
+
184
+ # @return the plugin instance, based on name
185
+ # also loads the plugin options, and default values from conf file
186
+ # @param plugin_name_sym : symbol for plugin name
187
+ def get_plugin_instance_with_options(plugin_name_sym)
188
+ Log.log.debug("get_plugin_instance_with_options -> #{plugin_name_sym}")
308
189
  require @plugins[plugin_name_sym][:require_stanza]
309
- command_plugin=Object::const_get(@@PLUGINS_MODULE+'::'+plugin_name_sym.to_s.capitalize).new()
190
+ command_plugin=Object::const_get(@@PLUGINS_MODULE+'::'+plugin_name_sym.to_s.capitalize).instance
310
191
  # TODO: check that ancestor is Plugin?
311
192
  @opt_mgr.parser.separator "COMMAND: #{plugin_name_sym}"
312
193
  @opt_mgr.parser.separator "SUBCOMMANDS: #{command_plugin.action_list.map{ |p| p.to_s}.join(', ')}"
@@ -317,16 +198,6 @@ module Asperalm
317
198
  return command_plugin
318
199
  end
319
200
 
320
- def self.flatten_all_config(t)
321
- r=[]
322
- t.each do |k,v|
323
- v.each do |kk,vv|
324
- r.push({"config"=>k,"parameter"=>kk,"value"=>vv})
325
- end
326
- end
327
- return r
328
- end
329
-
330
201
  # @param source [Hash] hash to modify
331
202
  # @param keep_last [bool]
332
203
  def self.flatten_object(source,keep_last)
@@ -370,6 +241,24 @@ module Asperalm
370
241
  end
371
242
  end
372
243
 
244
+ # expect some list, but nothing to display
245
+ def self.result_empty
246
+ return {:type => :empty, :data => :nil }
247
+ end
248
+
249
+ # nothing expected
250
+ def self.result_nothing
251
+ return {:type => :nothing, :data => :nil }
252
+ end
253
+
254
+ def self.result_status(status)
255
+ return {:type => :status, :data => status }
256
+ end
257
+
258
+ def self.result_success
259
+ return result_status('complete')
260
+ end
261
+
373
262
  # supported output formats
374
263
  def self.display_formats; [:table,:ruby,:json,:jsonpp,:yaml,:csv]; end
375
264
 
@@ -502,74 +391,19 @@ module Asperalm
502
391
  STDERR.puts(@opt_mgr.parser)
503
392
  if all_plugins
504
393
  # list plugins that have a "require" field, i.e. all but main plugin
505
- plugin_sym_list.select { |s| !@plugins[s][:require_stanza].nil? }.each do |plugin_name_sym|
394
+ @plugins.keys.select { |s| !@plugins[s][:require_stanza].nil? }.each do |plugin_name_sym|
506
395
  # override main option parser with a brand new
507
396
  @opt_mgr=Manager.new(@@PROGRAM_NAME)
508
397
  @opt_mgr.parser.banner = ""
509
- get_plugin_instance(plugin_name_sym)
398
+ get_plugin_instance_with_options(plugin_name_sym)
510
399
  STDERR.puts(@opt_mgr.parser)
511
400
  end
512
401
  end
513
402
  #STDERR.puts(@opt_mgr.parser)
514
- STDERR.puts "\nDocumentation : #{@@HELP_URL}"
403
+ STDERR.puts "\nDocumentation : #{Plugins::Config.instance.help_url}"
515
404
  Process.exit(0)
516
405
  end
517
406
 
518
- # read config file and validate format
519
- # tries to cnvert if possible and required
520
- def read_config_file
521
- # oldest compatible conf file format, update to latest version when an incompatible change is made
522
- if !File.exist?(@option_config_file)
523
- Log.log.warn("No config file found. Creating empty configuration file: #{@option_config_file}")
524
- @available_presets={@@MAIN_PLUGIN_NAME_SYM.to_s=>{@@CONFIG_PRESET_VERSION=>self.class.gem_version}}
525
- save_presets_to_config_file
526
- return nil
527
- end
528
- begin
529
- Log.log.debug "loading #{@option_config_file}"
530
- @available_presets=YAML.load_file(@option_config_file)
531
- Log.log.debug "Available_presets: #{@available_presets}"
532
- raise "Expecting YAML Hash" unless @available_presets.is_a?(Hash)
533
- # check there is at least the config section
534
- if !@available_presets.has_key?(@@MAIN_PLUGIN_NAME_SYM.to_s)
535
- raise "Cannot find key: #{@@MAIN_PLUGIN_NAME_SYM.to_s}"
536
- end
537
- version=@available_presets[@@MAIN_PLUGIN_NAME_SYM.to_s][@@CONFIG_PRESET_VERSION]
538
- if version.nil?
539
- raise "No version found in config section."
540
- end
541
- # check compatibility of version of conf file
542
- config_tested_version='0.4.5'
543
- if Gem::Version.new(version) < Gem::Version.new(config_tested_version)
544
- raise "Unsupported config file version #{version}. Expecting min version #{config_tested_version}"
545
- end
546
- save_required=false
547
- config_tested_version='0.6.14'
548
- if Gem::Version.new(version) <= Gem::Version.new(config_tested_version)
549
- old_plugin_name='files'
550
- new_plugin_name=ASPERA_PLUGIN_S
551
- if @available_presets[@@CONFIG_PRESET_DEFAULT].is_a?(Hash) and @available_presets[@@CONFIG_PRESET_DEFAULT].has_key?(old_plugin_name)
552
- @available_presets[@@CONFIG_PRESET_DEFAULT][new_plugin_name]=@available_presets[@@CONFIG_PRESET_DEFAULT][old_plugin_name]
553
- @available_presets[@@CONFIG_PRESET_DEFAULT].delete(old_plugin_name)
554
- Log.log.warn("Converted plugin default: #{old_plugin_name} -> #{new_plugin_name}")
555
- save_required=true
556
- end
557
- end
558
- # Place new compatibility code here
559
- if save_required
560
- @available_presets[@@MAIN_PLUGIN_NAME_SYM.to_s][@@CONFIG_PRESET_VERSION]=self.class.gem_version
561
- save_presets_to_config_file
562
- Log.log.warn("Saving automatic conversion.")
563
- end
564
- rescue => e
565
- new_name="#{@option_config_file}.pre#{self.class.gem_version}.manual_conversion_needed"
566
- File.rename(@option_config_file,new_name)
567
- Log.log.warn("Renamed config file to #{new_name}.")
568
- Log.log.warn("Manual Conversion is required. Next time, a new empty file will be created.")
569
- raise CliError,e.to_s
570
- end
571
- end
572
-
573
407
  protected
574
408
 
575
409
  def generate_new_key(key_filepath)
@@ -582,152 +416,6 @@ module Asperalm
582
416
 
583
417
  DEFAULT_REDIRECT='http://localhost:12345'
584
418
 
585
- # "config" plugin
586
- def execute_action
587
- action=@opt_mgr.get_next_argument('action',[:genkey,:plugins,:flush_tokens,:list,:overview,:open,:echo,:id,:documentation,:wizard])
588
- case action
589
- when :id
590
- config_name=@opt_mgr.get_next_argument('config name')
591
- action=@opt_mgr.get_next_argument('action',[:show,:delete,:set,:unset,:initialize,:update,:ask])
592
- case action
593
- when :show
594
- raise "no such config: #{config_name}" unless @available_presets.has_key?(config_name)
595
- return {:type=>:single_object,:data=>@available_presets[config_name]}
596
- when :delete
597
- @available_presets.delete(config_name)
598
- save_presets_to_config_file
599
- return Main.result_status("deleted: #{config_name}")
600
- when :set
601
- param_name=@opt_mgr.get_next_argument('parameter name')
602
- param_value=@opt_mgr.get_next_argument('parameter value')
603
- if !@available_presets.has_key?(config_name)
604
- Log.log.debug("no such config name: #{config_name}, initializing")
605
- @available_presets[config_name]=Hash.new
606
- end
607
- if @available_presets[config_name].has_key?(param_name)
608
- Log.log.warn("overwriting value: #{@available_presets[config_name][param_name]}")
609
- end
610
- @available_presets[config_name][param_name]=param_value
611
- save_presets_to_config_file
612
- return Main.result_status("updated: #{config_name}: #{param_name} <- #{param_value}")
613
- when :unset
614
- param_name=@opt_mgr.get_next_argument('parameter name')
615
- if @available_presets.has_key?(config_name)
616
- @available_presets[config_name].delete(param_name)
617
- save_presets_to_config_file
618
- else
619
- Log.log.warn("no such parameter: #{param_name} (ignoring)")
620
- end
621
- return Main.result_status("removed: #{config_name}: #{param_name}")
622
- when :initialize
623
- config_value=@opt_mgr.get_next_argument('extended value (Hash)')
624
- if @available_presets.has_key?(config_name)
625
- Log.log.warn("configuration already exists: #{config_name}, overwriting")
626
- end
627
- @available_presets[config_name]=config_value
628
- save_presets_to_config_file
629
- return Main.result_status("modified: #{@option_config_file}")
630
- when :update
631
- # TODO: when arguments are provided: --option=value, this creates an entry in the named configuration
632
- theopts=@opt_mgr.get_options_table
633
- Log.log.debug("opts=#{theopts}")
634
- @available_presets[config_name]={} if !@available_presets.has_key?(config_name)
635
- @available_presets[config_name].merge!(theopts)
636
- save_presets_to_config_file
637
- return Main.result_status("updated: #{config_name}")
638
- when :ask
639
- @opt_mgr.ask_missing_mandatory=:yes
640
- @available_presets[config_name]||={}
641
- @opt_mgr.get_next_argument('option names',:multiple).each do |optionname|
642
- option_value=@opt_mgr.get_interactive(:option,optionname)
643
- @available_presets[config_name][optionname]=option_value
644
- end
645
- save_presets_to_config_file
646
- return Main.result_status("updated: #{config_name}")
647
- end
648
- when :documentation
649
- OpenApplication.instance.uri(@@HELP_URL)
650
- return Main.result_nothing
651
- when :open
652
- OpenApplication.instance.uri("#{@option_config_file}") #file://
653
- return Main.result_nothing
654
- when :genkey # generate new rsa key
655
- key_filepath=@opt_mgr.get_next_argument('private key file path')
656
- generate_new_key(key_filepath)
657
- return Main.result_status('generated key: '+key_filepath)
658
- when :echo # display the content of a value given on command line
659
- result={:type=>:other_struct, :data=>@opt_mgr.get_next_argument("value")}
660
- # special for csv
661
- result[:type]=:object_list if result[:data].is_a?(Array) and result[:data].first.is_a?(Hash)
662
- return result
663
- when :flush_tokens
664
- deleted_files=Oauth.flush_tokens
665
- return {:type=>:value_list, :name=>'file',:data=>deleted_files}
666
- when :plugins
667
- return {:data => plugin_sym_list.map { |i| { 'plugin' => i.to_s, 'path' => @plugins[i][:source] } } , :fields => ['plugin','path'], :type => :object_list }
668
- when :list
669
- return {:data => @available_presets.keys, :type => :value_list, :name => 'name'}
670
- when :overview
671
- return {:type=>:object_list,:data=>self.class.flatten_all_config(@available_presets)}
672
- when :wizard
673
- # only one value, so no test, no switch for the time being
674
- plugin_name=@opt_mgr.get_next_argument('plugin name',[:aspera])
675
- require 'asperalm/cli/plugins/aspera'
676
- files_plugin=Plugins::Aspera.new
677
- files_plugin.declare_options
678
- @opt_mgr.parse_options!
679
- @opt_mgr.set_option(:auth,:web)
680
- @opt_mgr.set_option(:redirect_uri,DEFAULT_REDIRECT)
681
- instance_url=@opt_mgr.get_option(:url,:mandatory)
682
- organization,instance_domain=FilesApi.parse_url(instance_url)
683
- aspera_preset_name='aoc_'+organization
684
- key_filepath=File.join(@config_folder,'aspera_on_cloud_key')
685
- if File.exist?(key_filepath)
686
- puts "key file already exists: #{key_filepath}"
687
- else
688
- puts "generating: #{key_filepath}"
689
- generate_new_key(key_filepath)
690
- end
691
- puts "Please login to your Aspera on Cloud instance as Administrator."
692
- puts "Go to: Admin->Organization->Integrations"
693
- puts "Create a new integration:"
694
- puts "- name: aslmcli"
695
- puts "- redirect uri: #{DEFAULT_REDIRECT}"
696
- puts "- origin: localhost"
697
- puts "Once created please enter the following any required parameter:"
698
- OpenApplication.instance.uri(instance_url+"/admin/org/integrations")
699
- @opt_mgr.get_option(:client_id)
700
- @opt_mgr.get_option(:client_secret)
701
- @available_presets[@@CONFIG_PRESET_DEFAULT]||=Hash.new
702
- raise CliError,"a default configuration already exists (use --override=yes)" if @available_presets[@@CONFIG_PRESET_DEFAULT].has_key?(ASPERA_PLUGIN_S) and !option_override
703
- raise CliError,"preset already exists: #{aspera_preset_name} (use --override=yes)" if @available_presets.has_key?(aspera_preset_name) and !option_override
704
- # todo: check if key is identical
705
- files_plugin.init_apis
706
- myself=files_plugin.api_files_user.read('self')[:data]
707
- raise CliError,"public key is already set (use --override=yes)" unless myself['public_key'].empty? or option_override
708
- puts "updating profile with new key"
709
- files_plugin.api_files_user.update("users/#{myself['id']}",{'public_key'=>File.read(key_filepath+'.pub')})
710
- puts "Enabling JWT"
711
- files_plugin.api_files_admn.update("clients/#{@opt_mgr.get_option(:client_id)}",{"jwt_grant_enabled"=>true,"explicit_authorization_required"=>false})
712
- puts "creating new config preset: #{aspera_preset_name}"
713
- @available_presets[aspera_preset_name]={
714
- :url.to_s =>@opt_mgr.get_option(:url),
715
- :redirect_uri.to_s =>@opt_mgr.get_option(:redirect_uri),
716
- :client_id.to_s =>@opt_mgr.get_option(:client_id),
717
- :client_secret.to_s =>@opt_mgr.get_option(:client_secret),
718
- :auth.to_s =>:jwt.to_s,
719
- :private_key.to_s =>'@file:'+key_filepath,
720
- :username.to_s =>myself['email'],
721
- }
722
- puts "setting config preset as default for #{ASPERA_PLUGIN_S}"
723
- @available_presets[@@CONFIG_PRESET_DEFAULT][ASPERA_PLUGIN_S]=aspera_preset_name
724
- puts "saving config file"
725
- save_presets_to_config_file
726
- return Main.result_status("Done. You can test with:\naslmcli aspera user info show")
727
- # TODO: update documentation
728
- end
729
- end
730
-
731
419
  def add_plugin_lookup_folder(folder)
732
420
  @plugin_lookup_folders.push(folder)
733
421
  end
@@ -756,96 +444,55 @@ module Asperalm
756
444
 
757
445
  public
758
446
 
447
+ def start_transfer_wait_result(transfer_spec,ts_source)
448
+ return TransferAgent.instance.start_transfer_wait_result(transfer_spec,ts_source)
449
+ end
450
+
451
+ def destination_folder(direction)
452
+ return TransferAgent.instance.destination_folder(direction)
453
+ end
454
+
759
455
  def display_status(status)
760
456
  STDOUT.puts(status) if @opt_mgr.get_option(:format,:mandatory).eql?(:table)
761
457
  end
762
458
 
763
459
  def preset_by_name(config_name)
764
- raise "no such config: #{config_name}" unless @available_presets.has_key?(config_name)
765
- return @available_presets[config_name]
460
+ raise "no such config: #{config_name}" unless config_presets.has_key?(config_name)
461
+ return config_presets[config_name]
766
462
  end
463
+
767
464
  # public method
768
465
  # $HOME/.aspera/aslmcli
769
- attr_reader :config_folder
466
+ def config_folder; Plugins::Config.instance.config_folder; end
770
467
 
771
468
  def options;@opt_mgr;end
772
469
 
773
- # return destination folder for transfers
774
- # sets default if needed
775
- # param: 'send' or 'receive'
776
- def destination_folder(direction)
777
- # set default if needed
778
- if @transfer_spec_default['destination_root'].nil?
779
- # default: / on remote, . on local
780
- case direction
781
- when 'send'
782
- @transfer_spec_default['destination_root']='/'
783
- when 'receive'
784
- @transfer_spec_default['destination_root']='.'
785
- else
786
- raise "wrong direction: #{direction}"
787
- end
788
- end
789
- return @transfer_spec_default['destination_root']
790
- end
791
-
792
- # plugins shall use this method to start a transfer
793
- # @param: ts_source specifies how destination_root is set (how transfer spec was generated)
794
- # and not the default one
795
- def start_transfer_wait_result(transfer_spec,ts_source)
796
- # initialize transfert agent, to set default transfer spec options before merge
797
- transfer_manager
798
- case transfer_spec['direction']
799
- when 'receive'
800
- # init default if required in any case
801
- destination_folder(transfer_spec['direction'])
802
- when 'send'
803
- case ts_source
804
- when :direct
805
- # init default if required
806
- destination_folder(transfer_spec['direction'])
807
- when :node_gen3
808
- # in that case, destination is set in return by application (API/upload_setup)
809
- # but to_folder was used in intial api call
810
- @transfer_spec_default.delete('destination_root')
811
- when :node_gen4
812
- @transfer_spec_default['destination_root']='/'
813
- else
814
- raise StandardError,"InternalError: unsupported value: #{ts_source}"
815
- end
816
- end
817
-
818
- transfer_spec.merge!(@transfer_spec_default)
819
- # add bypass keys if there is a token, also prevents connect plugin to ask password
820
- transfer_spec['authentication']='token' if transfer_spec.has_key?('token')
821
- Log.log.debug("mgr is a #{transfer_manager.class}")
822
- transfer_manager.start_transfer(transfer_spec)
823
- return self.class.result_nothing
824
- end
825
-
826
470
  # this is the main function called by initial script just after constructor
827
471
  def process_command_line(argv)
828
472
  exception_info=nil
829
473
  begin
830
474
  # first thing : manage debug level (allows debugging or option parser)
831
475
  early_debug_setup(argv)
832
- # declare and parse basic options (includes config file location)
833
- create_opt_mgr
834
- # give command line arguments to option manager
476
+ # give command line arguments to option manager (no parsing)
835
477
  @opt_mgr.add_cmd_line_options(argv)
478
+ # declare initial options
479
+ init_options
480
+ # declare options for config file location
481
+ Plugins::Config.instance.declare_options
836
482
  # parse declared options
837
483
  @opt_mgr.parse_options!
838
484
  # load default config if it was not overriden on command line
839
- read_config_file
485
+ Plugins::Config.instance.read_config_file
840
486
  # declare general options
841
- declare_options
487
+ declare_global_options
488
+ TransferAgent.instance.declare_transfer_options
842
489
  @opt_mgr.parse_options!
843
490
  # find plugins, shall be after parse! ?
844
491
  add_plugins_from_lookup_folders
845
492
  # help requested without command ? (plugins must be known here)
846
493
  exit_with_usage(true) if @option_help and @opt_mgr.command_or_arg_empty?
847
494
  # load global default options and process
848
- add_plugin_default_preset(@@MAIN_PLUGIN_NAME_SYM)
495
+ add_plugin_default_preset(@@CONFIG_PLUGIN_NAME_SYM)
849
496
  @opt_mgr.parse_options!
850
497
  # dual execution locking
851
498
  lock_port=@opt_mgr.get_option(:lock_port,:optional)
@@ -858,19 +505,19 @@ module Asperalm
858
505
  end
859
506
  end
860
507
  if @option_show_config and @opt_mgr.command_or_arg_empty?
861
- command_sym=@@MAIN_PLUGIN_NAME_SYM
508
+ command_sym=@@CONFIG_PLUGIN_NAME_SYM
862
509
  else
863
- command_sym=@opt_mgr.get_next_argument('command',plugin_sym_list.dup.unshift(:help))
510
+ command_sym=@opt_mgr.get_next_argument('command',@plugins.keys.dup.unshift(:help))
864
511
  end
865
512
  # main plugin is not dynamically instanciated
866
513
  case command_sym
867
514
  when :help
868
515
  exit_with_usage(true)
869
- when @@MAIN_PLUGIN_NAME_SYM
870
- command_plugin=self
516
+ when @@CONFIG_PLUGIN_NAME_SYM
517
+ command_plugin=Plugins::Config.instance
871
518
  else
872
519
  # get plugin, set options, etc
873
- command_plugin=get_plugin_instance(command_sym)
520
+ command_plugin=get_plugin_instance_with_options(command_sym)
874
521
  # parse plugin specific options
875
522
  @opt_mgr.parse_options!
876
523
  end
@@ -883,7 +530,7 @@ module Asperalm
883
530
  # execute and display
884
531
  display_results(command_plugin.execute_action)
885
532
  # wait for session termination
886
- transfer_manager.shutdown(true)
533
+ TransferAgent.instance.shutdown(true)
887
534
  @opt_mgr.fail_if_unprocessed
888
535
  rescue CliBadArgument => e; exception_info=[e,'Argument',:usage]
889
536
  rescue CliNoSuchId => e; exception_info=[e,'Identifier']
@@ -898,7 +545,7 @@ module Asperalm
898
545
  TempFileManager.instance.cleanup
899
546
  # processing of error condition
900
547
  unless exception_info.nil?
901
- STDERR.puts "ERROR:".bg_red().gray().blink()+" "+exception_info[1]+": "+exception_info[0].message
548
+ STDERR.puts "ERROR:".bg_red.gray.blink+" "+exception_info[1]+": "+exception_info[0].message
902
549
  STDERR.puts "Use '-h' option to get help." if exception_info[2].eql?(:usage)
903
550
  if Log.instance.level.eql?(:debug)
904
551
  # will force to show stack trace