示例#1
0
def choose_configurator_plugins(
    config: configuration.NamespaceConfig, plugins: disco.PluginsRegistry,
    verb: str
) -> Tuple[Optional[interfaces.Installer], Optional[interfaces.Authenticator]]:
    """
    Figure out which configurator we're going to use, modifies
    config.authenticator and config.installer strings to reflect that choice if
    necessary.

    :raises errors.PluginSelectionError if there was a problem

    :returns: tuple of (`Installer` or None, `Authenticator` or None)
    :rtype: tuple
    """

    req_auth, req_inst = cli_plugin_requests(config)
    installer_question = ""

    if verb == "enhance":
        installer_question = ("Which installer would you like to use to "
                              "configure the selected enhancements?")

    # Which plugins do we need?
    if verb == "run":
        need_inst = need_auth = True
        from certbot._internal.cli import cli_command
        if req_auth in noninstaller_plugins and not req_inst:
            msg = (
                'With the {0} plugin, you probably want to use the "certonly" command, eg:{1}'
                '{1}    {2} certonly --{0}{1}{1}'
                '(Alternatively, add a --installer flag. See https://eff.org/letsencrypt-plugins'
                '{1} and "--help plugins" for more information.)'.format(
                    req_auth, os.linesep, cli_command))

            raise errors.MissingCommandlineFlag(msg)
    else:
        need_inst = need_auth = False
    if verb == "certonly":
        need_auth = True
    elif verb in ("install", "enhance"):
        need_inst = True
        if config.authenticator:
            logger.warning(
                "Specifying an authenticator doesn't make sense when "
                "running Certbot with verb \"%s\"", verb)
    # Try to meet the user's request and/or ask them to pick plugins
    authenticator: Optional[interfaces.Authenticator] = None
    installer: Optional[interfaces.Installer] = None
    if verb == "run" and req_auth == req_inst:
        # Unless the user has explicitly asked for different auth/install,
        # only consider offering a single choice
        configurator = pick_configurator(config, req_inst, plugins)
        authenticator = cast(Optional[interfaces.Authenticator], configurator)
        installer = cast(Optional[interfaces.Installer], configurator)
    else:
        if need_inst or req_inst:
            installer = pick_installer(config, req_inst, plugins,
                                       installer_question)
        if need_auth:
            authenticator = pick_authenticator(config, req_auth, plugins)
    logger.debug("Selected authenticator %s and installer %s", authenticator,
                 installer)

    # Report on any failures
    if need_inst and not installer:
        diagnose_configurator_problem("installer", req_inst, plugins)
    if need_auth and not authenticator:
        diagnose_configurator_problem("authenticator", req_auth, plugins)

    record_chosen_plugins(config, plugins, authenticator, installer)
    return installer, authenticator
示例#2
0
 def test_noninteractive(self, mock_util):
     mock_util().menu.side_effect = errors.MissingCommandlineFlag("no vhost default")
     try:
         self._call(self.vhosts)
     except errors.MissingCommandlineFlag as e:
         self.assertTrue("vhost ambiguity" in e.message)
示例#3
0
def choose_configurator_plugins(config, plugins, verb):
    """
    Figure out which configurator we're going to use, modifies
    config.authenticator and config.installer strings to reflect that choice if
    necessary.

    :raises errors.PluginSelectionError if there was a problem

    :returns: (an `IAuthenticator` or None, an `IInstaller` or None)
    :rtype: tuple
    """

    req_auth, req_inst = cli_plugin_requests(config)

    # Which plugins do we need?
    if verb == "run":
        need_inst = need_auth = True
        from certbot.cli import cli_command
        if req_auth in noninstaller_plugins and not req_inst:
            msg = (
                'With the {0} plugin, you probably want to use the "certonly" command, eg:{1}'
                '{1}    {2} certonly --{0}{1}{1}'
                '(Alternatively, add a --installer flag. See https://eff.org/letsencrypt-plugins'
                '{1} and "--help plugins" for more information.)'.format(
                    req_auth, os.linesep, cli_command))

            raise errors.MissingCommandlineFlag(msg)
    else:
        need_inst = need_auth = False
    if verb == "certonly":
        need_auth = True
    if verb == "install":
        need_inst = True
        if config.authenticator:
            logger.warning(
                "Specifying an authenticator doesn't make sense in install mode"
            )

    # Try to meet the user's request and/or ask them to pick plugins
    authenticator = installer = None
    if verb == "run" and req_auth == req_inst:
        # Unless the user has explicitly asked for different auth/install,
        # only consider offering a single choice
        authenticator = installer = pick_configurator(config, req_inst,
                                                      plugins)
    else:
        if need_inst or req_inst:
            installer = pick_installer(config, req_inst, plugins)
        if need_auth:
            authenticator = pick_authenticator(config, req_auth, plugins)
    logger.debug("Selected authenticator %s and installer %s", authenticator,
                 installer)

    # Report on any failures
    if need_inst and not installer:
        diagnose_configurator_problem("installer", req_inst, plugins)
    if need_auth and not authenticator:
        diagnose_configurator_problem("authenticator", req_auth, plugins)

    record_chosen_plugins(config, plugins, authenticator, installer)
    return installer, authenticator
示例#4
0
def _vhost_menu(domain, vhosts):
    """Select an appropriate Apache Vhost.

    :param vhosts: Available Apache Virtual Hosts
    :type vhosts: :class:`list` of type `~obj.Vhost`

    :returns: Display tuple - ('code', tag')
    :rtype: `tuple`

    """
    # Free characters in the line of display text (9 is for ' | ' formatting)
    free_chars = display_util.WIDTH - len("HTTPS") - len("Enabled") - 9

    if free_chars < 2:
        logger.debug("Display size is too small for "
                     "certbot_apache.display_ops._vhost_menu()")
        # This runs the edge off the screen, but it doesn't cause an "error"
        filename_size = 1
        disp_name_size = 1
    else:
        # Filename is a bit more important and probably longer with 000-*
        filename_size = int(free_chars * .6)
        disp_name_size = free_chars - filename_size

    choices = []
    for vhost in vhosts:
        if len(vhost.get_names()) == 1:
            disp_name = next(iter(vhost.get_names()))
        elif len(vhost.get_names()) == 0:
            disp_name = ""
        else:
            disp_name = "Multiple Names"

        choices.append(
            "{fn:{fn_size}s} | {name:{name_size}s} | {https:5s} | "
            "{active:7s}".format(
                fn=os.path.basename(vhost.filep)[:filename_size],
                name=disp_name[:disp_name_size],
                https="HTTPS" if vhost.ssl else "",
                active="Enabled" if vhost.enabled else "",
                fn_size=filename_size,
                name_size=disp_name_size)
        )

    try:
        code, tag = zope.component.getUtility(interfaces.IDisplay).menu(
            "We were unable to find a vhost with a ServerName "
            "or Address of {0}.{1}Which virtual host would you "
            "like to choose?\n(note: conf files with multiple "
            "vhosts are not yet supported)".format(domain, os.linesep),
            choices, force_interactive=True)
    except errors.MissingCommandlineFlag:
        msg = (
            "Encountered vhost ambiguity when trying to find a vhost for "
            "{0} but was unable to ask for user "
            "guidance in non-interactive mode. Certbot may need "
            "vhosts to be explicitly labelled with ServerName or "
            "ServerAlias directives.".format(domain))
        logger.warning(msg)
        raise errors.MissingCommandlineFlag(msg)

    return code, tag