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
Instance Method Summary collapse
-
#ask_private_key(user:, url:, page:) ⇒ Array
To be called in public wizard method to get private key.
- #check_email(email) ⇒ Object
- #config ⇒ Object
-
#find(apps) ⇒ Object
Wizard function, creates configuration.
- #formatter ⇒ Object
-
#identify_plugins_for_url ⇒ Hash
Find a plugin, and issue the “require”.
-
#initialize(parent, main_folder) ⇒ Wizard
constructor
A new instance of Wizard.
- #options ⇒ Object
-
#required ⇒ Object
False if in test mode to avoid interactive input.
Constructor Details
#initialize(parent, main_folder) ⇒ Wizard
Returns a new instance of Wizard.
16 17 18 19 20 21 22 23 |
# File 'lib/aspera/cli/wizard.rb', line 16 def initialize(parent, main_folder) @parent = parent @main_folder = main_folder # Wizard options .declare(:override, 'Wizard: override existing value', values: :bool, default: :no) .declare(:default, 'Wizard: set as default configuration for specified plugin (also: update)', values: :bool, default: true) .declare(:key_path, 'Wizard: path to private key for JWT') end |
Instance Method Details
#ask_private_key(user:, url:, page:) ⇒ Array
To be called in public wizard method to get private key
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 |
# File 'lib/aspera/cli/wizard.rb', line 88 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?(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(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
42 43 44 |
# File 'lib/aspera/cli/wizard.rb', line 42 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 |
#config ⇒ Object
38 39 40 |
# File 'lib/aspera/cli/wizard.rb', line 38 def config @parent.config end |
#find(apps) ⇒ Object
Wizard function, creates configuration
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 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/aspera/cli/wizard.rb', line 121 def find(apps) identification = if apps.length.eql?(1) Log.log.debug{"Detected: #{identification}"} apps.first else formatter.display_status('Multiple applications detected, please select from:') formatter.display_results(type: :object_list, data: 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 = .get_next_argument('preset name', default: '') 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) do "Detected: #{identification[:product]}, but this application has no wizard" end # 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) config.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 Main.result_status("You can test with:\n#{test_cmd.red}") end |
#formatter ⇒ Object
34 35 36 |
# File 'lib/aspera/cli/wizard.rb', line 34 def formatter @parent.formatter end |
#identify_plugins_for_url ⇒ Hash
Find a plugin, and issue the “require”
48 49 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 |
# File 'lib/aspera/cli/wizard.rb', line 48 def identify_plugins_for_url app_url = .get_next_argument('url', mandatory: true) check_only = .get_next_argument('plugin name', mandatory: false) check_only = check_only.to_sym unless check_only.nil? 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}"} formatter.long_operation_running("#{plugin_name_sym}\r") 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.respond_to?(:application_name) ? plugin_klass.application_name : plugin_klass.name.split('::').last # 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 raise "No known application found at #{app_url}" if found_apps.empty? Aspera.assert(found_apps.all?{ |a| a.keys.all?(Symbol)}) return found_apps end |
#options ⇒ Object
30 31 32 |
# File 'lib/aspera/cli/wizard.rb', line 30 def @parent. end |
#required ⇒ Object
Returns false if in test mode to avoid interactive input.
26 27 28 |
# File 'lib/aspera/cli/wizard.rb', line 26 def required !ENV['ASCLI_WIZ_TEST'] end |