Class: Aspera::Cli::Plugins::Config
- Includes:
- SyncActions
- Defined in:
- lib/aspera/cli/plugins/config.rb
Overview
Manage the CLI config file
Constant Summary collapse
- PRESET_GBL_ACTIONS =
Legacy actions available globally
%i[list overview lookup secure].freeze
- PRESET_EXIST_ACTIONS =
Operations requiring that preset exists
%i[show delete get unset].freeze
- PRESET_INSTANCE_ACTIONS =
require id
%i[initialize update ask set].concat(PRESET_EXIST_ACTIONS).freeze
- PRESET_ALL_ACTIONS =
(PRESET_GBL_ACTIONS + PRESET_INSTANCE_ACTIONS).freeze
- ACTIONS =
%i[ preset open documentation genkey pubkey remote_certificate gem plugins tokens echo download wizard detect coffee image ascp sync transferd email_test smtp_settings proxy_check folder file check_update initdemo vault test platform completion ].freeze
- EXTEND_ARGS =
:''
Constants included from SyncActions
Instance Attribute Summary collapse
-
#gem_url ⇒ Object
readonly
Returns the value of attribute gem_url.
-
#main_folder ⇒ Object
Returns the value of attribute main_folder.
-
#option_cache_tokens ⇒ Object
Returns the value of attribute option_cache_tokens.
-
#option_config_file ⇒ Object
Returns the value of attribute option_config_file.
-
#progress_bar ⇒ Object
readonly
Returns the value of attribute progress_bar.
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 ⇒ Object
Go up as many times as englobing modules (not counting class, as it is a file).
-
.module_family_folder ⇒ Object
Product family folder (~/.aspera).
Instance Method Summary collapse
-
#add_plugin_default_preset(plugin_name_sym) ⇒ Object
Delegation to PresetManager: loads default preset options for a plugin.
- #check_gem_version ⇒ Object
-
#defaults_set(plugin_name, preset_name, preset_values, option_default, option_override) ⇒ Object
Delegations to PresetManager kept for backward compatibility.
-
#email_settings ⇒ Hash
Email server setting with defaults if not defined.
-
#execute_action ⇒ Object
Main action procedure for plugin.
- #execute_action_ascp ⇒ Object
- #execute_action_transferd ⇒ Object
-
#execute_completion ⇒ Result
Generate shell completion.
- #execute_preset(action: nil, name: nil) ⇒ Object
-
#execute_test ⇒ Object
Artificially raise an exception for tests.
-
#execute_vault ⇒ Hash
Result of execution of vault command.
- #get_plugin_default_config_name(plugin_name_sym) ⇒ Object
- #ignore_cert?(address, port) ⇒ Boolean
-
#initialize(**_) ⇒ Config
constructor
A new instance of Config.
- #install_transfer_sdk ⇒ Object
- #lookup_preset(url:, username:) ⇒ Object
-
#lookup_secret(url:, username:) ⇒ String?
Lookup the corresponding secret for the given URL and usernames.
- #option_http_options ⇒ Object
- #option_http_options=(v) ⇒ Object
- #option_ignore_cert_host_port ⇒ Object
-
#option_insecure ⇒ Object
Delegations to http_config kept for backward compatibility with transfer_agent and plugins.
- #option_insecure=(v) ⇒ Object
- #option_plugin_folder ⇒ Object
- #option_plugin_folder=(value) ⇒ Object
- #option_preset ⇒ Object
- #option_preset=(value) ⇒ Object
- #option_warn_insecure_cert ⇒ Object
- #option_warn_insecure_cert=(v) ⇒ Object
- #periodic_check_newer_gem_version ⇒ Object
- #preset_by_name(config_name, include_path = []) ⇒ Object
- #save_config_file_if_needed ⇒ Object
-
#send_email_template(email_template_default: nil, values: {}) ⇒ Object
Send email using ERB template.
- #set_global_default(key, value) ⇒ Object
- #set_preset_key(preset, param_name, param_value) ⇒ Object
- #set_sdk_dir ⇒ Object
- #trusted_cert_locations ⇒ Object
- #trusted_cert_locations=(v) ⇒ Object
-
#vault ⇒ Object
Vault, from options or cache.
-
#vault_value(name) ⇒ String
Value from vault matching
..
Methods included from SyncActions
#async_info_from_args, #db_from_args, declare_options, #execute_sync_action, #execute_sync_admin
Methods inherited from Base
#add_manual_header, #config, declare_options, #do_bulk_operation, #entity_execute, #formatter, #http_config, #options, #persistency, #presets, #query_read_delete, #transfer, #value_create_modify
Constructor Details
#initialize(**_) ⇒ Config
Returns a new instance of Config.
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/aspera/cli/plugins/config.rb', line 83 def initialize(**_) # We need to defer parsing of options until we have the config file, so we can use @extend with @preset super @vault_instance = nil @pac_exec = nil @sdk_default_location = false @option_cache_tokens = true @main_folder = nil @option_config_file = nil @progress_bar = nil # Option to set main folder .declare( :home, 'Home folder for tool', handler: {o: self, m: :main_folder}, default: self.class.default_app_main_folder(app_name: Info::CMD_NAME) ) . Log.log.debug{"#{Info::CMD_NAME} folder: #{@main_folder}"} setup_persistency_and_plugin_folders # Option to set config file .declare( :config_file, 'Path to YAML file with preset configuration', handler: {o: self, m: :option_config_file}, default: File.join(@main_folder, DEFAULT_CONFIG_FILENAME) ) . # Instantiate PresetManager (reads config file) and inject into context context.presets = PresetManager.new(config_file: @option_config_file) # Instantiate Http and inject into context context.http_config = Http.new setup_extended_value_handlers # Vault options .declare(:secret, 'Secret for access keys') .declare(:vault, 'Vault for secrets', allowed: Hash) .declare(:vault_password, 'Vault password') . # Declare generic plugin options only after handlers are declared Base.() # Configuration options .declare(:no_default, 'Do not load default configuration for plugin', allowed: Allowed::TYPES_NONE, short: 'N'){ presets.use_plugin_defaults = false } .declare(:preset, 'Load the named option preset from current config file', short: 'P', handler: {o: self, m: :option_preset}) .declare(:version_check_days, 'Period in days to check new version (zero to disable)', allowed: Allowed::TYPES_INTEGER, default: DEFAULT_CHECK_NEW_VERSION_DAYS) .declare(:plugin_folder, 'Folder where to find additional plugins', handler: {o: self, m: :option_plugin_folder}) # Declare wizard options @wizard = Wizard.new(self, @main_folder) # Transfer SDK options .declare(:sdk_url, 'Ascp: URL to get Aspera Transfer Executables', default: SpecialValues::DEF) . set_sdk_dir .declare(:locations_url, 'Ascp: URL to get download locations of Aspera Transfer Daemon', handler: {o: Ascp::Installation.instance, m: :transferd_urls}) .declare(:sdk_folder, 'Ascp: Path to folder with ascp (or product with "product:")', handler: {o: Products::Transferd, m: :sdk_directory}) .declare(:progress_bar, 'Display progress bar', allowed: Allowed::TYPES_BOOLEAN, default: Environment.terminal?) # Email options .declare(:smtp, 'Email: SMTP configuration', allowed: Hash) .declare(:notify_to, 'Email: Recipient for notification of transfers') .declare(:notify_template, 'Email: ERB template for notification of transfers') # HTTP options — declared by HttpConfig itself context.http_config.() .declare(:cache_tokens, 'Save and reuse OAuth tokens', allowed: Allowed::TYPES_BOOLEAN, handler: {o: self, m: :option_cache_tokens}) .declare(:fpac, 'Proxy auto configuration script') .declare(:proxy_credentials, 'HTTP proxy credentials for fpac: user, password', allowed: [Array, NilClass]) . @progress_bar = TransferProgress.new if .get_option(:progress_bar) setup_pac_executor setup_rest_and_transfer_runtime end |
Instance Attribute Details
#gem_url ⇒ Object (readonly)
Returns the value of attribute gem_url.
332 333 334 |
# File 'lib/aspera/cli/plugins/config.rb', line 332 def gem_url @gem_url end |
#main_folder ⇒ Object
Returns the value of attribute main_folder.
210 211 212 |
# File 'lib/aspera/cli/plugins/config.rb', line 210 def main_folder @main_folder end |
#option_cache_tokens ⇒ Object
Returns the value of attribute option_cache_tokens.
210 211 212 |
# File 'lib/aspera/cli/plugins/config.rb', line 210 def option_cache_tokens @option_cache_tokens end |
#option_config_file ⇒ Object
Returns the value of attribute option_config_file.
333 334 335 |
# File 'lib/aspera/cli/plugins/config.rb', line 333 def option_config_file @option_config_file end |
#progress_bar ⇒ Object (readonly)
Returns the value of attribute progress_bar.
211 212 213 |
# File 'lib/aspera/cli/plugins/config.rb', line 211 def @progress_bar 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 ⇒ Object
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 ⇒ Object
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
#add_plugin_default_preset(plugin_name_sym) ⇒ Object
Delegation to PresetManager: loads default preset options for a plugin
297 298 299 300 301 |
# File 'lib/aspera/cli/plugins/config.rb', line 297 def add_plugin_default_preset(plugin_name_sym) default_config_name = presets.plugin_default_name(plugin_name_sym) Log.log.debug{"add_plugin_default_preset:#{plugin_name_sym}:#{default_config_name}"} .add_option_preset(presets.by_name(default_config_name), 'default_plugin', override: false) unless default_config_name.nil? end |
#check_gem_version ⇒ Object
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 |
# File 'lib/aspera/cli/plugins/config.rb', line 247 def check_gem_version latest_version = begin Rest.new(base_url: 'https://rubygems.org/api/v1').read("versions/#{Info::GEM_NAME}/latest.json")['version'] rescue StandardError Log.log.warn('Could not retrieve latest gem version on rubygems.') '0' end if Gem::Version.new(Environment.ruby_version) < Gem::Version.new(Info::RUBY_FUTURE_MINIMUM_VERSION) Log.log.warn do "Note that a future version will require Ruby version #{Info::RUBY_FUTURE_MINIMUM_VERSION} at minimum, " \ "you are using #{Environment.ruby_version}" end end return { name: Info::GEM_NAME, current: Cli::VERSION, latest: latest_version, need_update: Gem::Version.new(Cli::VERSION) < Gem::Version.new(latest_version) } end |
#defaults_set(plugin_name, preset_name, preset_values, option_default, option_override) ⇒ Object
Delegations to PresetManager kept for backward compatibility
304 305 306 |
# File 'lib/aspera/cli/plugins/config.rb', line 304 def defaults_set(plugin_name, preset_name, preset_values, option_default, option_override) presets.defaults_set(plugin_name, preset_name, preset_values, option_default, option_override) end |
#email_settings ⇒ Hash
Returns email server setting with defaults if not defined.
753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 |
# File 'lib/aspera/cli/plugins/config.rb', line 753 def email_settings smtp = .get_option(:smtp, mandatory: true) # Change keys from string into symbol smtp = smtp.symbolize_keys unsupported = smtp.keys - SMTP_CONF_PARAMS raise Cli::Error, "Unsupported SMTP parameter: #{unsupported.join(', ')}, use: #{SMTP_CONF_PARAMS.join(', ')}" unless unsupported.empty? # Defaults # smtp[:ssl] = nil (false) smtp[:tls] = !smtp[:ssl] unless smtp.key?(:tls) smtp[:port] ||= if smtp[:tls] 587 elsif smtp[:ssl] 465 else 25 end smtp[:from_email] ||= smtp[:username] if smtp.key?(:username) smtp[:from_name] ||= smtp[:from_email].sub(/@.*$/, '').gsub(/[^a-zA-Z]/, ' ').capitalize if smtp.key?(:username) smtp[:domain] ||= smtp[:from_email].sub(/^.*@/, '') if smtp.key?(:from_email) # Check minimum required %i[server port domain].each do |n| Aspera.assert(smtp.key?(n)){"Missing mandatory smtp parameter: #{n}"} end Log.log.debug{"smtp=#{smtp}"} return smtp end |
#execute_action ⇒ Object
Main action procedure for plugin
563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 |
# File 'lib/aspera/cli/plugins/config.rb', line 563 def execute_action action = .get_next_command(ACTIONS) case action when :preset # Newer syntax return execute_preset when :open Environment.instance.open_editor(@option_config_file.to_s) return Result::Nothing.new when :documentation section = .get_next_argument('private key file path', mandatory: false) section = "##{section}" unless section.nil? Environment.instance.open_uri("#{Info::DOC_URL}#{section}") return Result::Nothing.new when :genkey # Generate new rsa key private_key_path = .get_next_argument('private key file path') private_key_length = .get_next_argument('size in bits', mandatory: false, validation: Integer, default: OAuth::Jwt::DEFAULT_PRIV_KEY_LENGTH) OAuth::Jwt.generate_rsa_private_key(path: private_key_path, length: private_key_length) return Result::Status.new("Generated #{private_key_length} bit RSA key: #{private_key_path}") when :pubkey # Get pub key private_key_pem = .get_next_argument('private key PEM value') return Result::Text.new(OpenSSL::PKey::RSA.new(private_key_pem).public_key.to_s) when :remote_certificate cert_action = .get_next_command(%i[chain only name]) remote_url = .get_next_argument('remote URL') remote_chain = Rest.remote_certificate_chain(remote_url, as_string: false) raise "No certificate found for #{remote_url}" unless remote_chain&.first case cert_action when :chain return Result::Text.new(remote_chain.map(&:to_pem).join("\n")) when :only return Result::Text.new(remote_chain.first.to_pem) when :name return Result::Text.new(remote_chain.first.subject.to_a.find{ |name, _, _| name == 'CN'}[1]) end when :echo # Display the content of a value given on command line return Result.auto(.get_next_argument('value', validation: nil)) when :download file_url = .get_next_argument('source URL').chomp file_dest = .get_next_argument('file path', mandatory: false) 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: file_dest) return Result::Status.new("Saved to: #{file_dest}") when :tokens require 'aspera/api/node' case .get_next_command(%i{flush list show}) when :flush return Result::ValueList.new(OAuth::Factory.instance.flush_tokens, name: 'file') when :list return Result::ObjectList.new(OAuth::Factory.instance.persisted_tokens) when :show data = OAuth::Factory.instance.get_token_info(.instance_identifier) raise Cli::Error, 'Unknown identifier' if data.nil? return Result::SingleObject.new(data) end when :plugins case .get_next_command(%i[list create]) when :list result = [] Plugins::Factory.instance.plugin_list.each do |name| plugin_class = Plugins::Factory.instance.plugin_class(name) result.push({ 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 return Result::ObjectList.new(result, fields: %w[plugin detect wizard path]) when :create plugin_name = .get_next_argument('name').downcase destination_folder = .get_next_argument('folder', mandatory: false) || File.join(@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 ACTIONS=[] def execute_action return Result::Status.new('You called plugin #{plugin_name}') end end end end end END_OF_PLUGIN_CODE File.write(plugin_file, content) return Result::Status.new("Created #{plugin_file}") end when :detect, :wizard # Interactive mode .ask_missing_mandatory = true # Detect plugins by url and optional query apps = @wizard.identify_plugins_for_url.freeze return Result::ObjectList.new(apps) if action.eql?(:detect) return @wizard.find(apps) when :coffee return Result::Image.new(COFFEE_IMAGE_URL) when :image return Result::Image.new(.get_next_argument('image URI or blob')) when :ascp execute_action_ascp when :sync SyncActions.() case .get_next_command(%i[spec admin translate]) when :spec builder = Schema::Documentation.new(TerminalFormatter, Sync::Operations::CONF_SCHEMA, include_option: true).build return Result::ObjectList.new(builder.rows, fields: builder.columns) when :admin return execute_sync_admin when :translate return Result::SingleObject.new(Sync::Operations.args_to_conf(.get_next_argument('async arguments', multiple: true))) else Aspera.error_unreachable_line end when :transferd execute_action_transferd when :gem case .get_next_command(%i[path version name]) when :path then return Result::Text.new(self.class.gem_src_root) when :version then return Result::Text.new(Cli::VERSION) when :name then return Result::Text.new(Info::GEM_NAME) else Aspera.error_unreachable_line end when :folder return Result::Text.new(@main_folder) when :file return Result::Text.new(@option_config_file) when :email_test send_email_template(email_template_default: EMAIL_TEST_TEMPLATE) return Result::Nothing.new when :smtp_settings return Result::SingleObject.new(email_settings) when :proxy_check # Ensure fpac was provided .get_option(:fpac, mandatory: true) server_url = .get_next_argument('server url') return Result::ValueList.new(@pac_exec.get_proxies(server_url), name: 'proxy') when :check_update return Result::SingleObject.new(check_gem_version) when :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 return Result::Status.new('Done') when :vault then execute_vault when :test then return execute_test when :platform return Result::Text.new(Environment.instance.architecture) when :completion return execute_completion else Aspera.error_unreachable_line end end |
#execute_action_ascp ⇒ Object
366 367 368 369 370 371 372 373 374 375 376 377 378 379 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 366 def execute_action_ascp command = .get_next_command(%i[show products info install spec schema errors]) case command when :show return Result::Text.new(Ascp::Installation.instance.path(:ascp)) when :info # Collect info from ascp executable data = Ascp::Installation.instance.ascp_info # Add command line transfer spec data['ts'] = transfer.user_transfer_spec # Add keys DataRepository::ELEMENTS.each_with_object(data){ |i, h| h[i.to_s] = DataRepository.instance.item(i)} # Declare those as secrets SecretHider::ADDITIONAL_KEYS_TO_HIDE.concat(DataRepository::ELEMENTS.map(&:to_s)) return Result::SingleObject.new(data) when :products command = .get_next_command(%i[list]) case command when :list return Result::ObjectList.new(Ascp::Installation.instance.installed_products, fields: %w[name app_root]) end when :install return install_transfer_sdk when :spec builder = Schema::Documentation.new(TerminalFormatter, Transfer::Spec::SCHEMA, include_option: true, agent_columns: true).build return Result::ObjectList.new(builder.rows, fields: builder.columns) when :schema schema = Transfer::Spec::SCHEMA.current.merge({'$comment'=>'DO NOT EDIT, this file was generated from the YAML.'}) agent = .get_next_argument('transfer agent name', mandatory: false) schema['properties'] = schema['properties'].select{ |_k, v| CommandLineBuilder.supported_by_agent(agent, v)} unless agent.nil? schema['properties'] = schema['properties'].sort.to_h return Result::SingleObject.new(schema) when :errors error_data = [] Ascp::Management::ERRORS.each_pair do |code, prop| error_data.push(code: code, mnemonic: prop[:c], retry: prop[:r], info: prop[:a]) end return Result::ObjectList.new(error_data) else Aspera.error_unexpected_value(command) end Aspera.error_unreachable_line end |
#execute_action_transferd ⇒ Object
409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 |
# File 'lib/aspera/cli/plugins/config.rb', line 409 def execute_action_transferd command = .get_next_command(%i[list install]) case command when :install return install_transfer_sdk when :list sdk_list = Ascp::Installation.instance.sdk_locations return Result::ObjectList.new( sdk_list, fields: sdk_list.first.keys - ['url'] ) else Aspera.error_unexpected_value(command) end Aspera.error_unreachable_line end |
#execute_completion ⇒ Result
Generate shell completion
738 739 740 741 742 743 744 745 746 747 748 749 750 |
# File 'lib/aspera/cli/plugins/config.rb', line 738 def execute_completion shell_type = .get_next_command(%i[bash]) case shell_type when :bash if .get_next_argument('', multiple: true, mandatory: false).nil? Plugins::Factory.instance.plugin_list.each{ |p| puts p} else Log.log.warn('only first level completion so far') end Process.exit(0) else Aspera.error_unreachable_line end end |
#execute_preset(action: nil, name: nil) ⇒ Object
433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 |
# File 'lib/aspera/cli/plugins/config.rb', line 433 def execute_preset(action: nil, name: nil) cp = presets.config_presets action = .get_next_command(PRESET_ALL_ACTIONS) if action.nil? name = .instance_identifier if name.nil? && PRESET_INSTANCE_ACTIONS.include?(action) name = presets.global_default_preset if name.eql?(GLOBAL_DEFAULT_KEYWORD) # Those operations require existing option raise "no such preset: #{name}" if PRESET_EXIST_ACTIONS.include?(action) && !cp.key?(name) case action when :list return Result::ValueList.new(cp.keys, name: 'name') when :overview # Display process modifies the value (hide secrets): we do not want to save removed secrets data = PresetManager.deep_clone(cp) formatter.hide_secrets(data) result = [] data.each do |config, preset| preset.each do |parameter, value| result.push(CONF_OVERVIEW_KEYS.zip([config, parameter, value]).to_h) end end return Result::ObjectList.new(result, fields: CONF_OVERVIEW_KEYS) when :show return Result::SingleObject.new(PresetManager.deep_clone(cp[name])) when :delete cp.delete(name) return Result::Status.new("Deleted: #{name}") when :get param_name = .get_next_argument('parameter name') value = cp[name][param_name] raise "no such option in preset #{name} : #{param_name}" if value.nil? case value when Numeric, String then return Result::Text.new(ExtendedValue.instance.evaluate(value.to_s, context: 'preset')) end return Result::SingleObject.new(value) when :unset param_name = .get_next_argument('parameter name') cp[name].delete(param_name) return Result::Status.new("Removed: #{name}: #{param_name}") when :set param_name = .get_next_argument('parameter name') param_name = Manager.option_line_to_name(param_name) param_value = .get_next_argument('parameter value', validation: nil) set_preset_key(name, param_name, param_value) return Result::Nothing.new when :initialize config_value = .get_next_argument('extended value', validation: Hash) Log.log.warn{"configuration already exists: #{name}, overwriting"} if cp.key?(name) cp[name] = config_value return Result::Status.new("Modified: #{@option_config_file}") when :update = . Log.log.debug{"opts=#{}"} cp[name] ||= {} cp[name].merge!() return Result::Status.new("Updated: #{name}") when :ask .ask_missing_mandatory = true cp[name] ||= {} .get_next_argument('option names', multiple: true).each do |option_name| option_value = .get_interactive(option_name, check_option: true) cp[name][option_name] = option_value end return Result::Status.new("Updated: #{name}") when :lookup BasicAuth.() url = .get_option(:url, mandatory: true) user = .get_option(:username, mandatory: true) result = lookup_preset(url: url, username: user) raise Error, 'no such config found' if result.nil? return Result::SingleObject.new(result) when :secure identifier = .get_next_argument('config name', mandatory: false) preset_names = identifier.nil? ? cp.keys : [identifier] secret_keywords = %w[password secret].freeze preset_names.each do |preset_name| preset = cp[preset_name] next unless preset.is_a?(Hash) preset.each_key do |option_name| secret_keywords.each do |keyword| next unless option_name.end_with?(keyword) vault_label = preset_name incr = 0 until vault.get(label: vault_label, exception: false).nil? vault_label = "#{preset_name}#{incr}" incr += 1 end to_set = {label: vault_label, password: preset[option_name]} puts "need to encode #{preset_name}.#{option_name} -> #{vault_label} -> #{to_set}" vault.set(to_set) preset[option_name] = "@vault:#{vault_label}.password" end end end return Result::Status.new('Secrets secured in vault: Make sure to save the vault password securely.') end end |
#execute_test ⇒ Object
Artificially raise an exception for tests
865 866 867 868 869 870 871 872 873 874 875 876 877 |
# File 'lib/aspera/cli/plugins/config.rb', line 865 def execute_test case .get_next_command(%i[throw web]) when :throw # :type [String] # Options exception_class_name = .get_next_argument('exception class name', mandatory: true) exception_text = .get_next_argument('exception text', mandatory: true) type = Object.const_get(exception_class_name) Aspera.assert(type <= Exception){"#{type} is not an exception: #{type.class}"} raise type, exception_text when :web end end |
#execute_vault ⇒ Hash
Returns result of execution of vault command.
815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 |
# File 'lib/aspera/cli/plugins/config.rb', line 815 def execute_vault command = .get_next_command(%i[info list show create delete password]) case command when :info return Result::SingleObject.new(vault.info) when :list # , fields: %w(label url username password description) return Result::ObjectList.new(vault.list) when :show return Result::SingleObject.new(vault.get(label: .get_next_argument('label'))) when :create vault.set(.get_next_argument('info', validation: Hash).symbolize_keys) return Result::Status.new('Secret added') when :delete label_to_delete = .get_next_argument('label') vault.delete(label: label_to_delete) return Result::Status.new("Secret deleted: #{label_to_delete}") when :password Aspera.assert(vault.respond_to?(:change_password), 'Vault does not support password change') vault.change_password(.get_next_argument('new_password')) return Result::Status.new('Vault password updated') end end |
#get_plugin_default_config_name(plugin_name_sym) ⇒ Object
320 321 322 |
# File 'lib/aspera/cli/plugins/config.rb', line 320 def get_plugin_default_config_name(plugin_name_sym) presets.plugin_default_name(plugin_name_sym) end |
#ignore_cert?(address, port) ⇒ Boolean
221 |
# File 'lib/aspera/cli/plugins/config.rb', line 221 def ignore_cert?(address, port); context.http_config.ignore_cert?(address, port); end |
#install_transfer_sdk ⇒ Object
358 359 360 361 362 363 364 |
# File 'lib/aspera/cli/plugins/config.rb', line 358 def install_transfer_sdk asked_version = .get_next_argument('transferd version', mandatory: false) sdk_url = .get_option(:sdk_url, mandatory: true) sdk_url = nil if sdk_url.eql?(SpecialValues::DEF) name, version, folder = Ascp::Installation.instance.retrieve_sdk(url: sdk_url, version: asked_version) return Result::Status.new("Installed #{name} version #{version} in #{folder}") end |
#lookup_preset(url:, username:) ⇒ Object
328 329 330 |
# File 'lib/aspera/cli/plugins/config.rb', line 328 def lookup_preset(url:, username:) presets.lookup_preset(url: url, username: username) end |
#lookup_secret(url:, username:) ⇒ String?
Lookup the corresponding secret for the given URL and usernames
883 884 885 886 887 888 889 890 891 892 893 |
# File 'lib/aspera/cli/plugins/config.rb', line 883 def lookup_secret(url:, username:) secret = .get_option(:secret) if secret.eql?('PRESET') conf = presets.lookup_preset(url: url, username: username) if conf.is_a?(Hash) Log.log.debug{"Found preset #{conf} with URL and username"} secret = conf['password'] end end return secret end |
#option_http_options ⇒ Object
218 |
# File 'lib/aspera/cli/plugins/config.rb', line 218 def ; context.http_config.; end |
#option_http_options=(v) ⇒ Object
219 |
# File 'lib/aspera/cli/plugins/config.rb', line 219 def (v); context.http_config. = v; end |
#option_ignore_cert_host_port ⇒ Object
220 |
# File 'lib/aspera/cli/plugins/config.rb', line 220 def option_ignore_cert_host_port; context.http_config.ignore_cert_host_port; end |
#option_insecure ⇒ Object
Delegations to http_config kept for backward compatibility with transfer_agent and plugins
214 |
# File 'lib/aspera/cli/plugins/config.rb', line 214 def option_insecure; context.http_config.insecure; end |
#option_insecure=(v) ⇒ Object
215 |
# File 'lib/aspera/cli/plugins/config.rb', line 215 def option_insecure=(v); context.http_config.insecure = v; end |
#option_plugin_folder ⇒ Object
341 342 343 |
# File 'lib/aspera/cli/plugins/config.rb', line 341 def option_plugin_folder return Plugins::Factory.instance.lookup_folders end |
#option_plugin_folder=(value) ⇒ Object
335 336 337 338 339 |
# File 'lib/aspera/cli/plugins/config.rb', line 335 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
345 |
# File 'lib/aspera/cli/plugins/config.rb', line 345 def option_preset; 'write-only option'; end |
#option_preset=(value) ⇒ Object
347 348 349 350 351 352 353 354 355 356 |
# File 'lib/aspera/cli/plugins/config.rb', line 347 def option_preset=(value) case value when Hash .add_option_preset(value, 'set') when String .add_option_preset(preset_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 |
#option_warn_insecure_cert ⇒ Object
216 |
# File 'lib/aspera/cli/plugins/config.rb', line 216 def option_warn_insecure_cert; context.http_config.warn_insecure; end |
#option_warn_insecure_cert=(v) ⇒ Object
217 |
# File 'lib/aspera/cli/plugins/config.rb', line 217 def option_warn_insecure_cert=(v); context.http_config.warn_insecure = v; end |
#periodic_check_newer_gem_version ⇒ Object
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 |
# File 'lib/aspera/cli/plugins/config.rb', line 269 def periodic_check_newer_gem_version # Get verification period delay_days = .get_option(:version_check_days, mandatory: true).to_i # Check only if not zero day return if delay_days.eql?(0) # Get last date from persistency last_check_array = [] check_date_persist = PersistencyActionOnce.new( manager: persistency, data: last_check_array, id: 'version_last_check' ) # Get persisted date or nil current_date = Date.today last_check_days = (current_date - Date.strptime(last_check_array.first, GEM_CHECK_DATE_FMT)) rescue nil Log.log.debug{"gem check new version: #{delay_days}, #{last_check_days}, #{current_date}, #{last_check_array}"} return if !last_check_days.nil? && last_check_days < delay_days # Generate timestamp last_check_array[0] = current_date.strftime(GEM_CHECK_DATE_FMT) check_date_persist.save # Compare this version and the one on internet check_data = check_gem_version Log.log.warn do "A new version is available: #{check_data[:latest]}. You have #{check_data[:current]}. Upgrade with: gem update #{check_data[:name]}" end if check_data[:need_update] end |
#preset_by_name(config_name, include_path = []) ⇒ Object
316 317 318 |
# File 'lib/aspera/cli/plugins/config.rb', line 316 def preset_by_name(config_name, include_path = []) presets.by_name(config_name, include_path) end |
#save_config_file_if_needed ⇒ Object
324 325 326 |
# File 'lib/aspera/cli/plugins/config.rb', line 324 def save_config_file_if_needed presets.save_if_needed end |
#send_email_template(email_template_default: nil, values: {}) ⇒ Object
Send email using ERB template
783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 |
# File 'lib/aspera/cli/plugins/config.rb', line 783 def send_email_template(email_template_default: nil, values: {}) values[:to] ||= .get_option(:notify_to, mandatory: true) notify_template = .get_option(:notify_template, mandatory: email_template_default.nil?) || email_template_default mail_conf = email_settings values[:from_name] ||= mail_conf[:from_name] values[:from_email] ||= mail_conf[:from_email] %i[to from_email].each do |n| Aspera.assert_type(values[n], String){"Missing email parameter: #{n} in config"} end = [mail_conf[:domain]] .push(mail_conf[:username], mail_conf[:password], :login) if mail_conf.key?(:username) && mail_conf.key?(:password) # Create a binding with only variables defined in values template_binding = Environment.empty_binding # Add variables to binding values.each do |k, v| Aspera.assert_type(k, Symbol) template_binding.local_variable_set(k, v) end # Execute template msg_with_headers = ERB.new(notify_template).result(template_binding) Log.dump(:msg_with_headers, msg_with_headers) require 'net/smtp' smtp = Net::SMTP.new(mail_conf[:server], mail_conf[:port]) smtp.enable_starttls if mail_conf[:tls] smtp.enable_tls if mail_conf[:ssl] smtp.start(*) do |smtp_session| smtp_session.(msg_with_headers, values[:from_email], values[:to]) end nil end |
#set_global_default(key, value) ⇒ Object
312 313 314 |
# File 'lib/aspera/cli/plugins/config.rb', line 312 def set_global_default(key, value) presets.set_global_default(key, value) end |
#set_preset_key(preset, param_name, param_value) ⇒ Object
308 309 310 |
# File 'lib/aspera/cli/plugins/config.rb', line 308 def set_preset_key(preset, param_name, param_value) presets.set_key(preset, param_name, param_value) end |
#set_sdk_dir ⇒ Object
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 |
# File 'lib/aspera/cli/plugins/config.rb', line 225 def set_sdk_dir # Check SDK folder is set or not, for compatibility, we check in two places sdk_dir = Products::Transferd.sdk_directory rescue nil if sdk_dir.nil? @sdk_default_location = true Log.log.debug('SDK folder is not set, checking default') # New location sdk_dir = self.class.default_app_main_folder(app_name: TRANSFERD_APP_NAME) Log.log.debug{"Checking: #{sdk_dir}"} if !Dir.exist?(sdk_dir) Log.log.debug{"No such folder: #{sdk_dir}"} # Former location former_sdk_folder = File.join(self.class.default_app_main_folder(app_name: Info::CMD_NAME), TRANSFERD_APP_NAME) Log.log.debug{"Checking: #{former_sdk_folder}"} sdk_dir = former_sdk_folder if Dir.exist?(former_sdk_folder) end Log.log.debug{"Using: #{sdk_dir}"} Products::Transferd.sdk_directory = sdk_dir end end |
#trusted_cert_locations ⇒ Object
222 |
# File 'lib/aspera/cli/plugins/config.rb', line 222 def trusted_cert_locations; context.http_config.trusted_cert_locations; end |
#trusted_cert_locations=(v) ⇒ Object
223 |
# File 'lib/aspera/cli/plugins/config.rb', line 223 def trusted_cert_locations=(v); context.http_config.trusted_cert_locations = v; end |
#vault ⇒ Object
Returns vault, from options or cache.
851 852 853 854 855 856 857 858 859 860 861 862 |
# File 'lib/aspera/cli/plugins/config.rb', line 851 def vault return @vault_instance unless @vault_instance.nil? info = .get_option(:vault).symbolize_keys info[:type] ||= 'file' require 'aspera/keychain/factory' @vault_instance = Keychain::Factory.create( info, Info::CMD_NAME, @main_folder, .get_option(:vault_password) ) end |
#vault_value(name) ⇒ String
Returns value from vault matching
840 841 842 843 844 845 846 847 848 |
# File 'lib/aspera/cli/plugins/config.rb', line 840 def vault_value(name) m = name.split('.') raise BadArgument, 'vault name shall match <name>.<param>' unless m.length.eql?(2) # This raise exception if label not found: info = vault.get(label: m[0]) value = info[m[1].to_sym] raise "no such entry value: #{m[1]}" if value.nil? return value end |