Class: Aspera::Cli::Plugins::Config
- Includes:
- AscpActions, GemChecker, Aspera::Cli::PresetActions, SyncActions, TransferActions, VaultManager
- Defined in:
- lib/aspera/cli/plugins/config.rb
Overview
Manage the CLI config file
Constant Summary
Constants included from Aspera::Cli::PresetActions
Aspera::Cli::PresetActions::CONF_OVERVIEW_KEYS, Aspera::Cli::PresetActions::GLOBAL_DEFAULT_KEYWORD
Constants included from AscpActions
AscpActions::TRANSFERD_APP_NAME
Constants included from GemChecker
GemChecker::GEM_CHECK_DATE_FMT
Constants included from SyncActions
SyncActions::ADMIN_COMMANDS, SyncActions::PATH_AND_INFO_ARGS, SyncActions::STATE_STR
Constants inherited from Base
Instance Attribute Summary collapse
-
#gem_url ⇒ Object
readonly
Returns the value of attribute gem_url.
-
#option_cache_tokens ⇒ Object
Returns the value of attribute option_cache_tokens.
Attributes inherited from Base
Class Method Summary collapse
-
.deep_clone(val) ⇒ Object
Deep clone hash so that it does not get modified in case of display and secret hide.
-
.default_app_main_folder(app_name:) ⇒ String
Product config folder (~/.aspera/
). -
.gem_plugins_folder ⇒ Object
Folder containing plugins in the gem's main folder.
-
.gem_src_root ⇒ String
Go up as many times as englobing modules (not counting class, as it is a file).
-
.module_family_folder ⇒ String
Product family folder (~/.aspera).
Instance Method Summary collapse
- #action_commands ⇒ Object
- #action_completion_bash(words: nil) ⇒ Object
- #action_detect(url:, plugin_name: nil) ⇒ Object
-
#action_documentation(location: :github, section: nil) ⇒ Object
DSL handlers - one method per leaf command.
- #action_download(file_url:, file_dest: nil) ⇒ Object
- #action_genkey(private_key_path:, private_key_length: OAuth::Jwt::DEFAULT_PRIV_KEY_LENGTH) ⇒ Object
- #action_initdemo ⇒ Object
- #action_options(plugin_name:) ⇒ Object
- #action_plugins_create(name:, folder: nil) ⇒ Object
- #action_plugins_list ⇒ Object
- #action_remote_certificate_chain(remote_url:) ⇒ Object
- #action_remote_certificate_name(remote_url:) ⇒ Object
- #action_remote_certificate_only(remote_url:) ⇒ Object
- #action_test_throw(exception_class_name:, exception_text:) ⇒ Object
- #action_tokens_show(token_id:) ⇒ Object
- #action_wizard(url:, plugin_name: nil, preset_name: '') ⇒ Object
-
#initialize(**_) ⇒ Config
constructor
A new instance of Config.
- #option_plugin_folder ⇒ Object
- #option_plugin_folder=(value) ⇒ Object
- #option_preset ⇒ Object
- #option_preset=(value) ⇒ Object
Methods included from TransferActions
#action_transfer_cleanup, #action_transfer_list, #action_transfer_status
Methods included from Aspera::Cli::PresetActions
#action_preset_ask, #action_preset_delete, #action_preset_get, #action_preset_initialize, #action_preset_list, #action_preset_lookup, #action_preset_overview, #action_preset_secure, #action_preset_set, #action_preset_show, #action_preset_unset, #action_preset_update
Methods included from AscpActions
#action_agents_list, #action_agents_parameters, #action_agents_show, #action_ascp_errors, #action_ascp_info, #action_ascp_install, #action_ascp_products_list, #action_ascp_schema, #action_ascp_show, #action_ascp_spec, #action_transferd_install, #action_transferd_list, #install_transfer_sdk, #set_sdk_dir
Methods included from GemChecker
#check_gem_version, #periodic_check_newer_gem_version
Methods included from VaultManager
#action_vault_create, #action_vault_delete, #action_vault_import, #action_vault_password, #action_vault_show, #vault, #vault_required, #vault_value
Methods included from SyncActions
#action_sync_admin_counters, #action_sync_admin_file_info, #action_sync_admin_find, #action_sync_admin_meta, #action_sync_admin_overview, #action_sync_admin_query, #action_sync_admin_status, #async_info_from_args, #db_from_args, included, register_sync_admin_commands, #run_sync_transfer
Methods inherited from Base
#action_for, #add_manual_header, application_name, #bulk_result, command, command_registry, commands_under, #config, crud_commands, declare_options, define_action_method, #dispatch_child, #dispatch_from_registry, #dispatch_leaf, #entity_create, #entity_delete, entity_display_name, #entity_list, #entity_modify, #entity_res_path, #entity_show, #execute_action, #execute_leaf, file_matcher, #formatter, #generate_help, #http_config, #invoke_action, option, #options, #persistency, #presets, #progress_bar, #query_read_delete, #resolve_argument, root_setup, #transfer, use_options, used_option_sources
Constructor Details
#initialize(**_) ⇒ Config
Returns a new instance of Config.
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/aspera/cli/plugins/config.rb', line 97 def initialize(**_) super @vault_instance = nil @sdk_default_location = false @option_cache_tokens = true # :no_default uses a &block callback - must stay imperative .declare(:no_default, description: 'Do not load default configuration for plugin', allowed: Type::NONE, short: 'N') { presets.use_plugin_defaults = false } # Declare wizard options (Wizard#initialize calls options.declare internally) @wizard = Wizard.new(self, context.main_folder) . set_sdk_dir # HTTP options: declare metadata (class method), then bind to the instance Http.() context.http_config.() . end |
Instance Attribute Details
#gem_url ⇒ Object (readonly)
Returns the value of attribute gem_url.
353 354 355 |
# File 'lib/aspera/cli/plugins/config.rb', line 353 def gem_url @gem_url end |
#option_cache_tokens ⇒ Object
Returns the value of attribute option_cache_tokens.
351 352 353 |
# File 'lib/aspera/cli/plugins/config.rb', line 351 def option_cache_tokens @option_cache_tokens end |
Class Method Details
.deep_clone(val) ⇒ Object
Deep clone hash so that it does not get modified in case of display and secret hide
64 65 66 |
# File 'lib/aspera/cli/plugins/config.rb', line 64 def deep_clone(val) return Marshal.load(Marshal.dump(val)) end |
.default_app_main_folder(app_name:) ⇒ String
Returns Product config folder (~/.aspera/
76 77 78 79 80 |
# File 'lib/aspera/cli/plugins/config.rb', line 76 def default_app_main_folder(app_name:) Aspera.assert_type(app_name, String) Aspera.assert(!app_name.empty?, 'app_name must not be empty') return File.join(module_family_folder, app_name) end |
.gem_plugins_folder ⇒ Object
Folder containing plugins in the gem's main folder
52 53 54 |
# File 'lib/aspera/cli/plugins/config.rb', line 52 def gem_plugins_folder File.dirname(File.(__FILE__)) end |
.gem_src_root ⇒ String
Go up as many times as englobing modules (not counting class, as it is a file)
58 59 60 61 |
# File 'lib/aspera/cli/plugins/config.rb', line 58 def gem_src_root # Module.nesting[2] is Cli::Plugins File.(Module.nesting[2].to_s.gsub('::', '/').gsub(%r{[^/]+}, '..'), gem_plugins_folder) end |
.module_family_folder ⇒ String
Returns product family folder (~/.aspera).
69 70 71 72 73 |
# File 'lib/aspera/cli/plugins/config.rb', line 69 def module_family_folder user_home_folder = Dir.home Aspera.assert(Dir.exist?(user_home_folder), type: Cli::Error) { "Home folder does not exist: #{user_home_folder}. Check your user environment." } return File.join(user_home_folder, ASPERA_HOME_FOLDER_NAME) end |
Instance Method Details
#action_commands ⇒ Object
519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 |
# File 'lib/aspera/cli/plugins/config.rb', line 519 def action_commands commands = Plugins::Factory.instance.plugin_list.flat_map do |name| plugin_class = Plugins::Factory.instance.plugin_class(name) reg = plugin_class.command_registry reg.all_paths.reject { |path| reg.children_of(path).any? }.map do |path| spec = reg[path] # Build syntax by interleaving each path segment with the arguments declared on that node tokens = [name.to_s] path.each_with_index do |seg, i| tokens << seg.to_s node_args = reg[path[0, i + 1]]&.arguments.to_a node_args.each do |a| token = a.allowed ? a.allowed.join('|') : a.name.to_s token += '...' if a.multiple tokens << (a.mandatory ? "<#{token}>" : "[<#{token}>]") end end syntax = tokens.join(' ') { syntax: syntax, description: spec&.description.to_s } end end Result::ObjectList.new(commands, fields: %w[syntax description]) end |
#action_completion_bash(words: nil) ⇒ Object
567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 |
# File 'lib/aspera/cli/plugins/config.rb', line 567 def action_completion_bash(words: nil, **) if words.nil? || words.empty? # Level 0: propose plugin names Plugins::Factory.instance.plugin_list.each { |p| puts p } else plugin_sym = words.first.to_sym plugin_class = begin Plugins::Factory.instance.plugin_class(plugin_sym) rescue StandardError Process.exit(0) end # Navigate into the registry using remaining words as path path = words[1..].map(&:to_sym) plugin_class.command_registry.children_of(path).each_key { |k| puts k } end Process.exit(0) end |
#action_detect(url:, plugin_name: nil) ⇒ Object
483 484 485 486 487 |
# File 'lib/aspera/cli/plugins/config.rb', line 483 def action_detect(url:, plugin_name: nil, **) .ask_missing_mandatory = true apps = @wizard.identify_plugins_for_url(url: url, plugin_name: plugin_name).freeze Result::ObjectList.new(apps) end |
#action_documentation(location: :github, section: nil) ⇒ Object
DSL handlers - one method per leaf command
380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 |
# File 'lib/aspera/cli/plugins/config.rb', line 380 def action_documentation(location: :github, section: nil, **) case location when :github section = "##{section}" unless section.nil? Environment.instance.open_uri("#{Info::DOC_URL}#{section}") return Result::Nothing.new when :toc, :local require 'aspera/markdown' local_doc = File.join(self.class.gem_src_root, '..', 'docs', 'README.md') Aspera.assert(File.exist?(local_doc), type: Cli::Error) { "Local documentation not found: #{local_doc}" } content = File.read(local_doc) if location == :toc entries = Markdown.toc(content) return Result::ObjectList.new(entries, fields: %w[level title anchor]) end # :local if section text = Markdown.extract_section(content, section) Aspera.assert(!text.nil?, type: Cli::Error) { "Section not found: #{section}" } return Result::Text.new(text) end if Environment.instance.url_method.eql?(:graphical) Environment.instance.open_uri("file://#{local_doc}") return Result::Nothing.new end return Result::Text.new(content) end end |
#action_download(file_url:, file_dest: nil) ⇒ Object
432 433 434 435 436 437 438 |
# File 'lib/aspera/cli/plugins/config.rb', line 432 def action_download(file_url:, file_dest: nil, **) file_url = file_url.chomp file_dest = File.join(transfer.destination_folder(Transfer::Spec::DIRECTION_RECEIVE), file_url.gsub(%r{.*/}, '')) if file_dest.nil? Log.log.info("Downloading: #{file_url}") Rest.new(base_url: file_url).call(operation: 'GET', save_to: file_dest) Result::Status.new("Saved to: #{file_dest}") end |
#action_genkey(private_key_path:, private_key_length: OAuth::Jwt::DEFAULT_PRIV_KEY_LENGTH) ⇒ Object
409 410 411 412 |
# File 'lib/aspera/cli/plugins/config.rb', line 409 def action_genkey(private_key_path:, private_key_length: OAuth::Jwt::DEFAULT_PRIV_KEY_LENGTH, **) OAuth::Jwt.generate_rsa_private_key(path: private_key_path, length: private_key_length) Result::Status.new("Generated #{private_key_length} bit RSA key: #{private_key_path}") end |
#action_initdemo ⇒ Object
495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 |
# File 'lib/aspera/cli/plugins/config.rb', line 495 def action_initdemo cp = presets.config_presets if cp.key?(DEMO_PRESET) Log.log.warn { "Demo server preset already present: #{DEMO_PRESET}" } else Log.log.info { "Creating Demo server preset: #{DEMO_PRESET}" } cp[DEMO_PRESET] = { 'url' => "ssh://#{DEMO_SERVER}.asperasoft.com:33001", 'username' => ASPERA, 'ssAP'.downcase.reverse + 'drow'.reverse => DEMO_SERVER + ASPERA # cspell:disable-line } end cp[PresetManager::Key::DEFAULTS] ||= {} if cp[PresetManager::Key::DEFAULTS].key?(SERVER_COMMAND) Log.log.warn { "Server default preset already set to: #{cp[PresetManager::Key::DEFAULTS][SERVER_COMMAND]}" } Log.log.warn { "Use #{DEMO_PRESET} for demo: -P#{DEMO_PRESET}" } unless DEMO_PRESET.eql?(cp[PresetManager::Key::DEFAULTS][SERVER_COMMAND]) else cp[PresetManager::Key::DEFAULTS][SERVER_COMMAND] = DEMO_PRESET Log.log.info { "Setting server default preset to : #{DEMO_PRESET}" } end Result::Status.new('Done') end |
#action_options(plugin_name:) ⇒ Object
546 547 548 549 550 551 552 553 554 555 556 557 558 559 |
# File 'lib/aspera/cli/plugins/config.rb', line 546 def (plugin_name:, **) # Instantiate the plugin so that it registers all its options in context.options Plugins::Factory.instance.create(plugin_name.to_sym, context: context) rows = context...map do |sym, opt| row = { option: "--#{sym.to_s.tr('_', '-')}", description: opt.description.to_s } row[:allowed] = opt.values.join('|') if opt.values&.any? row[:deprecated] = opt.deprecation if opt.deprecation row end Result::ObjectList.new(rows, fields: %w[option description allowed deprecated]) end |
#action_plugins_create(name:, folder: nil) ⇒ Object
460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 |
# File 'lib/aspera/cli/plugins/config.rb', line 460 def action_plugins_create(name:, folder: nil, **) plugin_name = name.downcase destination_folder = folder || File.join(context.main_folder, ASPERA_PLUGINS_FOLDERNAME) plugin_file = File.join(destination_folder, "#{plugin_name}.rb") content = <<~END_OF_PLUGIN_CODE require 'aspera/cli/plugins/base' module Aspera module Cli module Plugins class #{plugin_name.snake_to_capital} < Base command :example, description: 'example command', action: :action_example def action_example Result::Status.new('You called plugin #{plugin_name}') end end end end end END_OF_PLUGIN_CODE File.write(plugin_file, content) Result::Status.new("Created #{plugin_file}") end |
#action_plugins_list ⇒ Object
447 448 449 450 451 452 453 454 455 456 457 458 |
# File 'lib/aspera/cli/plugins/config.rb', line 447 def action_plugins_list result = Plugins::Factory.instance.plugin_list.map do |name| plugin_class = Plugins::Factory.instance.plugin_class(name) { plugin: name, detect: TerminalFormatter.tick(plugin_class.respond_to?(:detect)), wizard: TerminalFormatter.tick(plugin_class.method_defined?(:wizard)), path: Plugins::Factory.instance.plugin_source(name) } end Result::ObjectList.new(result, fields: %w[plugin detect wizard path]) end |
#action_remote_certificate_chain(remote_url:) ⇒ Object
414 415 416 417 418 |
# File 'lib/aspera/cli/plugins/config.rb', line 414 def action_remote_certificate_chain(remote_url:, **) remote_chain = Rest.remote_certificate_chain(remote_url, as_string: false) Aspera.assert(remote_chain&.first) { "No certificate found for #{remote_url}" } Result::Text.new(remote_chain.map(&:to_pem).join("\n")) end |
#action_remote_certificate_name(remote_url:) ⇒ Object
426 427 428 429 430 |
# File 'lib/aspera/cli/plugins/config.rb', line 426 def action_remote_certificate_name(remote_url:, **) remote_chain = Rest.remote_certificate_chain(remote_url, as_string: false) Aspera.assert(remote_chain&.first) { "No certificate found for #{remote_url}" } Result::Text.new(remote_chain.first.subject.to_a.find { |name, _, _| name == 'CN' }[1]) end |
#action_remote_certificate_only(remote_url:) ⇒ Object
420 421 422 423 424 |
# File 'lib/aspera/cli/plugins/config.rb', line 420 def action_remote_certificate_only(remote_url:, **) remote_chain = Rest.remote_certificate_chain(remote_url, as_string: false) Aspera.assert(remote_chain&.first) { "No certificate found for #{remote_url}" } Result::Text.new(remote_chain.first.to_pem) end |
#action_test_throw(exception_class_name:, exception_text:) ⇒ Object
561 562 563 564 565 |
# File 'lib/aspera/cli/plugins/config.rb', line 561 def action_test_throw(exception_class_name:, exception_text:, **) type = Object.const_get(exception_class_name) Aspera.assert(type <= Exception) { "#{type} is not an exception: #{type.class}" } raise type, exception_text end |
#action_tokens_show(token_id:) ⇒ Object
440 441 442 443 444 445 |
# File 'lib/aspera/cli/plugins/config.rb', line 440 def action_tokens_show(token_id:, **) require 'aspera/api/node' data = OAuth::Factory.instance.get_token_info(token_id) Aspera.assert(!data.nil?, type: Cli::Error) { 'Unknown identifier' } Result::SingleObject.new(data) end |
#action_wizard(url:, plugin_name: nil, preset_name: '') ⇒ Object
489 490 491 492 493 |
# File 'lib/aspera/cli/plugins/config.rb', line 489 def action_wizard(url:, plugin_name: nil, preset_name: '', **) .ask_missing_mandatory = true apps = @wizard.identify_plugins_for_url(url: url, plugin_name: plugin_name).freeze @wizard.find(apps, preset_name: preset_name) end |
#option_plugin_folder ⇒ Object
361 362 363 |
# File 'lib/aspera/cli/plugins/config.rb', line 361 def option_plugin_folder return Plugins::Factory.instance.lookup_folders end |
#option_plugin_folder=(value) ⇒ Object
355 356 357 358 359 |
# File 'lib/aspera/cli/plugins/config.rb', line 355 def option_plugin_folder=(value) value = [value] unless value.is_a?(Array) Aspera.assert_array_all(value, String) { 'plugin folder(s)' } value.each { |f| Plugins::Factory.instance.add_lookup_folder(f) } end |
#option_preset ⇒ Object
365 |
# File 'lib/aspera/cli/plugins/config.rb', line 365 def option_preset; 'write-only option'; end |
#option_preset=(value) ⇒ Object
367 368 369 370 371 372 373 374 375 376 |
# File 'lib/aspera/cli/plugins/config.rb', line 367 def option_preset=(value) case value when Hash .add_option_preset(value, 'set') when String .add_option_preset(presets.by_name(value), 'set_by_name') else raise BadArgument, 'Preset definition must be a String for preset name, or Hash for set of values' end end |