def get_unprepared_installer( config: configuration.NamespaceConfig, plugins: disco.PluginsRegistry) -> Optional[interfaces.Installer]: """ Get an unprepared interfaces.Installer object. :param certbot.configuration.NamespaceConfig config: Configuration :param certbot._internal.plugins.disco.PluginsRegistry plugins: All plugins registered as entry points. :returns: Unprepared installer plugin or None :rtype: Plugin or None """ _, req_inst = cli_plugin_requests(config) if not req_inst: return None installers = plugins.filter(lambda p_ep: p_ep.check_name(req_inst)) installers.init(config) installers = installers.verify((interfaces.Installer, )) if len(installers) > 1: raise errors.PluginSelectionError( "Found multiple installers with the name %s, Certbot is unable to " "determine which one to use. Skipping." % req_inst) if installers: inst = list(installers.values())[0] logger.debug("Selecting plugin: %s", inst) return inst.init(config) raise errors.PluginSelectionError( "Could not select or initialize the requested installer %s." % req_inst)
def pick_plugin(config: configuration.NamespaceConfig, default: Optional[str], plugins: disco.PluginsRegistry, question: str, ifaces: Iterable[Type]) -> Optional[P]: """Pick plugin. :param certbot.configuration.NamespaceConfig config: Configuration :param str default: Plugin name supplied by user or ``None``. :param certbot._internal.plugins.disco.PluginsRegistry plugins: All plugins registered as entry points. :param str question: Question to be presented to the user in case multiple candidates are found. :param list ifaces: Interfaces that plugins must provide. :returns: Initialized plugin. :rtype: Plugin """ if default is not None: # throw more UX-friendly error if default not in plugins filtered = plugins.filter(lambda p_ep: p_ep.check_name(default)) else: if config.noninteractive_mode: # it's really bad to auto-select the single available plugin in # non-interactive mode, because an update could later add a second # available plugin raise errors.MissingCommandlineFlag( "Missing command line flags. For non-interactive execution, " "you will need to specify a plugin on the command line. Run " "with '--help plugins' to see a list of options, and see " "https://eff.org/letsencrypt-plugins for more detail on what " "the plugins do and how to use them.") filtered = plugins.visible().ifaces(ifaces) filtered.init(config) verified = filtered.verify(ifaces) verified.prepare() prepared = verified.available() if len(prepared) > 1: logger.debug("Multiple candidate plugins: %s", prepared) plugin_ep1 = choose_plugin(list(prepared.values()), question) if plugin_ep1 is None: return None return cast(P, plugin_ep1.init()) elif len(prepared) == 1: plugin_ep2 = list(prepared.values())[0] logger.debug("Single candidate plugin: %s", plugin_ep2) if plugin_ep2.misconfigured: return None return plugin_ep2.init() else: logger.debug("No candidate plugin") return None