示例#1
0
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
示例#2
0
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)
示例#3
0
def record_chosen_plugins(config: configuration.NamespaceConfig,
                          plugins: disco.PluginsRegistry,
                          auth: Optional[interfaces.Authenticator],
                          inst: Optional[interfaces.Installer]) -> None:
    """Update the config entries to reflect the plugins we actually selected."""
    config.authenticator = None
    if auth:
        auth_ep = plugins.find_init(auth)
        if auth_ep:
            config.authenticator = auth_ep.name
    config.installer = None
    if inst:
        inst_ep = plugins.find_init(inst)
        if inst_ep:
            config.installer = inst_ep.name
    logger.info("Plugins selected: Authenticator %s, Installer %s",
                config.authenticator, config.installer)
示例#4
0
 def test_find_all(self):
     from certbot._internal.plugins.disco import PluginsRegistry
     with mock.patch("certbot._internal.plugins.disco.pkg_resources") as mock_pkg:
         mock_pkg.iter_entry_points.side_effect = [iter([EP_SA]),
                                                   iter([EP_WR])]
         plugins = PluginsRegistry.find_all()
     self.assertTrue(plugins["sa"].plugin_cls is standalone.Authenticator)
     self.assertTrue(plugins["sa"].entry_point is EP_SA)
     self.assertTrue(plugins["wr"].plugin_cls is webroot.Authenticator)
     self.assertTrue(plugins["wr"].entry_point is EP_WR)
示例#5
0
    def add_plugin_args(self, plugins: disco.PluginsRegistry) -> None:
        """

        Let each of the plugins add its own command line arguments, which
        may or may not be displayed as help topics.

        """
        for name, plugin_ep in plugins.items():
            parser_or_group = self.add_group(
                name, description=plugin_ep.long_description)
            plugin_ep.plugin_cls.inject_parser_options(parser_or_group, name)
示例#6
0
 def setUp(self):
     super(GetUnpreparedInstallerTest, self).setUp()
     self.mock_apache_fail_ep = mock.Mock(description_with_name="afail")
     self.mock_apache_fail_ep.name = "afail"
     self.mock_apache_ep = mock.Mock(description_with_name="apache")
     self.mock_apache_ep.name = "apache"
     self.mock_apache_plugin = mock.MagicMock()
     self.mock_apache_ep.init.return_value = self.mock_apache_plugin
     self.plugins = PluginsRegistry({
         "afail": self.mock_apache_fail_ep,
         "apache": self.mock_apache_ep,
     })
示例#7
0
 def setUp(self):
     super().setUp()
     self.mock_apache_fail_ep = mock.Mock(description_with_name="afail")
     self.mock_apache_fail_ep.check_name = lambda name: name == "afail"
     self.mock_apache_ep = mock.Mock(description_with_name="apache")
     self.mock_apache_ep.check_name = lambda name: name == "apache"
     self.mock_apache_plugin = mock.MagicMock()
     self.mock_apache_ep.init.return_value = self.mock_apache_plugin
     self.plugins = PluginsRegistry({
         "afail": self.mock_apache_fail_ep,
         "apache": self.mock_apache_ep,
     })
示例#8
0
 def test_find_all(self):
     from certbot._internal.plugins.disco import PluginsRegistry
     with mock.patch("certbot._internal.plugins.disco.pkg_resources") as mock_pkg:
         mock_pkg.iter_entry_points.side_effect = [
             iter([EP_SA]), iter([EP_WR, self.ep1])
         ]
         with mock.patch.object(pkg_resources.EntryPoint, 'load') as mock_load:
             mock_load.side_effect = [
                 standalone.Authenticator, webroot.Authenticator,
                 null.Installer, null.Installer]
             plugins = PluginsRegistry.find_all()
     self.assertIs(plugins["sa"].plugin_cls, standalone.Authenticator)
     self.assertIs(plugins["sa"].entry_point, EP_SA)
     self.assertIs(plugins["wr"].plugin_cls, webroot.Authenticator)
     self.assertIs(plugins["wr"].entry_point, EP_WR)
     self.assertIs(plugins["ep1"].plugin_cls, null.Installer)
     self.assertIs(plugins["ep1"].entry_point, self.ep1)
     self.assertIs(plugins["p1:ep1"].plugin_cls, null.Installer)
     self.assertIs(plugins["p1:ep1"].entry_point, self.ep1)
示例#9
0
 def test_no_available_installers(self):
     self.config.configurator = "apache"
     self.plugins = PluginsRegistry({})
     self.assertRaises(errors.PluginSelectionError, self._call)
示例#10
0
 def _create_new_registry(cls, plugins):
     from certbot._internal.plugins.disco import PluginsRegistry
     return PluginsRegistry(plugins)