Compare commits
8 Commits
python37-t
...
nargs-defa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a09be984e1 | ||
|
|
3fe338a35a | ||
|
|
15904d24c0 | ||
|
|
43f2bfd6f1 | ||
|
|
cdf93de338 | ||
|
|
dd600db436 | ||
|
|
2564566e1c | ||
|
|
08378203df |
11
.travis.yml
11
.travis.yml
@@ -41,8 +41,9 @@ matrix:
|
|||||||
env: TOXENV=py34
|
env: TOXENV=py34
|
||||||
sudo: required
|
sudo: required
|
||||||
services: docker
|
services: docker
|
||||||
- python: "3.6"
|
- python: "3.7"
|
||||||
env: TOXENV=py36
|
dist: xenial
|
||||||
|
env: TOXENV=py37
|
||||||
sudo: required
|
sudo: required
|
||||||
services: docker
|
services: docker
|
||||||
- sudo: required
|
- sudo: required
|
||||||
@@ -77,8 +78,6 @@ sudo: false
|
|||||||
|
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
sources:
|
|
||||||
- augeas
|
|
||||||
packages: # Keep in sync with letsencrypt-auto-source/pieces/bootstrappers/deb_common.sh and Boulder.
|
packages: # Keep in sync with letsencrypt-auto-source/pieces/bootstrappers/deb_common.sh and Boulder.
|
||||||
- python-dev
|
- python-dev
|
||||||
- python-virtualenv
|
- python-virtualenv
|
||||||
@@ -90,10 +89,6 @@ addons:
|
|||||||
# For certbot-nginx integration testing
|
# For certbot-nginx integration testing
|
||||||
- nginx-light
|
- nginx-light
|
||||||
- openssl
|
- openssl
|
||||||
# for apacheconftest
|
|
||||||
- apache2
|
|
||||||
- libapache2-mod-wsgi
|
|
||||||
- libapache2-mod-macro
|
|
||||||
|
|
||||||
install: "travis_retry $(command -v pip || command -v pip3) install tox coveralls"
|
install: "travis_retry $(command -v pip || command -v pip3) install tox coveralls"
|
||||||
script:
|
script:
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ setup(
|
|||||||
'Programming Language :: Python :: 3.4',
|
'Programming Language :: Python :: 3.4',
|
||||||
'Programming Language :: Python :: 3.5',
|
'Programming Language :: Python :: 3.5',
|
||||||
'Programming Language :: Python :: 3.6',
|
'Programming Language :: Python :: 3.6',
|
||||||
|
'Programming Language :: Python :: 3.7',
|
||||||
'Topic :: Internet :: WWW/HTTP',
|
'Topic :: Internet :: WWW/HTTP',
|
||||||
'Topic :: Security',
|
'Topic :: Security',
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -165,6 +165,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||||||
self._autohsts = {} # type: Dict[str, Dict[str, Union[int, float]]]
|
self._autohsts = {} # type: Dict[str, Dict[str, Union[int, float]]]
|
||||||
|
|
||||||
# These will be set in the prepare function
|
# These will be set in the prepare function
|
||||||
|
self._prepared = False
|
||||||
self.parser = None
|
self.parser = None
|
||||||
self.version = version
|
self.version = version
|
||||||
self.vhosts = None
|
self.vhosts = None
|
||||||
@@ -249,6 +250,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||||||
logger.debug("Encountered error:", exc_info=True)
|
logger.debug("Encountered error:", exc_info=True)
|
||||||
raise errors.PluginError(
|
raise errors.PluginError(
|
||||||
"Unable to lock %s", self.conf("server-root"))
|
"Unable to lock %s", self.conf("server-root"))
|
||||||
|
self._prepared = True
|
||||||
|
|
||||||
def _check_aug_version(self):
|
def _check_aug_version(self):
|
||||||
""" Checks that we have recent enough version of libaugeas.
|
""" Checks that we have recent enough version of libaugeas.
|
||||||
@@ -2394,6 +2396,9 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
|
|||||||
continue
|
continue
|
||||||
nextstep = config["laststep"] + 1
|
nextstep = config["laststep"] + 1
|
||||||
if nextstep < len(constants.AUTOHSTS_STEPS):
|
if nextstep < len(constants.AUTOHSTS_STEPS):
|
||||||
|
# If installer hasn't been prepared yet, do it now
|
||||||
|
if not self._prepared:
|
||||||
|
self.prepare()
|
||||||
# Have not reached the max value yet
|
# Have not reached the max value yet
|
||||||
try:
|
try:
|
||||||
vhost = self.find_vhost_by_id(id_str)
|
vhost = self.find_vhost_by_id(id_str)
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ function Cleanup() {
|
|||||||
|
|
||||||
# if our environment asks us to enable modules, do our best!
|
# if our environment asks us to enable modules, do our best!
|
||||||
if [ "$1" = --debian-modules ] ; then
|
if [ "$1" = --debian-modules ] ; then
|
||||||
|
sudo apt-get install -y apache2
|
||||||
sudo apt-get install -y libapache2-mod-wsgi
|
sudo apt-get install -y libapache2-mod-wsgi
|
||||||
sudo apt-get install -y libapache2-mod-macro
|
sudo apt-get install -y libapache2-mod-macro
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,9 @@ class AutoHSTSTest(util.ApacheTest):
|
|||||||
|
|
||||||
@mock.patch("certbot_apache.constants.AUTOHSTS_FREQ", 0)
|
@mock.patch("certbot_apache.constants.AUTOHSTS_FREQ", 0)
|
||||||
@mock.patch("certbot_apache.configurator.ApacheConfigurator.restart")
|
@mock.patch("certbot_apache.configurator.ApacheConfigurator.restart")
|
||||||
def test_autohsts_increase(self, _mock_restart):
|
@mock.patch("certbot_apache.configurator.ApacheConfigurator.prepare")
|
||||||
|
def test_autohsts_increase(self, mock_prepare, _mock_restart):
|
||||||
|
self.config._prepared = False
|
||||||
maxage = "\"max-age={0}\""
|
maxage = "\"max-age={0}\""
|
||||||
initial_val = maxage.format(constants.AUTOHSTS_STEPS[0])
|
initial_val = maxage.format(constants.AUTOHSTS_STEPS[0])
|
||||||
inc_val = maxage.format(constants.AUTOHSTS_STEPS[1])
|
inc_val = maxage.format(constants.AUTOHSTS_STEPS[1])
|
||||||
@@ -69,6 +71,7 @@ class AutoHSTSTest(util.ApacheTest):
|
|||||||
# Verify increased value
|
# Verify increased value
|
||||||
self.assertEquals(self.get_autohsts_value(self.vh_truth[7].path),
|
self.assertEquals(self.get_autohsts_value(self.vh_truth[7].path),
|
||||||
inc_val)
|
inc_val)
|
||||||
|
self.assertTrue(mock_prepare.called)
|
||||||
|
|
||||||
@mock.patch("certbot_apache.configurator.ApacheConfigurator.restart")
|
@mock.patch("certbot_apache.configurator.ApacheConfigurator.restart")
|
||||||
@mock.patch("certbot_apache.configurator.ApacheConfigurator._autohsts_increase")
|
@mock.patch("certbot_apache.configurator.ApacheConfigurator._autohsts_increase")
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ setup(
|
|||||||
'Programming Language :: Python :: 3.4',
|
'Programming Language :: Python :: 3.4',
|
||||||
'Programming Language :: Python :: 3.5',
|
'Programming Language :: Python :: 3.5',
|
||||||
'Programming Language :: Python :: 3.6',
|
'Programming Language :: Python :: 3.6',
|
||||||
|
'Programming Language :: Python :: 3.7',
|
||||||
'Topic :: Internet :: WWW/HTTP',
|
'Topic :: Internet :: WWW/HTTP',
|
||||||
'Topic :: Security',
|
'Topic :: Security',
|
||||||
'Topic :: System :: Installation/Setup',
|
'Topic :: System :: Installation/Setup',
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ setup(
|
|||||||
'Programming Language :: Python :: 3.4',
|
'Programming Language :: Python :: 3.4',
|
||||||
'Programming Language :: Python :: 3.5',
|
'Programming Language :: Python :: 3.5',
|
||||||
'Programming Language :: Python :: 3.6',
|
'Programming Language :: Python :: 3.6',
|
||||||
|
'Programming Language :: Python :: 3.7',
|
||||||
'Topic :: Internet :: WWW/HTTP',
|
'Topic :: Internet :: WWW/HTTP',
|
||||||
'Topic :: Security',
|
'Topic :: Security',
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ setup(
|
|||||||
'Programming Language :: Python :: 3.4',
|
'Programming Language :: Python :: 3.4',
|
||||||
'Programming Language :: Python :: 3.5',
|
'Programming Language :: Python :: 3.5',
|
||||||
'Programming Language :: Python :: 3.6',
|
'Programming Language :: Python :: 3.6',
|
||||||
|
'Programming Language :: Python :: 3.7',
|
||||||
'Topic :: Internet :: WWW/HTTP',
|
'Topic :: Internet :: WWW/HTTP',
|
||||||
'Topic :: Security',
|
'Topic :: Security',
|
||||||
'Topic :: System :: Installation/Setup',
|
'Topic :: System :: Installation/Setup',
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ setup(
|
|||||||
'Programming Language :: Python :: 3.4',
|
'Programming Language :: Python :: 3.4',
|
||||||
'Programming Language :: Python :: 3.5',
|
'Programming Language :: Python :: 3.5',
|
||||||
'Programming Language :: Python :: 3.6',
|
'Programming Language :: Python :: 3.6',
|
||||||
|
'Programming Language :: Python :: 3.7',
|
||||||
'Topic :: Internet :: WWW/HTTP',
|
'Topic :: Internet :: WWW/HTTP',
|
||||||
'Topic :: Security',
|
'Topic :: Security',
|
||||||
'Topic :: System :: Installation/Setup',
|
'Topic :: System :: Installation/Setup',
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ setup(
|
|||||||
'Programming Language :: Python :: 3.4',
|
'Programming Language :: Python :: 3.4',
|
||||||
'Programming Language :: Python :: 3.5',
|
'Programming Language :: Python :: 3.5',
|
||||||
'Programming Language :: Python :: 3.6',
|
'Programming Language :: Python :: 3.6',
|
||||||
|
'Programming Language :: Python :: 3.7',
|
||||||
'Topic :: Internet :: WWW/HTTP',
|
'Topic :: Internet :: WWW/HTTP',
|
||||||
'Topic :: Security',
|
'Topic :: Security',
|
||||||
'Topic :: System :: Installation/Setup',
|
'Topic :: System :: Installation/Setup',
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ setup(
|
|||||||
'Programming Language :: Python :: 3.4',
|
'Programming Language :: Python :: 3.4',
|
||||||
'Programming Language :: Python :: 3.5',
|
'Programming Language :: Python :: 3.5',
|
||||||
'Programming Language :: Python :: 3.6',
|
'Programming Language :: Python :: 3.6',
|
||||||
|
'Programming Language :: Python :: 3.7',
|
||||||
'Topic :: Internet :: WWW/HTTP',
|
'Topic :: Internet :: WWW/HTTP',
|
||||||
'Topic :: Security',
|
'Topic :: Security',
|
||||||
'Topic :: System :: Installation/Setup',
|
'Topic :: System :: Installation/Setup',
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ setup(
|
|||||||
'Programming Language :: Python :: 3.4',
|
'Programming Language :: Python :: 3.4',
|
||||||
'Programming Language :: Python :: 3.5',
|
'Programming Language :: Python :: 3.5',
|
||||||
'Programming Language :: Python :: 3.6',
|
'Programming Language :: Python :: 3.6',
|
||||||
|
'Programming Language :: Python :: 3.7',
|
||||||
'Topic :: Internet :: WWW/HTTP',
|
'Topic :: Internet :: WWW/HTTP',
|
||||||
'Topic :: Security',
|
'Topic :: Security',
|
||||||
'Topic :: System :: Installation/Setup',
|
'Topic :: System :: Installation/Setup',
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ setup(
|
|||||||
'Programming Language :: Python :: 3.4',
|
'Programming Language :: Python :: 3.4',
|
||||||
'Programming Language :: Python :: 3.5',
|
'Programming Language :: Python :: 3.5',
|
||||||
'Programming Language :: Python :: 3.6',
|
'Programming Language :: Python :: 3.6',
|
||||||
|
'Programming Language :: Python :: 3.7',
|
||||||
'Topic :: Internet :: WWW/HTTP',
|
'Topic :: Internet :: WWW/HTTP',
|
||||||
'Topic :: Security',
|
'Topic :: Security',
|
||||||
'Topic :: System :: Installation/Setup',
|
'Topic :: System :: Installation/Setup',
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ setup(
|
|||||||
'Programming Language :: Python :: 3.4',
|
'Programming Language :: Python :: 3.4',
|
||||||
'Programming Language :: Python :: 3.5',
|
'Programming Language :: Python :: 3.5',
|
||||||
'Programming Language :: Python :: 3.6',
|
'Programming Language :: Python :: 3.6',
|
||||||
|
'Programming Language :: Python :: 3.7',
|
||||||
'Topic :: Internet :: WWW/HTTP',
|
'Topic :: Internet :: WWW/HTTP',
|
||||||
'Topic :: Security',
|
'Topic :: Security',
|
||||||
'Topic :: System :: Installation/Setup',
|
'Topic :: System :: Installation/Setup',
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ setup(
|
|||||||
'Programming Language :: Python :: 3.4',
|
'Programming Language :: Python :: 3.4',
|
||||||
'Programming Language :: Python :: 3.5',
|
'Programming Language :: Python :: 3.5',
|
||||||
'Programming Language :: Python :: 3.6',
|
'Programming Language :: Python :: 3.6',
|
||||||
|
'Programming Language :: Python :: 3.7',
|
||||||
'Topic :: Internet :: WWW/HTTP',
|
'Topic :: Internet :: WWW/HTTP',
|
||||||
'Topic :: Security',
|
'Topic :: Security',
|
||||||
'Topic :: System :: Installation/Setup',
|
'Topic :: System :: Installation/Setup',
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ setup(
|
|||||||
'Programming Language :: Python :: 3.4',
|
'Programming Language :: Python :: 3.4',
|
||||||
'Programming Language :: Python :: 3.5',
|
'Programming Language :: Python :: 3.5',
|
||||||
'Programming Language :: Python :: 3.6',
|
'Programming Language :: Python :: 3.6',
|
||||||
|
'Programming Language :: Python :: 3.7',
|
||||||
'Topic :: Internet :: WWW/HTTP',
|
'Topic :: Internet :: WWW/HTTP',
|
||||||
'Topic :: Security',
|
'Topic :: Security',
|
||||||
'Topic :: System :: Installation/Setup',
|
'Topic :: System :: Installation/Setup',
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ setup(
|
|||||||
'Programming Language :: Python :: 3.4',
|
'Programming Language :: Python :: 3.4',
|
||||||
'Programming Language :: Python :: 3.5',
|
'Programming Language :: Python :: 3.5',
|
||||||
'Programming Language :: Python :: 3.6',
|
'Programming Language :: Python :: 3.6',
|
||||||
|
'Programming Language :: Python :: 3.7',
|
||||||
'Topic :: Internet :: WWW/HTTP',
|
'Topic :: Internet :: WWW/HTTP',
|
||||||
'Topic :: Security',
|
'Topic :: Security',
|
||||||
'Topic :: System :: Installation/Setup',
|
'Topic :: System :: Installation/Setup',
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ setup(
|
|||||||
'Programming Language :: Python :: 3.4',
|
'Programming Language :: Python :: 3.4',
|
||||||
'Programming Language :: Python :: 3.5',
|
'Programming Language :: Python :: 3.5',
|
||||||
'Programming Language :: Python :: 3.6',
|
'Programming Language :: Python :: 3.6',
|
||||||
|
'Programming Language :: Python :: 3.7',
|
||||||
'Topic :: Internet :: WWW/HTTP',
|
'Topic :: Internet :: WWW/HTTP',
|
||||||
'Topic :: Security',
|
'Topic :: Security',
|
||||||
'Topic :: System :: Installation/Setup',
|
'Topic :: System :: Installation/Setup',
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ setup(
|
|||||||
'Programming Language :: Python :: 3.4',
|
'Programming Language :: Python :: 3.4',
|
||||||
'Programming Language :: Python :: 3.5',
|
'Programming Language :: Python :: 3.5',
|
||||||
'Programming Language :: Python :: 3.6',
|
'Programming Language :: Python :: 3.6',
|
||||||
|
'Programming Language :: Python :: 3.7',
|
||||||
'Topic :: Communications :: Email :: Mail Transport Agents',
|
'Topic :: Communications :: Email :: Mail Transport Agents',
|
||||||
'Topic :: Security',
|
'Topic :: Security',
|
||||||
'Topic :: System :: Installation/Setup',
|
'Topic :: System :: Installation/Setup',
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
import argparse
|
import argparse
|
||||||
import copy
|
import copy
|
||||||
|
import functools
|
||||||
import glob
|
import glob
|
||||||
import logging
|
import logging
|
||||||
import logging.handlers
|
import logging.handlers
|
||||||
@@ -120,7 +121,7 @@ More detailed help:
|
|||||||
|
|
||||||
|
|
||||||
# These argparse parameters should be removed when detecting defaults.
|
# These argparse parameters should be removed when detecting defaults.
|
||||||
ARGPARSE_PARAMS_TO_REMOVE = ("const", "nargs", "type",)
|
ARGPARSE_PARAMS_TO_REMOVE = ("const", "type",)
|
||||||
|
|
||||||
|
|
||||||
# These sets are used when to help detect options set by the user.
|
# These sets are used when to help detect options set by the user.
|
||||||
@@ -263,13 +264,23 @@ def option_was_set(option, value):
|
|||||||
return set_by_cli(option) or not has_default_value(option, value)
|
return set_by_cli(option) or not has_default_value(option, value)
|
||||||
|
|
||||||
|
|
||||||
|
def argparse_list(cast, values):
|
||||||
|
"""Wrap an argparse type function in a list (default: str)"""
|
||||||
|
if cast is None:
|
||||||
|
cast = str
|
||||||
|
return [cast(value) for value in values]
|
||||||
|
|
||||||
|
|
||||||
def argparse_type(variable):
|
def argparse_type(variable):
|
||||||
"""Return our argparse type function for a config variable (default: str)"""
|
"""Return our argparse type function for a config variable (default: str)"""
|
||||||
# pylint: disable=protected-access
|
# pylint: disable=protected-access
|
||||||
if helpful_parser is not None:
|
if helpful_parser is not None:
|
||||||
for action in helpful_parser.parser._actions:
|
for action in helpful_parser.parser._actions:
|
||||||
if action.type is not None and action.dest == variable:
|
if action.dest == variable:
|
||||||
return action.type
|
if action.nargs in ['N', '*', '+', argparse.REMAINDER]:
|
||||||
|
return functools.partial(argparse_list, action.type)
|
||||||
|
if action.type is not None:
|
||||||
|
return action.type
|
||||||
return str
|
return str
|
||||||
|
|
||||||
def read_file(filename, mode="rb"):
|
def read_file(filename, mode="rb"):
|
||||||
|
|||||||
@@ -620,6 +620,9 @@ class GenericUpdater(object):
|
|||||||
methods, and interfaces.GenericUpdater.register(InstallerClass) should
|
methods, and interfaces.GenericUpdater.register(InstallerClass) should
|
||||||
be called from the installer code.
|
be called from the installer code.
|
||||||
|
|
||||||
|
The plugins implementing this enhancement are responsible of handling
|
||||||
|
the saving of configuration checkpoints as well as other calls to
|
||||||
|
interface methods of `interfaces.IInstaller` such as prepare() and restart()
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
|
|||||||
@@ -1199,11 +1199,11 @@ def renew_cert(config, plugins, lineage):
|
|||||||
# In case of a renewal, reload server to pick up new certificate.
|
# In case of a renewal, reload server to pick up new certificate.
|
||||||
# In principle we could have a configuration option to inhibit this
|
# In principle we could have a configuration option to inhibit this
|
||||||
# from happening.
|
# from happening.
|
||||||
|
# Run deployer
|
||||||
updater.run_renewal_deployer(config, renewed_lineage, installer)
|
updater.run_renewal_deployer(config, renewed_lineage, installer)
|
||||||
installer.restart()
|
installer.restart()
|
||||||
notify("new certificate deployed with reload of {0} server; fullchain is {1}".format(
|
notify("new certificate deployed with reload of {0} server; fullchain is {1}".format(
|
||||||
config.installer, lineage.fullchain), pause=False)
|
config.installer, lineage.fullchain), pause=False)
|
||||||
# Run deployer
|
|
||||||
|
|
||||||
def certonly(config, plugins):
|
def certonly(config, plugins):
|
||||||
"""Authenticate & obtain cert, but do not install it.
|
"""Authenticate & obtain cert, but do not install it.
|
||||||
|
|||||||
@@ -88,7 +88,8 @@ class AutoHSTSEnhancement(object):
|
|||||||
|
|
||||||
The plugins implementing new style enhancements are responsible of handling
|
The plugins implementing new style enhancements are responsible of handling
|
||||||
the saving of configuration checkpoints as well as calling possible restarts
|
the saving of configuration checkpoints as well as calling possible restarts
|
||||||
of managed software themselves.
|
of managed software themselves. For update_autohsts method, the installer may
|
||||||
|
have to call prepare() to finalize the plugin initialization.
|
||||||
|
|
||||||
Methods:
|
Methods:
|
||||||
enable_autohsts is called when the header is initially installed using a
|
enable_autohsts is called when the header is initially installed using a
|
||||||
@@ -112,6 +113,10 @@ class AutoHSTSEnhancement(object):
|
|||||||
|
|
||||||
:param lineage: Certificate lineage object
|
:param lineage: Certificate lineage object
|
||||||
:type lineage: certbot.storage.RenewableCert
|
:type lineage: certbot.storage.RenewableCert
|
||||||
|
|
||||||
|
.. note:: prepare() method inherited from `interfaces.IPlugin` might need
|
||||||
|
to be called manually within implementation of this interface method
|
||||||
|
to finalize the plugin initialization.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
|
|||||||
@@ -39,6 +39,35 @@ def pick_authenticator(
|
|||||||
return pick_plugin(
|
return pick_plugin(
|
||||||
config, default, plugins, question, (interfaces.IAuthenticator,))
|
config, default, plugins, question, (interfaces.IAuthenticator,))
|
||||||
|
|
||||||
|
def get_unprepared_installer(config, plugins):
|
||||||
|
"""
|
||||||
|
Get an unprepared interfaces.IInstaller object.
|
||||||
|
|
||||||
|
:param certbot.interfaces.IConfig config: Configuration
|
||||||
|
:param certbot.plugins.disco.PluginsRegistry plugins:
|
||||||
|
All plugins registered as entry points.
|
||||||
|
|
||||||
|
:returns: Unprepared installer plugin or None
|
||||||
|
:rtype: IPlugin or None
|
||||||
|
"""
|
||||||
|
|
||||||
|
_, req_inst = cli_plugin_requests(config)
|
||||||
|
if not req_inst:
|
||||||
|
return None
|
||||||
|
installers = plugins.filter(lambda p_ep: p_ep.name == req_inst)
|
||||||
|
installers.init(config)
|
||||||
|
installers = installers.verify((interfaces.IInstaller,))
|
||||||
|
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)
|
||||||
|
else:
|
||||||
|
raise errors.PluginSelectionError(
|
||||||
|
"Could not select or initialize the requested installer %s." % req_inst)
|
||||||
|
|
||||||
def pick_plugin(config, default, plugins, question, ifaces):
|
def pick_plugin(config, default, plugins, question, ifaces):
|
||||||
"""Pick plugin.
|
"""Pick plugin.
|
||||||
|
|||||||
@@ -6,10 +6,13 @@ import unittest
|
|||||||
import mock
|
import mock
|
||||||
import zope.component
|
import zope.component
|
||||||
|
|
||||||
|
from certbot import errors
|
||||||
|
from certbot import interfaces
|
||||||
|
|
||||||
from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module
|
from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module
|
||||||
from certbot.display import util as display_util
|
from certbot.display import util as display_util
|
||||||
|
from certbot.plugins.disco import PluginsRegistry
|
||||||
from certbot.tests import util as test_util
|
from certbot.tests import util as test_util
|
||||||
from certbot import interfaces
|
|
||||||
|
|
||||||
|
|
||||||
class ConveniencePickPluginTest(unittest.TestCase):
|
class ConveniencePickPluginTest(unittest.TestCase):
|
||||||
@@ -170,5 +173,48 @@ class ChoosePluginTest(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertTrue("default" in mock_util().menu.call_args[1])
|
self.assertTrue("default" in mock_util().menu.call_args[1])
|
||||||
|
|
||||||
|
class GetUnpreparedInstallerTest(test_util.ConfigTestCase):
|
||||||
|
"""Tests for certbot.plugins.selection.get_unprepared_installer."""
|
||||||
|
|
||||||
|
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,
|
||||||
|
})
|
||||||
|
|
||||||
|
def _call(self):
|
||||||
|
from certbot.plugins.selection import get_unprepared_installer
|
||||||
|
return get_unprepared_installer(self.config, self.plugins)
|
||||||
|
|
||||||
|
def test_no_installer_defined(self):
|
||||||
|
self.config.configurator = None
|
||||||
|
self.assertEquals(self._call(), None)
|
||||||
|
|
||||||
|
def test_no_available_installers(self):
|
||||||
|
self.config.configurator = "apache"
|
||||||
|
self.plugins = PluginsRegistry({})
|
||||||
|
self.assertRaises(errors.PluginSelectionError, self._call)
|
||||||
|
|
||||||
|
def test_get_plugin(self):
|
||||||
|
self.config.configurator = "apache"
|
||||||
|
installer = self._call()
|
||||||
|
self.assertTrue(installer is self.mock_apache_plugin)
|
||||||
|
|
||||||
|
def test_multiple_installers_returned(self):
|
||||||
|
self.config.configurator = "apache"
|
||||||
|
# Two plugins with the same name
|
||||||
|
self.mock_apache_fail_ep.name = "apache"
|
||||||
|
self.assertRaises(errors.PluginSelectionError, self._call)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main() # pragma: no cover
|
unittest.main() # pragma: no cover
|
||||||
|
|||||||
@@ -1493,17 +1493,17 @@ class MainTest(test_util.ConfigTestCase): # pylint: disable=too-many-public-met
|
|||||||
self.assertTrue(mock_handle.called)
|
self.assertTrue(mock_handle.called)
|
||||||
|
|
||||||
@mock.patch('certbot.plugins.selection.choose_configurator_plugins')
|
@mock.patch('certbot.plugins.selection.choose_configurator_plugins')
|
||||||
def test_plugin_selection_error(self, mock_choose):
|
@mock.patch('certbot.updater._run_updaters')
|
||||||
|
def test_plugin_selection_error(self, mock_run, mock_choose):
|
||||||
mock_choose.side_effect = errors.PluginSelectionError
|
mock_choose.side_effect = errors.PluginSelectionError
|
||||||
self.assertRaises(errors.PluginSelectionError, main.renew_cert,
|
self.assertRaises(errors.PluginSelectionError, main.renew_cert,
|
||||||
None, None, None)
|
None, None, None)
|
||||||
|
|
||||||
with mock.patch('certbot.updater.logger.warning') as mock_log:
|
self.config.dry_run = False
|
||||||
self.config.dry_run = False
|
updater.run_generic_updaters(self.config, None, None)
|
||||||
updater.run_generic_updaters(self.config, None, None)
|
# Make sure we're returning None, and hence not trying to run the
|
||||||
self.assertTrue(mock_log.called)
|
# without installer
|
||||||
self.assertTrue("Could not choose appropriate plugin for updaters"
|
self.assertFalse(mock_run.called)
|
||||||
in mock_log.call_args[0][0])
|
|
||||||
|
|
||||||
|
|
||||||
class UnregisterTest(unittest.TestCase):
|
class UnregisterTest(unittest.TestCase):
|
||||||
|
|||||||
@@ -23,13 +23,15 @@ class RenewUpdaterTest(test_util.ConfigTestCase):
|
|||||||
|
|
||||||
@mock.patch('certbot.main._get_and_save_cert')
|
@mock.patch('certbot.main._get_and_save_cert')
|
||||||
@mock.patch('certbot.plugins.selection.choose_configurator_plugins')
|
@mock.patch('certbot.plugins.selection.choose_configurator_plugins')
|
||||||
|
@mock.patch('certbot.plugins.selection.get_unprepared_installer')
|
||||||
@test_util.patch_get_utility()
|
@test_util.patch_get_utility()
|
||||||
def test_server_updates(self, _, mock_select, mock_getsave):
|
def test_server_updates(self, _, mock_geti, mock_select, mock_getsave):
|
||||||
mock_getsave.return_value = mock.MagicMock()
|
mock_getsave.return_value = mock.MagicMock()
|
||||||
mock_generic_updater = self.generic_updater
|
mock_generic_updater = self.generic_updater
|
||||||
|
|
||||||
# Generic Updater
|
# Generic Updater
|
||||||
mock_select.return_value = (mock_generic_updater, None)
|
mock_select.return_value = (mock_generic_updater, None)
|
||||||
|
mock_geti.return_value = mock_generic_updater
|
||||||
with mock.patch('certbot.main._init_le_client'):
|
with mock.patch('certbot.main._init_le_client'):
|
||||||
main.renew_cert(self.config, None, mock.MagicMock())
|
main.renew_cert(self.config, None, mock.MagicMock())
|
||||||
self.assertTrue(mock_generic_updater.restart.called)
|
self.assertTrue(mock_generic_updater.restart.called)
|
||||||
@@ -62,9 +64,9 @@ class RenewUpdaterTest(test_util.ConfigTestCase):
|
|||||||
self.assertEquals(mock_log.call_args[0][0],
|
self.assertEquals(mock_log.call_args[0][0],
|
||||||
"Skipping renewal deployer in dry-run mode.")
|
"Skipping renewal deployer in dry-run mode.")
|
||||||
|
|
||||||
@mock.patch('certbot.plugins.selection.choose_configurator_plugins')
|
@mock.patch('certbot.plugins.selection.get_unprepared_installer')
|
||||||
def test_enhancement_updates(self, mock_select):
|
def test_enhancement_updates(self, mock_geti):
|
||||||
mock_select.return_value = (self.mockinstaller, None)
|
mock_geti.return_value = self.mockinstaller
|
||||||
updater.run_generic_updaters(self.config, mock.MagicMock(), None)
|
updater.run_generic_updaters(self.config, mock.MagicMock(), None)
|
||||||
self.assertTrue(self.mockinstaller.update_autohsts.called)
|
self.assertTrue(self.mockinstaller.update_autohsts.called)
|
||||||
self.assertEqual(self.mockinstaller.update_autohsts.call_count, 1)
|
self.assertEqual(self.mockinstaller.update_autohsts.call_count, 1)
|
||||||
@@ -74,10 +76,10 @@ class RenewUpdaterTest(test_util.ConfigTestCase):
|
|||||||
self.mockinstaller)
|
self.mockinstaller)
|
||||||
self.assertTrue(self.mockinstaller.deploy_autohsts.called)
|
self.assertTrue(self.mockinstaller.deploy_autohsts.called)
|
||||||
|
|
||||||
@mock.patch('certbot.plugins.selection.choose_configurator_plugins')
|
@mock.patch('certbot.plugins.selection.get_unprepared_installer')
|
||||||
def test_enhancement_updates_not_called(self, mock_select):
|
def test_enhancement_updates_not_called(self, mock_geti):
|
||||||
self.config.disable_renew_updates = True
|
self.config.disable_renew_updates = True
|
||||||
mock_select.return_value = (self.mockinstaller, None)
|
mock_geti.return_value = self.mockinstaller
|
||||||
updater.run_generic_updaters(self.config, mock.MagicMock(), None)
|
updater.run_generic_updaters(self.config, mock.MagicMock(), None)
|
||||||
self.assertFalse(self.mockinstaller.update_autohsts.called)
|
self.assertFalse(self.mockinstaller.update_autohsts.called)
|
||||||
|
|
||||||
@@ -87,8 +89,8 @@ class RenewUpdaterTest(test_util.ConfigTestCase):
|
|||||||
self.mockinstaller)
|
self.mockinstaller)
|
||||||
self.assertFalse(self.mockinstaller.deploy_autohsts.called)
|
self.assertFalse(self.mockinstaller.deploy_autohsts.called)
|
||||||
|
|
||||||
@mock.patch('certbot.plugins.selection.choose_configurator_plugins')
|
@mock.patch('certbot.plugins.selection.get_unprepared_installer')
|
||||||
def test_enhancement_no_updater(self, mock_select):
|
def test_enhancement_no_updater(self, mock_geti):
|
||||||
FAKEINDEX = [
|
FAKEINDEX = [
|
||||||
{
|
{
|
||||||
"name": "Test",
|
"name": "Test",
|
||||||
@@ -98,7 +100,7 @@ class RenewUpdaterTest(test_util.ConfigTestCase):
|
|||||||
"enable_function": "enable_autohsts"
|
"enable_function": "enable_autohsts"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
mock_select.return_value = (self.mockinstaller, None)
|
mock_geti.return_value = self.mockinstaller
|
||||||
with mock.patch("certbot.plugins.enhancements._INDEX", FAKEINDEX):
|
with mock.patch("certbot.plugins.enhancements._INDEX", FAKEINDEX):
|
||||||
updater.run_generic_updaters(self.config, mock.MagicMock(), None)
|
updater.run_generic_updaters(self.config, mock.MagicMock(), None)
|
||||||
self.assertFalse(self.mockinstaller.update_autohsts.called)
|
self.assertFalse(self.mockinstaller.update_autohsts.called)
|
||||||
|
|||||||
@@ -28,13 +28,13 @@ def run_generic_updaters(config, lineage, plugins):
|
|||||||
logger.debug("Skipping updaters in dry-run mode.")
|
logger.debug("Skipping updaters in dry-run mode.")
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
# installers are used in auth mode to determine domain names
|
installer = plug_sel.get_unprepared_installer(config, plugins)
|
||||||
installer, _ = plug_sel.choose_configurator_plugins(config, plugins, "certonly")
|
except errors.Error as e:
|
||||||
except errors.PluginSelectionError as e:
|
|
||||||
logger.warning("Could not choose appropriate plugin for updaters: %s", e)
|
logger.warning("Could not choose appropriate plugin for updaters: %s", e)
|
||||||
return
|
return
|
||||||
_run_updaters(lineage, installer, config)
|
if installer:
|
||||||
_run_enhancement_updaters(lineage, installer, config)
|
_run_updaters(lineage, installer, config)
|
||||||
|
_run_enhancement_updaters(lineage, installer, config)
|
||||||
|
|
||||||
def run_renewal_deployer(config, lineage, installer):
|
def run_renewal_deployer(config, lineage, installer):
|
||||||
"""Helper function to run deployer interface method if supported by the used
|
"""Helper function to run deployer interface method if supported by the used
|
||||||
|
|||||||
@@ -1092,9 +1092,9 @@ idna==2.5 \
|
|||||||
ipaddress==1.0.16 \
|
ipaddress==1.0.16 \
|
||||||
--hash=sha256:935712800ce4760701d89ad677666cd52691fd2f6f0b340c8b4239a3c17988a5 \
|
--hash=sha256:935712800ce4760701d89ad677666cd52691fd2f6f0b340c8b4239a3c17988a5 \
|
||||||
--hash=sha256:5a3182b322a706525c46282ca6f064d27a02cffbd449f9f47416f1dc96aa71b0
|
--hash=sha256:5a3182b322a706525c46282ca6f064d27a02cffbd449f9f47416f1dc96aa71b0
|
||||||
josepy==1.0.1 \
|
josepy==1.1.0 \
|
||||||
--hash=sha256:354a3513038a38bbcd27c97b7c68a8f3dfaff0a135b20a92c6db4cc4ea72915e \
|
--hash=sha256:1309a25aac3caeff5239729c58ff9b583f7d022ffdb1553406ddfc8e5b52b76e \
|
||||||
--hash=sha256:9f48b88ca37f0244238b1cc77723989f7c54f7b90b2eee6294390bacfe870acc
|
--hash=sha256:fb5c62c77d26e04df29cb5ecd01b9ce69b6fcc9e521eb1ca193b7faa2afa7086
|
||||||
linecache2==1.0.0 \
|
linecache2==1.0.0 \
|
||||||
--hash=sha256:e78be9c0a0dfcbac712fe04fbf92b96cddae80b1b842f24248214c8496f006ef \
|
--hash=sha256:e78be9c0a0dfcbac712fe04fbf92b96cddae80b1b842f24248214c8496f006ef \
|
||||||
--hash=sha256:4b26ff4e7110db76eeb6f5a7b64a82623839d595c2038eeda662f2a2db78e97c
|
--hash=sha256:4b26ff4e7110db76eeb6f5a7b64a82623839d595c2038eeda662f2a2db78e97c
|
||||||
|
|||||||
@@ -96,9 +96,9 @@ idna==2.5 \
|
|||||||
ipaddress==1.0.16 \
|
ipaddress==1.0.16 \
|
||||||
--hash=sha256:935712800ce4760701d89ad677666cd52691fd2f6f0b340c8b4239a3c17988a5 \
|
--hash=sha256:935712800ce4760701d89ad677666cd52691fd2f6f0b340c8b4239a3c17988a5 \
|
||||||
--hash=sha256:5a3182b322a706525c46282ca6f064d27a02cffbd449f9f47416f1dc96aa71b0
|
--hash=sha256:5a3182b322a706525c46282ca6f064d27a02cffbd449f9f47416f1dc96aa71b0
|
||||||
josepy==1.0.1 \
|
josepy==1.1.0 \
|
||||||
--hash=sha256:354a3513038a38bbcd27c97b7c68a8f3dfaff0a135b20a92c6db4cc4ea72915e \
|
--hash=sha256:1309a25aac3caeff5239729c58ff9b583f7d022ffdb1553406ddfc8e5b52b76e \
|
||||||
--hash=sha256:9f48b88ca37f0244238b1cc77723989f7c54f7b90b2eee6294390bacfe870acc
|
--hash=sha256:fb5c62c77d26e04df29cb5ecd01b9ce69b6fcc9e521eb1ca193b7faa2afa7086
|
||||||
linecache2==1.0.0 \
|
linecache2==1.0.0 \
|
||||||
--hash=sha256:e78be9c0a0dfcbac712fe04fbf92b96cddae80b1b842f24248214c8496f006ef \
|
--hash=sha256:e78be9c0a0dfcbac712fe04fbf92b96cddae80b1b842f24248214c8496f006ef \
|
||||||
--hash=sha256:4b26ff4e7110db76eeb6f5a7b64a82623839d595c2038eeda662f2a2db78e97c
|
--hash=sha256:4b26ff4e7110db76eeb6f5a7b64a82623839d595c2038eeda662f2a2db78e97c
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ setup(
|
|||||||
'Programming Language :: Python :: 3.4',
|
'Programming Language :: Python :: 3.4',
|
||||||
'Programming Language :: Python :: 3.5',
|
'Programming Language :: Python :: 3.5',
|
||||||
'Programming Language :: Python :: 3.6',
|
'Programming Language :: Python :: 3.6',
|
||||||
|
'Programming Language :: Python :: 3.7',
|
||||||
'Topic :: Internet :: WWW/HTTP',
|
'Topic :: Internet :: WWW/HTTP',
|
||||||
'Topic :: Security',
|
'Topic :: Security',
|
||||||
'Topic :: System :: Installation/Setup',
|
'Topic :: System :: Installation/Setup',
|
||||||
|
|||||||
1
setup.py
1
setup.py
@@ -99,6 +99,7 @@ setup(
|
|||||||
'Programming Language :: Python :: 3.4',
|
'Programming Language :: Python :: 3.4',
|
||||||
'Programming Language :: Python :: 3.5',
|
'Programming Language :: Python :: 3.5',
|
||||||
'Programming Language :: Python :: 3.6',
|
'Programming Language :: Python :: 3.6',
|
||||||
|
'Programming Language :: Python :: 3.7',
|
||||||
'Topic :: Internet :: WWW/HTTP',
|
'Topic :: Internet :: WWW/HTTP',
|
||||||
'Topic :: Security',
|
'Topic :: Security',
|
||||||
'Topic :: System :: Installation/Setup',
|
'Topic :: System :: Installation/Setup',
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ ipython==5.5.0
|
|||||||
ipython-genutils==0.2.0
|
ipython-genutils==0.2.0
|
||||||
Jinja2==2.9.6
|
Jinja2==2.9.6
|
||||||
jmespath==0.9.3
|
jmespath==0.9.3
|
||||||
josepy==1.0.1
|
josepy==1.1.0
|
||||||
logger==1.4
|
logger==1.4
|
||||||
logilab-common==1.4.1
|
logilab-common==1.4.1
|
||||||
MarkupSafe==1.0
|
MarkupSafe==1.0
|
||||||
@@ -51,7 +51,7 @@ pytest-forked==0.2
|
|||||||
pytest-xdist==1.20.1
|
pytest-xdist==1.20.1
|
||||||
python-dateutil==2.6.1
|
python-dateutil==2.6.1
|
||||||
python-digitalocean==1.11
|
python-digitalocean==1.11
|
||||||
PyYAML==3.12
|
PyYAML==3.13
|
||||||
repoze.sphinx.autointerface==0.8
|
repoze.sphinx.autointerface==0.8
|
||||||
requests-file==1.4.2
|
requests-file==1.4.2
|
||||||
requests-toolbelt==0.8.0
|
requests-toolbelt==0.8.0
|
||||||
|
|||||||
22
tox.ini
22
tox.ini
@@ -14,7 +14,8 @@ pip_install = {toxinidir}/tools/pip_install_editable.sh
|
|||||||
# before the script moves on to the next package. All dependencies are pinned
|
# before the script moves on to the next package. All dependencies are pinned
|
||||||
# to a specific version for increased stability for developers.
|
# to a specific version for increased stability for developers.
|
||||||
install_and_test = {toxinidir}/tools/install_and_test.sh
|
install_and_test = {toxinidir}/tools/install_and_test.sh
|
||||||
python37_compatible_dns_packages =
|
dns_packages =
|
||||||
|
certbot-dns-cloudflare \
|
||||||
certbot-dns-cloudxns \
|
certbot-dns-cloudxns \
|
||||||
certbot-dns-digitalocean \
|
certbot-dns-digitalocean \
|
||||||
certbot-dns-dnsimple \
|
certbot-dns-dnsimple \
|
||||||
@@ -24,22 +25,14 @@ python37_compatible_dns_packages =
|
|||||||
certbot-dns-nsone \
|
certbot-dns-nsone \
|
||||||
certbot-dns-rfc2136 \
|
certbot-dns-rfc2136 \
|
||||||
certbot-dns-route53
|
certbot-dns-route53
|
||||||
dns_packages =
|
all_packages =
|
||||||
certbot-dns-cloudflare \
|
|
||||||
{[base]python37_compatible_dns_packages}
|
|
||||||
nondns_packages =
|
|
||||||
acme[dev] \
|
acme[dev] \
|
||||||
.[dev] \
|
.[dev] \
|
||||||
certbot-apache \
|
certbot-apache \
|
||||||
|
{[base]dns_packages} \
|
||||||
certbot-nginx \
|
certbot-nginx \
|
||||||
certbot-postfix \
|
certbot-postfix \
|
||||||
letshelp-certbot
|
letshelp-certbot
|
||||||
python37_compatible_packages =
|
|
||||||
{[base]nondns_packages} \
|
|
||||||
{[base]python37_compatible_dns_packages}
|
|
||||||
all_packages =
|
|
||||||
{[base]nondns_packages} \
|
|
||||||
{[base]dns_packages}
|
|
||||||
install_packages =
|
install_packages =
|
||||||
{toxinidir}/tools/pip_install_editable.sh {[base]all_packages}
|
{toxinidir}/tools/pip_install_editable.sh {[base]all_packages}
|
||||||
source_paths =
|
source_paths =
|
||||||
@@ -69,13 +62,6 @@ commands =
|
|||||||
setenv =
|
setenv =
|
||||||
PYTHONHASHSEED = 0
|
PYTHONHASHSEED = 0
|
||||||
|
|
||||||
[testenv:py37]
|
|
||||||
commands =
|
|
||||||
{[base]install_and_test} {[base]python37_compatible_packages}
|
|
||||||
python tests/lock_test.py
|
|
||||||
setenv =
|
|
||||||
{[testenv]setenv}
|
|
||||||
|
|
||||||
[testenv:py27-oldest]
|
[testenv:py27-oldest]
|
||||||
commands =
|
commands =
|
||||||
{[testenv]commands}
|
{[testenv]commands}
|
||||||
|
|||||||
Reference in New Issue
Block a user