Class: Aspera::Cli::Wizard
- Inherits:
-
Object
- Object
- Aspera::Cli::Wizard
- Defined in:
- lib/aspera/cli/wizard.rb
Overview
The wizard detects applications and generates a config
Class Method Summary collapse
-
.declare_options(options) ⇒ Object
Declare all wizard CLI options (metadata only - no handler binding yet).
Instance Method Summary collapse
-
#ask_private_key(user:, url:, page:) ⇒ String
To be called in public wizard method to get private key.
- #check_email(email) ⇒ Object
-
#find(apps, preset_name: '') ⇒ Object
Wizard function, creates configuration.
- #formatter ⇒ Object
-
#identify_plugins_for_url(url:, plugin_name: nil) ⇒ Hash
Find a plugin, and issue the "require".
-
#initialize(parent, main_folder) ⇒ Wizard
constructor
A new instance of Wizard.
- #options ⇒ Object
-
#required ⇒ Boolean
False if in test mode to avoid interactive input.
Constructor Details
#initialize(parent, main_folder) ⇒ Wizard
Returns a new instance of Wizard.
25 26 27 28 29 |
# File 'lib/aspera/cli/wizard.rb', line 25 def initialize(parent, main_folder) @parent = parent @main_folder = main_folder self.class.() end |
Class Method Details
.declare_options(options) ⇒ Object
Declare all wizard CLI options (metadata only - no handler binding yet).
18 19 20 21 22 |
# File 'lib/aspera/cli/wizard.rb', line 18 def () .declare(:override, description: 'Wizard: override existing value', allowed: Allowed::TYPES_BOOLEAN, default: false) .declare(:default, description: 'Wizard: set as default configuration for specified plugin (also: update)', allowed: Allowed::TYPES_BOOLEAN, default: true) .declare(:key_path, description: 'Wizard: path to private key for JWT') end |
Instance Method Details
#ask_private_key(user:, url:, page:) ⇒ String
To be called in public wizard method to get private key
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 |
# File 'lib/aspera/cli/wizard.rb', line 93 def ask_private_key(user:, url:, page:) # Lets see if path to priv key is provided private_key_path = .get_option(:key_path) # Give a chance to provide if private_key_path.nil? formatter.display_status('Path to private RSA key (leave empty to generate):') private_key_path = .get_option(:key_path, mandatory: true).to_s end # Else generate path private_key_path = File.join(@main_folder, DEFAULT_PRIV_KEY_FILENAME) if private_key_path.empty? if File.exist?(File.(private_key_path)) formatter.display_status('Using existing key:') else formatter.display_status("Generating #{OAuth::Jwt::DEFAULT_PRIV_KEY_LENGTH} bit RSA key...") OAuth::Jwt.generate_rsa_private_key(path: private_key_path) formatter.display_status('Created key:') end formatter.display_status(private_key_path) private_key_pem = File.read(File.(private_key_path)) pub_key_pem = OpenSSL::PKey::RSA.new(private_key_pem).public_key.to_s .set_option(:private_key, private_key_pem) formatter.display_status("Please Log in as user #{user.red} at: #{url.red}") formatter.display_status("Navigate to: #{page}") formatter.display_status("Check or update the value to (#{'including BEGIN/END lines'.red}):".blink) formatter.display_status(pub_key_pem, hide_secrets: false) formatter.display_status('Once updated or validated, press [Enter].') Environment.instance.open_uri(url) $stdin.gets if required private_key_path end |
#check_email(email) ⇒ Object
44 45 46 |
# File 'lib/aspera/cli/wizard.rb', line 44 def check_email(email) Aspera.assert(email =~ /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i, type: ParameterError){"Username shall be an email: #{email}"} end |
#find(apps, preset_name: '') ⇒ Object
Wizard function, creates configuration
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/aspera/cli/wizard.rb', line 126 def find(apps, preset_name: '') identification = if apps.length.eql?(1) Log.log.debug{"Detected: #{identification}"} apps.first else formatter.display_status('Multiple applications detected, please select from:') require 'aspera/cli/result' formatter.display_results(Result::ObjectList.new(apps, fields: %w[product url version])) answer = .prompt_user_input_in_list('product', apps.map{ |a| a[:product]}) apps.find{ |a| a[:product].eql?(answer)} end wiz_preset_name = preset_name Log.dump(:identification, identification) wiz_url = identification[:url] formatter.display_status("Using: #{identification[:name]} at #{wiz_url}".bold) # Set url for instantiation of plugin .add_option_preset({url: wiz_url}, 'wizard') # Instantiate plugin: command line options will be known, e.g. private_key, and wizard can be called plugin_instance = Plugins::Factory.instance.plugin_class(identification[:product]).new(context: @parent.context) Aspera.assert(plugin_instance.respond_to?(:wizard), type: Cli::BadArgument){"Detected: #{identification[:product]}, but this application has no wizard"} # Call the wizard wizard_result = plugin_instance.wizard(self, wiz_url) Log.log.debug{"wizard result: #{wizard_result}"} Aspera.assert(WIZARD_RESULT_KEYS.eql?(wizard_result.keys.sort)){"missing or extra keys in wizard result: #{wizard_result.keys}"} # Get preset name from user or default if wiz_preset_name.empty? elements = [ identification[:product], URI.parse(wiz_url).host ] elements.push(.get_option(:username, mandatory: true)) unless wizard_result[:preset_value].key?(:link) rescue nil wiz_preset_name = elements.join('_').strip.downcase.gsub(/[^a-z0-9]/, '_').squeeze('_') end # Write configuration file formatter.display_status("Preparing preset: #{wiz_preset_name}") # Init defaults if necessary option_override = .get_option(:override, mandatory: true) option_default = .get_option(:default, mandatory: true) @parent.context.presets.defaults_set(identification[:product], wiz_preset_name, wizard_result[:preset_value].stringify_keys, option_default, option_override) test_args = wizard_result[:test_args] test_args = "-P#{wiz_preset_name} #{test_args}" unless option_default # TODO: actually test the command test_cmd = "#{Info::CMD_NAME} #{identification[:product]} #{test_args}" return Result::Status.new("You can test with:\n#{test_cmd.red}") end |
#formatter ⇒ Object
40 41 42 |
# File 'lib/aspera/cli/wizard.rb', line 40 def formatter @parent.formatter end |
#identify_plugins_for_url(url:, plugin_name: nil) ⇒ Hash
Find a plugin, and issue the "require"
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/aspera/cli/wizard.rb', line 50 def identify_plugins_for_url(url:, plugin_name: nil) app_url = url check_only = plugin_name&.to_sym found_apps = [] my_self_plugin_sym = self.class.name.split('::').last.downcase.to_sym Plugins::Factory.instance.plugin_list.each do |plugin_name_sym| # No detection for internal plugin next if plugin_name_sym.eql?(my_self_plugin_sym) next if check_only && !check_only.eql?(plugin_name_sym) # Load plugin class plugin_klass = Plugins::Factory.instance.plugin_class(plugin_name_sym) # Requires detection method next unless plugin_klass.respond_to?(:detect) detection_info = nil begin Log.log.debug{"detecting #{plugin_name_sym} at #{app_url}"} RestParameters.instance.spinner_cb.call(plugin_name_sym.to_s) detection_info = plugin_klass.detect(app_url) rescue OpenSSL::SSL::SSLError => e Log.log.warn(e.) Log.log.warn('Use option --insecure=yes to allow unchecked certificate') if e..include?('cert') rescue StandardError => e Log.log.debug{"detect error: [#{e.class}] #{e}"} next end next if detection_info.nil? Aspera.assert_type(detection_info, Hash) Aspera.assert_type(detection_info[:url], String) if detection_info.key?(:url) app_name = plugin_klass.application_name # If there is a redirect, then the detector can override the url. found_apps.push({product: plugin_name_sym, name: app_name, url: app_url, version: 'unknown'}.merge(detection_info)) end RestParameters.instance.spinner_cb.call(action: :success) Aspera.assert(!found_apps.empty?){"No known application found at #{app_url}"} Aspera.assert(found_apps.all?{ |a| a.keys.all?(Symbol)}, 'all app info keys must be symbols') return found_apps end |
#options ⇒ Object
36 37 38 |
# File 'lib/aspera/cli/wizard.rb', line 36 def @parent. end |
#required ⇒ Boolean
Returns false if in test mode to avoid interactive input.
32 33 34 |
# File 'lib/aspera/cli/wizard.rb', line 32 def required !ENV['ASCLI_WIZ_TEST'] end |