Merge branch 'master' into windows-auto-update

# Conflicts:
#	windows-installer/renew-up.ps1
This commit is contained in:
Adrien Ferrand 2019-11-19 15:05:51 +01:00
commit c02c14e18e
103 changed files with 560 additions and 1244 deletions

View file

@ -41,7 +41,7 @@ load-plugins=linter_plugin
# --enable=similarities". If you want to run only the classes checker, but have
# no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W"
disable=fixme,locally-disabled,locally-enabled,abstract-class-not-used,abstract-class-little-used,bad-continuation,too-few-public-methods,no-self-use,invalid-name,too-many-instance-attributes,cyclic-import,duplicate-code
disable=fixme,locally-disabled,locally-enabled,abstract-class-not-used,abstract-class-little-used,bad-continuation,no-self-use,invalid-name,cyclic-import,duplicate-code,design
# abstract-class-not-used cannot be disabled locally (at least in
# pylint 1.4.1), same for abstract-class-little-used
@ -297,40 +297,6 @@ valid-classmethod-first-arg=cls
valid-metaclass-classmethod-first-arg=mcs
[DESIGN]
# Maximum number of arguments for function / method
max-args=6
# Argument names that match this expression will be ignored. Default to name
# with leading underscore
ignored-argument-names=(unused)?_.*|dummy
# Maximum number of locals for function / method body
max-locals=15
# Maximum number of return / yield for function / method body
max-returns=6
# Maximum number of branch for function / method body
max-branches=12
# Maximum number of statements in function / method body
max-statements=50
# Maximum number of parents for a class (see R0901).
max-parents=12
# Maximum number of attributes for a class (see R0902).
max-attributes=7
# Minimum number of public methods for a class (see R0903).
min-public-methods=2
# Maximum number of public methods for a class (see R0904).
max-public-methods=20
[EXCEPTIONS]
# Exceptions that will emit a warning when being caught. Defaults to

View file

@ -10,13 +10,19 @@ Certbot adheres to [Semantic Versioning](https://semver.org/).
### Changed
* certbot-auto has deprecated support for systems using OpenSSL 1.0.1 that are
not running on x86-64. This primarily affects RHEL 6 based systems.
* Certbot's `config_changes` subcommand has been removed
* `certbot.plugins.common.TLSSNI01` has been removed.
* Deprecated attributes related to the TLS-SNI-01 challenge in
`acme.challenges` and `acme.standalone`
have been removed.
* The functions `certbot.client.view_config_changes`,
`certbot.main.config_changes`,
`certbot.plugins.common.Installer.view_config_changes`,
`certbot.reverter.Reverter.view_config_changes`, and
`certbot.util.get_systemd_os_info` have been removed
* Certbot's `register --update-registration` subcommand has been removed
### Fixed

View file

@ -21,30 +21,3 @@ for mod in list(sys.modules):
# preserved (acme.jose.* is josepy.*)
if mod == 'josepy' or mod.startswith('josepy.'):
sys.modules['acme.' + mod.replace('josepy', 'jose', 1)] = sys.modules[mod]
# This class takes a similar approach to the cryptography project to deprecate attributes
# in public modules. See the _ModuleWithDeprecation class here:
# https://github.com/pyca/cryptography/blob/91105952739442a74582d3e62b3d2111365b0dc7/src/cryptography/utils.py#L129
class _TLSSNI01DeprecationModule(object):
"""
Internal class delegating to a module, and displaying warnings when
attributes related to TLS-SNI-01 are accessed.
"""
def __init__(self, module):
self.__dict__['_module'] = module
def __getattr__(self, attr):
if 'TLSSNI01' in attr or attr == 'BaseRequestHandlerWithLogging':
warnings.warn('{0} attribute is deprecated, and will be removed soon.'.format(attr),
DeprecationWarning, stacklevel=2)
return getattr(self._module, attr)
def __setattr__(self, attr, value): # pragma: no cover
setattr(self._module, attr, value)
def __delattr__(self, attr): # pragma: no cover
delattr(self._module, attr)
def __dir__(self): # pragma: no cover
return ['_module'] + dir(self._module)

View file

@ -3,19 +3,13 @@ import abc
import functools
import hashlib
import logging
import socket
import sys
from cryptography.hazmat.primitives import hashes # type: ignore
import josepy as jose
import OpenSSL
import requests
import six
from acme import errors
from acme import crypto_util
from acme import fields
from acme import _TLSSNI01DeprecationModule
logger = logging.getLogger(__name__)
@ -237,7 +231,7 @@ class DNS01Response(KeyAuthorizationChallengeResponse):
return verified
@Challenge.register # pylint: disable=too-many-ancestors
@Challenge.register
class DNS01(KeyAuthorizationChallenge):
"""ACME dns-01 challenge."""
response_cls = DNS01Response
@ -327,7 +321,7 @@ class HTTP01Response(KeyAuthorizationChallengeResponse):
return True
@Challenge.register # pylint: disable=too-many-ancestors
@Challenge.register
class HTTP01(KeyAuthorizationChallenge):
"""ACME http-01 challenge."""
response_cls = HTTP01Response
@ -367,148 +361,6 @@ class HTTP01(KeyAuthorizationChallenge):
return self.key_authorization(account_key)
@ChallengeResponse.register
class TLSSNI01Response(KeyAuthorizationChallengeResponse):
"""ACME tls-sni-01 challenge response."""
typ = "tls-sni-01"
DOMAIN_SUFFIX = b".acme.invalid"
"""Domain name suffix."""
PORT = 443
"""Verification port as defined by the protocol.
You can override it (e.g. for testing) by passing ``port`` to
`simple_verify`.
"""
@property
def z(self): # pylint: disable=invalid-name
"""``z`` value used for verification.
:rtype bytes:
"""
return hashlib.sha256(
self.key_authorization.encode("utf-8")).hexdigest().lower().encode()
@property
def z_domain(self):
"""Domain name used for verification, generated from `z`.
:rtype bytes:
"""
return self.z[:32] + b'.' + self.z[32:] + self.DOMAIN_SUFFIX
def gen_cert(self, key=None, bits=2048):
"""Generate tls-sni-01 certificate.
:param OpenSSL.crypto.PKey key: Optional private key used in
certificate generation. If not provided (``None``), then
fresh key will be generated.
:param int bits: Number of bits for newly generated key.
:rtype: `tuple` of `OpenSSL.crypto.X509` and `OpenSSL.crypto.PKey`
"""
if key is None:
key = OpenSSL.crypto.PKey()
key.generate_key(OpenSSL.crypto.TYPE_RSA, bits)
return crypto_util.gen_ss_cert(key, [
# z_domain is too big to fit into CN, hence first dummy domain
'dummy', self.z_domain.decode()], force_san=True), key
def probe_cert(self, domain, **kwargs):
"""Probe tls-sni-01 challenge certificate.
:param unicode domain:
"""
# TODO: domain is not necessary if host is provided
if "host" not in kwargs:
host = socket.gethostbyname(domain)
logger.debug('%s resolved to %s', domain, host)
kwargs["host"] = host
kwargs.setdefault("port", self.PORT)
kwargs["name"] = self.z_domain
# TODO: try different methods?
return crypto_util.probe_sni(**kwargs)
def verify_cert(self, cert):
"""Verify tls-sni-01 challenge certificate.
:param OpensSSL.crypto.X509 cert: Challenge certificate.
:returns: Whether the certificate was successfully verified.
:rtype: bool
"""
# pylint: disable=protected-access
sans = crypto_util._pyopenssl_cert_or_req_san(cert)
logger.debug('Certificate %s. SANs: %s', cert.digest('sha256'), sans)
return self.z_domain.decode() in sans
def simple_verify(self, chall, domain, account_public_key,
cert=None, **kwargs):
"""Simple verify.
Verify ``validation`` using ``account_public_key``, optionally
probe tls-sni-01 certificate and check using `verify_cert`.
:param .challenges.TLSSNI01 chall: Corresponding challenge.
:param str domain: Domain name being validated.
:param JWK account_public_key:
:param OpenSSL.crypto.X509 cert: Optional certificate. If not
provided (``None``) certificate will be retrieved using
`probe_cert`.
:param int port: Port used to probe the certificate.
:returns: ``True`` iff client's control of the domain has been
verified.
:rtype: bool
"""
if not self.verify(chall, account_public_key):
logger.debug("Verification of key authorization in response failed")
return False
if cert is None:
try:
cert = self.probe_cert(domain=domain, **kwargs)
except errors.Error as error:
logger.debug(str(error), exc_info=True)
return False
return self.verify_cert(cert)
@Challenge.register # pylint: disable=too-many-ancestors
class TLSSNI01(KeyAuthorizationChallenge):
"""ACME tls-sni-01 challenge."""
response_cls = TLSSNI01Response
typ = response_cls.typ
# boulder#962, ietf-wg-acme#22
#n = jose.Field("n", encoder=int, decoder=int)
def validation(self, account_key, **kwargs):
"""Generate validation.
:param JWK account_key:
:param OpenSSL.crypto.PKey cert_key: Optional private key used
in certificate generation. If not provided (``None``), then
fresh key will be generated.
:rtype: `tuple` of `OpenSSL.crypto.X509` and `OpenSSL.crypto.PKey`
"""
return self.response(account_key).gen_cert(key=kwargs.get('cert_key'))
@ChallengeResponse.register
class TLSALPN01Response(KeyAuthorizationChallengeResponse):
"""ACME TLS-ALPN-01 challenge response.
@ -520,7 +372,7 @@ class TLSALPN01Response(KeyAuthorizationChallengeResponse):
typ = "tls-alpn-01"
@Challenge.register # pylint: disable=too-many-ancestors
@Challenge.register
class TLSALPN01(KeyAuthorizationChallenge):
"""ACME tls-alpn-01 challenge.
@ -617,7 +469,3 @@ class DNSResponse(ChallengeResponse):
"""
return chall.check_validation(self.validation, account_public_key)
# Patching ourselves to warn about TLS-SNI challenge deprecation and removal.
sys.modules[__name__] = _TLSSNI01DeprecationModule(sys.modules[__name__])

View file

@ -3,12 +3,10 @@ import unittest
import josepy as jose
import mock
import OpenSSL
import requests
from six.moves.urllib import parse as urllib_parse # pylint: disable=relative-import
from acme import errors
from acme import test_util
CERT = test_util.load_comparable_cert('cert.pem')
@ -77,7 +75,6 @@ class KeyAuthorizationChallengeResponseTest(unittest.TestCase):
class DNS01ResponseTest(unittest.TestCase):
# pylint: disable=too-many-instance-attributes
def setUp(self):
from acme.challenges import DNS01Response
@ -149,7 +146,6 @@ class DNS01Test(unittest.TestCase):
class HTTP01ResponseTest(unittest.TestCase):
# pylint: disable=too-many-instance-attributes
def setUp(self):
from acme.challenges import HTTP01Response
@ -259,152 +255,7 @@ class HTTP01Test(unittest.TestCase):
self.msg.update(token=b'..').good_token)
class TLSSNI01ResponseTest(unittest.TestCase):
# pylint: disable=too-many-instance-attributes
def setUp(self):
from acme.challenges import TLSSNI01
self.chall = TLSSNI01(
token=jose.b64decode(b'a82d5ff8ef740d12881f6d3c2277ab2e'))
self.response = self.chall.response(KEY)
self.jmsg = {
'resource': 'challenge',
'type': 'tls-sni-01',
'keyAuthorization': self.response.key_authorization,
}
# pylint: disable=invalid-name
label1 = b'dc38d9c3fa1a4fdcc3a5501f2d38583f'
label2 = b'b7793728f084394f2a1afd459556bb5c'
self.z = label1 + label2
self.z_domain = label1 + b'.' + label2 + b'.acme.invalid'
self.domain = 'foo.com'
def test_z_and_domain(self):
self.assertEqual(self.z, self.response.z)
self.assertEqual(self.z_domain, self.response.z_domain)
def test_to_partial_json(self):
self.assertEqual({k: v for k, v in self.jmsg.items() if k != 'keyAuthorization'},
self.response.to_partial_json())
def test_from_json(self):
from acme.challenges import TLSSNI01Response
self.assertEqual(self.response, TLSSNI01Response.from_json(self.jmsg))
def test_from_json_hashable(self):
from acme.challenges import TLSSNI01Response
hash(TLSSNI01Response.from_json(self.jmsg))
@mock.patch('acme.challenges.socket.gethostbyname')
@mock.patch('acme.challenges.crypto_util.probe_sni')
def test_probe_cert(self, mock_probe_sni, mock_gethostbyname):
mock_gethostbyname.return_value = '127.0.0.1'
self.response.probe_cert('foo.com')
mock_gethostbyname.assert_called_once_with('foo.com')
mock_probe_sni.assert_called_once_with(
host='127.0.0.1', port=self.response.PORT,
name=self.z_domain)
self.response.probe_cert('foo.com', host='8.8.8.8')
mock_probe_sni.assert_called_with(
host='8.8.8.8', port=mock.ANY, name=mock.ANY)
self.response.probe_cert('foo.com', port=1234)
mock_probe_sni.assert_called_with(
host=mock.ANY, port=1234, name=mock.ANY)
self.response.probe_cert('foo.com', bar='baz')
mock_probe_sni.assert_called_with(
host=mock.ANY, port=mock.ANY, name=mock.ANY, bar='baz')
self.response.probe_cert('foo.com', name=b'xxx')
mock_probe_sni.assert_called_with(
host=mock.ANY, port=mock.ANY,
name=self.z_domain)
def test_gen_verify_cert(self):
key1 = test_util.load_pyopenssl_private_key('rsa512_key.pem')
cert, key2 = self.response.gen_cert(key1)
self.assertEqual(key1, key2)
self.assertTrue(self.response.verify_cert(cert))
def test_gen_verify_cert_gen_key(self):
cert, key = self.response.gen_cert()
self.assertTrue(isinstance(key, OpenSSL.crypto.PKey))
self.assertTrue(self.response.verify_cert(cert))
def test_verify_bad_cert(self):
self.assertFalse(self.response.verify_cert(
test_util.load_cert('cert.pem')))
def test_simple_verify_bad_key_authorization(self):
key2 = jose.JWKRSA.load(test_util.load_vector('rsa256_key.pem'))
self.response.simple_verify(self.chall, "local", key2.public_key())
@mock.patch('acme.challenges.TLSSNI01Response.verify_cert', autospec=True)
def test_simple_verify(self, mock_verify_cert):
mock_verify_cert.return_value = mock.sentinel.verification
self.assertEqual(
mock.sentinel.verification, self.response.simple_verify(
self.chall, self.domain, KEY.public_key(),
cert=mock.sentinel.cert))
mock_verify_cert.assert_called_once_with(
self.response, mock.sentinel.cert)
@mock.patch('acme.challenges.TLSSNI01Response.probe_cert')
def test_simple_verify_false_on_probe_error(self, mock_probe_cert):
mock_probe_cert.side_effect = errors.Error
self.assertFalse(self.response.simple_verify(
self.chall, self.domain, KEY.public_key()))
class TLSSNI01Test(unittest.TestCase):
def setUp(self):
self.jmsg = {
'type': 'tls-sni-01',
'token': 'a82d5ff8ef740d12881f6d3c2277ab2e',
}
from acme.challenges import TLSSNI01
self.msg = TLSSNI01(
token=jose.b64decode('a82d5ff8ef740d12881f6d3c2277ab2e'))
def test_to_partial_json(self):
self.assertEqual(self.jmsg, self.msg.to_partial_json())
def test_from_json(self):
from acme.challenges import TLSSNI01
self.assertEqual(self.msg, TLSSNI01.from_json(self.jmsg))
def test_from_json_hashable(self):
from acme.challenges import TLSSNI01
hash(TLSSNI01.from_json(self.jmsg))
def test_from_json_invalid_token_length(self):
from acme.challenges import TLSSNI01
self.jmsg['token'] = jose.encode_b64jose(b'abcd')
self.assertRaises(
jose.DeserializationError, TLSSNI01.from_json, self.jmsg)
@mock.patch('acme.challenges.TLSSNI01Response.gen_cert')
def test_validation(self, mock_gen_cert):
mock_gen_cert.return_value = ('cert', 'key')
self.assertEqual(('cert', 'key'), self.msg.validation(
KEY, cert_key=mock.sentinel.cert_key))
mock_gen_cert.assert_called_once_with(key=mock.sentinel.cert_key)
def test_deprecation_message(self):
with mock.patch('acme.warnings.warn') as mock_warn:
from acme.challenges import TLSSNI01
assert TLSSNI01
self.assertEqual(mock_warn.call_count, 1)
self.assertTrue('deprecated' in mock_warn.call_args[0][0])
class TLSALPN01ResponseTest(unittest.TestCase):
# pylint: disable=too-many-instance-attributes
def setUp(self):
from acme.challenges import TLSALPN01Response

View file

@ -44,7 +44,7 @@ DEFAULT_NETWORK_TIMEOUT = 45
DER_CONTENT_TYPE = 'application/pkix-cert'
class ClientBase(object): # pylint: disable=too-many-instance-attributes
class ClientBase(object):
"""ACME client base object.
:ivar messages.Directory directory:
@ -254,7 +254,6 @@ class Client(ClientBase):
URI from which the resource will be downloaded.
"""
# pylint: disable=too-many-arguments
self.key = key
if net is None:
net = ClientNetwork(key, alg=alg, verify_ssl=verify_ssl)
@ -435,7 +434,6 @@ class Client(ClientBase):
was marked by the CA as invalid
"""
# pylint: disable=too-many-locals
assert max_attempts > 0
attempts = collections.defaultdict(int) # type: Dict[messages.AuthorizationResource, int]
exhausted = set()
@ -947,7 +945,7 @@ class BackwardsCompatibleClientV2(object):
return self.client.external_account_required()
class ClientNetwork(object): # pylint: disable=too-many-instance-attributes
class ClientNetwork(object):
"""Wrapper around requests that signs POSTs for authentication.
Also adds user agent, and handles Content-Type.
@ -973,7 +971,6 @@ class ClientNetwork(object): # pylint: disable=too-many-instance-attributes
def __init__(self, key, account=None, alg=jose.RS256, verify_ssl=True,
user_agent='acme-python', timeout=DEFAULT_NETWORK_TIMEOUT,
source_address=None):
# pylint: disable=too-many-arguments
self.key = key
self.account = account
self.alg = alg
@ -1081,7 +1078,6 @@ class ClientNetwork(object): # pylint: disable=too-many-instance-attributes
return response
def _send_request(self, method, url, *args, **kwargs):
# pylint: disable=too-many-locals
"""Send HTTP request.
Makes sure that `verify_ssl` is respected. Logs request and

View file

@ -318,7 +318,6 @@ class BackwardsCompatibleClientV2Test(ClientTestBase):
class ClientTest(ClientTestBase):
"""Tests for acme.client.Client."""
# pylint: disable=too-many-instance-attributes,too-many-public-methods
def setUp(self):
super(ClientTest, self).setUp()
@ -888,7 +887,7 @@ class ClientV2Test(ClientTestBase):
new_nonce_url='https://www.letsencrypt-demo.org/acme/new-nonce')
self.client.net.get.assert_not_called()
class FakeError(messages.Error): # pylint: disable=too-many-ancestors
class FakeError(messages.Error):
"""Fake error to reproduce a malformed request ACME error"""
def __init__(self): # pylint: disable=super-init-not-called
pass
@ -917,7 +916,6 @@ class MockJSONDeSerializable(jose.JSONDeSerializable):
class ClientNetworkTest(unittest.TestCase):
"""Tests for acme.client.ClientNetwork."""
# pylint: disable=too-many-public-methods
def setUp(self):
self.verify_ssl = mock.MagicMock()
@ -1123,7 +1121,6 @@ class ClientNetworkTest(unittest.TestCase):
class ClientNetworkWithMockedResponseTest(unittest.TestCase):
"""Tests for acme.client.ClientNetwork which mock out response."""
# pylint: disable=too-many-instance-attributes
def setUp(self):
from acme.client import ClientNetwork

View file

@ -28,7 +28,7 @@ logger = logging.getLogger(__name__)
_DEFAULT_SSL_METHOD = SSL.SSLv23_METHOD # type: ignore
class SSLSocket(object): # pylint: disable=too-few-public-methods
class SSLSocket(object):
"""SSL wrapper for sockets.
:ivar socket sock: Original wrapped socket.
@ -74,7 +74,7 @@ class SSLSocket(object): # pylint: disable=too-few-public-methods
class FakeConnection(object):
"""Fake OpenSSL.SSL.Connection."""
# pylint: disable=too-few-public-methods,missing-docstring
# pylint: disable=missing-docstring
def __init__(self, connection):
self._wrapped = connection

View file

@ -30,7 +30,6 @@ class SSLSocketAndProbeSNITest(unittest.TestCase):
class _TestServer(socketserver.TCPServer):
# pylint: disable=too-few-public-methods
# six.moves.* | pylint: disable=attribute-defined-outside-init,no-init
def server_bind(self): # pylint: disable=missing-docstring

View file

@ -43,7 +43,7 @@ class JWS(jose.JWS):
__slots__ = jose.JWS._orig_slots # pylint: disable=no-member
@classmethod
# pylint: disable=arguments-differ,too-many-arguments
# pylint: disable=arguments-differ
def sign(cls, payload, key, alg, nonce, url=None, kid=None):
# Per ACME spec, jwk and kid are mutually exclusive, so only include a
# jwk field if kid is not provided.

View file

@ -1,30 +1,23 @@
"""Support for standalone client challenge solvers. """
import argparse
import collections
import functools
import logging
import os
import socket
import sys
import threading
import warnings
from six.moves import BaseHTTPServer # type: ignore # pylint: disable=import-error
from six.moves import http_client # pylint: disable=import-error
from six.moves import socketserver # type: ignore # pylint: disable=import-error
import OpenSSL
from acme import challenges
from acme import crypto_util
from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module
from acme import _TLSSNI01DeprecationModule
logger = logging.getLogger(__name__)
# six.moves.* | pylint: disable=no-member,attribute-defined-outside-init
# pylint: disable=too-few-public-methods,no-init
# pylint: disable=no-init
class TLSServer(socketserver.TCPServer):
@ -133,35 +126,6 @@ class BaseDualNetworkedServers(object):
self.threads = []
class TLSSNI01Server(TLSServer, ACMEServerMixin):
"""TLSSNI01 Server."""
def __init__(self, server_address, certs, ipv6=False):
TLSServer.__init__(
self, server_address, BaseRequestHandlerWithLogging, certs=certs, ipv6=ipv6)
class TLSSNI01DualNetworkedServers(BaseDualNetworkedServers):
"""TLSSNI01Server Wrapper. Tries everything for both. Failures for one don't
affect the other."""
def __init__(self, *args, **kwargs):
BaseDualNetworkedServers.__init__(self, TLSSNI01Server, *args, **kwargs)
class BaseRequestHandlerWithLogging(socketserver.BaseRequestHandler):
"""BaseRequestHandler with logging."""
def log_message(self, format, *args): # pylint: disable=redefined-builtin
"""Log arbitrary message."""
logger.debug("%s - - %s", self.client_address[0], format % args)
def handle(self):
"""Handle request."""
self.log_message("Incoming request")
socketserver.BaseRequestHandler.handle(self)
class HTTPServer(BaseHTTPServer.HTTPServer):
"""Generic HTTP Server."""
@ -264,42 +228,3 @@ class HTTP01RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
"""
return functools.partial(
cls, simple_http_resources=simple_http_resources)
def simple_tls_sni_01_server(cli_args, forever=True):
"""Run simple standalone TLSSNI01 server."""
warnings.warn(
'simple_tls_sni_01_server is deprecated and will be removed soon.',
DeprecationWarning, stacklevel=2)
logging.basicConfig(level=logging.DEBUG)
parser = argparse.ArgumentParser()
parser.add_argument(
"-p", "--port", default=0, help="Port to serve at. By default "
"picks random free port.")
args = parser.parse_args(cli_args[1:])
certs = {}
_, hosts, _ = next(os.walk('.')) # type: ignore # https://github.com/python/mypy/issues/465
for host in hosts:
with open(os.path.join(host, "cert.pem")) as cert_file:
cert_contents = cert_file.read()
with open(os.path.join(host, "key.pem")) as key_file:
key_contents = key_file.read()
certs[host.encode()] = (
OpenSSL.crypto.load_privatekey(
OpenSSL.crypto.FILETYPE_PEM, key_contents),
OpenSSL.crypto.load_certificate(
OpenSSL.crypto.FILETYPE_PEM, cert_contents))
server = TLSSNI01Server(('', int(args.port)), certs=certs)
logger.info("Serving at https://%s:%s...", *server.socket.getsockname()[:2])
if forever: # pragma: no cover
server.serve_forever()
else:
server.handle_request()
# Patching ourselves to warn about TLS-SNI challenge deprecation and removal.
sys.modules[__name__] = _TLSSNI01DeprecationModule(sys.modules[__name__])

View file

@ -1,14 +1,7 @@
"""Tests for acme.standalone."""
import multiprocessing
import os
import shutil
import socket
import threading
import tempfile
import unittest
import warnings
import time
from contextlib import closing
from six.moves import http_client # pylint: disable=import-error
from six.moves import socketserver # type: ignore # pylint: disable=import-error
@ -18,8 +11,6 @@ import mock
import requests
from acme import challenges
from acme import crypto_util
from acme import errors
from acme import test_util
from acme.magic_typing import Set # pylint: disable=unused-import, no-name-in-module
@ -42,44 +33,6 @@ class TLSServerTest(unittest.TestCase):
server.server_close()
class TLSSNI01ServerTest(unittest.TestCase):
"""Test for acme.standalone.TLSSNI01Server."""
def setUp(self):
self.certs = {b'localhost': (
test_util.load_pyopenssl_private_key('rsa2048_key.pem'),
test_util.load_cert('rsa2048_cert.pem'),
)}
from acme.standalone import TLSSNI01Server
self.server = TLSSNI01Server(('localhost', 0), certs=self.certs)
self.thread = threading.Thread(target=self.server.serve_forever)
self.thread.start()
def tearDown(self):
self.server.shutdown()
self.thread.join()
def test_it(self):
host, port = self.server.socket.getsockname()[:2]
cert = crypto_util.probe_sni(
b'localhost', host=host, port=port, timeout=1)
self.assertEqual(jose.ComparableX509(cert),
jose.ComparableX509(self.certs[b'localhost'][1]))
class BaseRequestHandlerWithLoggingTest(unittest.TestCase):
"""Test for acme.standalone.BaseRequestHandlerWithLogging."""
def test_it(self):
with mock.patch('acme.standalone.warnings.warn') as mock_warn:
# pylint: disable=unused-variable
from acme.standalone import BaseRequestHandlerWithLogging
self.assertTrue(mock_warn.called)
msg = mock_warn.call_args[0][0]
self.assertTrue(msg.startswith('BaseRequestHandlerWithLogging'))
class HTTP01ServerTest(unittest.TestCase):
"""Tests for acme.standalone.HTTP01Server."""
@ -183,33 +136,6 @@ class BaseDualNetworkedServersTest(unittest.TestCase):
prev_port = port
class TLSSNI01DualNetworkedServersTest(unittest.TestCase):
"""Test for acme.standalone.TLSSNI01DualNetworkedServers."""
def setUp(self):
self.certs = {b'localhost': (
test_util.load_pyopenssl_private_key('rsa2048_key.pem'),
test_util.load_cert('rsa2048_cert.pem'),
)}
from acme.standalone import TLSSNI01DualNetworkedServers
self.servers = TLSSNI01DualNetworkedServers(('localhost', 0), certs=self.certs)
self.servers.serve_forever()
def tearDown(self):
self.servers.shutdown_and_server_close()
def test_connect(self):
socknames = self.servers.getsocknames()
# connect to all addresses
for sockname in socknames:
host, port = sockname[:2]
cert = crypto_util.probe_sni(
b'localhost', host=host, port=port, timeout=1)
self.assertEqual(jose.ComparableX509(cert),
jose.ComparableX509(self.certs[b'localhost'][1]))
class HTTP01DualNetworkedServersTest(unittest.TestCase):
"""Tests for acme.standalone.HTTP01DualNetworkedServers."""
@ -260,66 +186,5 @@ class HTTP01DualNetworkedServersTest(unittest.TestCase):
self.assertFalse(self._test_http01(add=False))
class TestSimpleTLSSNI01Server(unittest.TestCase):
"""Tests for acme.standalone.simple_tls_sni_01_server."""
def setUp(self):
# mirror ../examples/standalone
self.test_cwd = tempfile.mkdtemp()
localhost_dir = os.path.join(self.test_cwd, 'localhost')
os.makedirs(localhost_dir)
shutil.copy(test_util.vector_path('rsa2048_cert.pem'),
os.path.join(localhost_dir, 'cert.pem'))
shutil.copy(test_util.vector_path('rsa2048_key.pem'),
os.path.join(localhost_dir, 'key.pem'))
with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
sock.bind(('', 0))
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.port = sock.getsockname()[1]
self.process = multiprocessing.Process(target=_simple_tls_sni_01_server_no_warnings,
args=(['path', '-p', str(self.port)],))
self.old_cwd = os.getcwd()
os.chdir(self.test_cwd)
def tearDown(self):
os.chdir(self.old_cwd)
if self.process.is_alive():
self.process.terminate()
self.process.join(timeout=5)
# Check that we didn't timeout waiting for the process to
# terminate.
self.assertNotEqual(self.process.exitcode, None)
shutil.rmtree(self.test_cwd)
@mock.patch('acme.standalone.TLSSNI01Server.handle_request')
def test_mock(self, handle):
_simple_tls_sni_01_server_no_warnings(cli_args=['path', '-p', str(self.port)],
forever=False)
self.assertEqual(handle.call_count, 1)
def test_live(self):
self.process.start()
cert = None
for _ in range(50):
time.sleep(0.1)
try:
cert = crypto_util.probe_sni(b'localhost', b'127.0.0.1', self.port)
break
except errors.Error: # pragma: no cover
pass
self.assertEqual(jose.ComparableX509(cert),
test_util.load_comparable_cert('rsa2048_cert.pem'))
def _simple_tls_sni_01_server_no_warnings(*args, **kwargs):
with warnings.catch_warnings():
warnings.filterwarnings('ignore', 'simple_tls.*')
from acme.standalone import simple_tls_sni_01_server
return simple_tls_sni_01_server(*args, **kwargs)
if __name__ == "__main__":
unittest.main() # pragma: no cover

View file

@ -12,12 +12,6 @@ import josepy as jose
from OpenSSL import crypto
def vector_path(*names):
"""Path to a test vector."""
return pkg_resources.resource_filename(
__name__, os.path.join('testdata', *names))
def load_vector(*names):
"""Load contents of a test vector."""
# luckily, resource_string opens file in binary mode

View file

@ -71,7 +71,6 @@ logger = logging.getLogger(__name__)
@zope.interface.implementer(interfaces.IAuthenticator, interfaces.IInstaller)
@zope.interface.provider(interfaces.IPluginFactory)
class ApacheConfigurator(common.Installer):
# pylint: disable=too-many-instance-attributes,too-many-public-methods
"""Apache configurator.
:ivar config: Configuration.
@ -1116,7 +1115,7 @@ class ApacheConfigurator(common.Installer):
if "ssl_module" not in self.parser.modules:
self.enable_mod("ssl", temp=temp)
def make_vhost_ssl(self, nonssl_vhost): # pylint: disable=too-many-locals
def make_vhost_ssl(self, nonssl_vhost):
"""Makes an ssl_vhost version of a nonssl_vhost.
Duplicates vhost and adds default ssl options
@ -1612,9 +1611,9 @@ class ApacheConfigurator(common.Installer):
:param str domain: domain to enhance
:param str enhancement: enhancement type defined in
:const:`~certbot.constants.ENHANCEMENTS`
:const:`~certbot.plugins.enhancements.ENHANCEMENTS`
:param options: options for the enhancement
See :const:`~certbot.constants.ENHANCEMENTS`
See :const:`~certbot.plugins.enhancements.ENHANCEMENTS`
documentation for appropriate parameter.
:raises .errors.PluginError: If Enhancement is not supported, or if

View file

@ -98,7 +98,7 @@ class Addr(common.Addr):
return self.get_addr_obj(port)
class VirtualHost(object): # pylint: disable=too-few-public-methods
class VirtualHost(object):
"""Represents an Apache Virtualhost.
:ivar str filep: file path of VH
@ -126,7 +126,6 @@ class VirtualHost(object): # pylint: disable=too-few-public-methods
def __init__(self, filep, path, addrs, ssl, enabled, name=None,
aliases=None, modmacro=False, ancestor=None):
# pylint: disable=too-many-arguments
"""Initialize a VH."""
self.filep = filep
self.path = path

View file

@ -19,7 +19,6 @@ logger = logging.getLogger(__name__)
class ApacheParser(object):
# pylint: disable=too-many-public-methods
"""Class handles the fine details of parsing the Apache Configuration.
.. todo:: Make parsing general... remove sites-available etc...

View file

@ -1,4 +1,4 @@
# pylint: disable=too-many-public-methods,too-many-lines
# pylint: disable=too-many-lines
"""Test for certbot_apache.configurator AutoHSTS functionality"""
import re
import unittest

View file

@ -1,4 +1,4 @@
# pylint: disable=too-many-public-methods,too-many-lines
# pylint: disable=too-many-lines
"""Test for certbot_apache.configurator."""
import copy
import shutil

View file

@ -1,4 +1,3 @@
# pylint: disable=too-many-public-methods
"""Tests for certbot_apache.parser."""
import shutil
import unittest

View file

@ -18,7 +18,7 @@ from certbot_apache import entrypoint
from certbot_apache import obj
class ApacheTest(unittest.TestCase): # pylint: disable=too-few-public-methods
class ApacheTest(unittest.TestCase):
def setUp(self, test_dir="debian_apache_2_4/multiple_vhosts",
config_root="debian_apache_2_4/multiple_vhosts/apache2",
@ -81,7 +81,7 @@ class ParserTest(ApacheTest):
self.config_path, self.vhost_path, configurator=self.config)
def get_apache_configurator( # pylint: disable=too-many-arguments, too-many-locals
def get_apache_configurator(
config_path, vhost_path,
config_dir, work_dir, version=(2, 4, 7),
os_info="generic",

View file

@ -62,11 +62,6 @@ def test_registration_override(context):
context.certbot(['unregister'])
context.certbot(['register', '--email', 'ex1@domain.org,ex2@domain.org'])
# TODO: When `certbot register --update-registration` is fully deprecated,
# delete the two following deprecated uses
context.certbot(['register', '--update-registration', '--email', 'ex1@domain.org'])
context.certbot(['register', '--update-registration', '--email', 'ex1@domain.org,ex2@domain.org'])
context.certbot(['update_account', '--email', 'example@domain.org'])
context.certbot(['update_account', '--email', 'ex1@domain.org,ex2@domain.org'])

View file

@ -6,7 +6,7 @@ import subprocess
import mock
import zope.interface
from certbot import configuration
from certbot._internal import configuration
from certbot import errors as le_errors
from certbot import util as certbot_util
from certbot_apache import entrypoint
@ -18,7 +18,6 @@ from certbot_compatibility_test.configurators import common as configurators_com
@zope.interface.implementer(interfaces.IConfiguratorProxy)
class Proxy(configurators_common.Proxy):
# pylint: disable=too-many-instance-attributes
"""A common base for Apache test configurators"""
def __init__(self, args):

View file

@ -4,7 +4,7 @@ import os
import shutil
import tempfile
from certbot import constants
from certbot._internal import constants
from certbot_compatibility_test import errors
from certbot_compatibility_test import util
@ -13,7 +13,6 @@ logger = logging.getLogger(__name__)
class Proxy(object):
# pylint: disable=too-many-instance-attributes
"""A common base for compatibility test configurators"""
@classmethod

View file

@ -7,7 +7,7 @@ import zope.interface
from acme.magic_typing import Set # pylint: disable=unused-import, no-name-in-module
from certbot import configuration
from certbot._internal import configuration
from certbot_nginx import configurator
from certbot_nginx import constants
from certbot_compatibility_test import errors
@ -18,7 +18,6 @@ from certbot_compatibility_test.configurators import common as configurators_com
@zope.interface.implementer(interfaces.IConfiguratorProxy)
class Proxy(configurators_common.Proxy):
# pylint: disable=too-many-instance-attributes
"""A common base for Nginx test configurators"""
def load_config(self):

View file

@ -9,7 +9,7 @@ import tarfile
import josepy as jose
from certbot.tests import util as test_util
from certbot import constants
from certbot._internal import constants
from certbot_compatibility_test import errors

View file

@ -17,7 +17,6 @@ from acme import challenges
from acme import crypto_util as acme_crypto_util
from acme.magic_typing import List, Dict, Set # pylint: disable=unused-import, no-name-in-module
from certbot import constants as core_constants
from certbot import crypto_util
from certbot import errors
from certbot import interfaces
@ -45,7 +44,6 @@ logger = logging.getLogger(__name__)
@zope.interface.implementer(interfaces.IAuthenticator, interfaces.IInstaller)
@zope.interface.provider(interfaces.IPluginFactory)
class NginxConfigurator(common.Installer):
# pylint: disable=too-many-instance-attributes,too-many-public-methods
"""Nginx configurator.
.. todo:: Add proper support for comments in the config. Currently,
@ -101,9 +99,6 @@ class NginxConfigurator(common.Installer):
openssl_version = kwargs.pop("openssl_version", None)
super(NginxConfigurator, self).__init__(*args, **kwargs)
# Verify that all directories and files exist with proper permissions
self._verify_setup()
# Files to save
self.save_notes = ""
@ -708,9 +703,9 @@ class NginxConfigurator(common.Installer):
:param str domain: domain to enhance
:param str enhancement: enhancement type defined in
:const:`~certbot.constants.ENHANCEMENTS`
:const:`~certbot.plugins.enhancements.ENHANCEMENTS`
:param options: options for the enhancement
See :const:`~certbot.constants.ENHANCEMENTS`
See :const:`~certbot.plugins.enhancements.ENHANCEMENTS`
documentation for appropriate parameter.
"""
@ -929,18 +924,6 @@ class NginxConfigurator(common.Installer):
except errors.SubprocessError as err:
raise errors.MisconfigurationError(str(err))
def _verify_setup(self):
"""Verify the setup to ensure safe operating environment.
Make sure that files/directories are setup with appropriate permissions
Aim for defensive coding... make sure all input files
have permissions of root.
"""
util.make_or_verify_dir(self.config.work_dir, core_constants.CONFIG_DIRS_MODE)
util.make_or_verify_dir(self.config.backup_dir, core_constants.CONFIG_DIRS_MODE)
util.make_or_verify_dir(self.config.config_dir, core_constants.CONFIG_DIRS_MODE)
def _nginx_version(self):
"""Return results of nginx -V

View file

@ -63,7 +63,6 @@ class RawNginxParser(object):
return self.parse().asList()
class RawNginxDumper(object):
# pylint: disable=too-few-public-methods
"""A class that dumps nginx configuration from the provided tree."""
def __init__(self, blocks):
self.blocks = blocks

View file

@ -37,7 +37,6 @@ class Addr(common.Addr):
CANONICAL_UNSPECIFIED_ADDRESS = UNSPECIFIED_IPV4_ADDRESSES[0]
def __init__(self, host, port, ssl, default, ipv6, ipv6only):
# pylint: disable=too-many-arguments
super(Addr, self).__init__((host, port))
self.ssl = ssl
self.default = default
@ -145,7 +144,7 @@ class Addr(common.Addr):
return False
class VirtualHost(object): # pylint: disable=too-few-public-methods
class VirtualHost(object):
"""Represents an Nginx Virtualhost.
:ivar str filep: file path of VH
@ -162,7 +161,6 @@ class VirtualHost(object): # pylint: disable=too-few-public-methods
"""
def __init__(self, filep, addrs, ssl, enabled, names, raw, path):
# pylint: disable=too-many-arguments
"""Initialize a VH."""
self.filep = filep
self.addrs = addrs

View file

@ -1,4 +1,3 @@
# pylint: disable=too-many-public-methods
"""Test for certbot_nginx.configurator."""
import unittest
@ -27,7 +26,7 @@ class NginxConfiguratorTest(util.NginxTest):
def setUp(self):
super(NginxConfiguratorTest, self).setUp()
self.config = util.get_nginx_configurator(
self.config = self.get_nginx_configurator(
self.config_path, self.config_dir, self.work_dir, self.logs_dir)
@mock.patch("certbot_nginx.configurator.util.exe_exists")
@ -935,7 +934,7 @@ class InstallSslOptionsConfTest(util.NginxTest):
def setUp(self):
super(InstallSslOptionsConfTest, self).setUp()
self.config = util.get_nginx_configurator(
self.config = self.get_nginx_configurator(
self.config_path, self.config_dir, self.work_dir, self.logs_dir)
def _call(self):

View file

@ -47,7 +47,7 @@ class HttpPerformTest(util.NginxTest):
def setUp(self):
super(HttpPerformTest, self).setUp()
config = util.get_nginx_configurator(
config = self.get_nginx_configurator(
self.config_path, self.config_dir, self.work_dir, self.logs_dir)
from certbot_nginx import http_01

View file

@ -15,7 +15,7 @@ from certbot_nginx import parser
from certbot_nginx.tests import util
class NginxParserTest(util.NginxTest): #pylint: disable=too-many-public-methods
class NginxParserTest(util.NginxTest):
"""Nginx Parser Test."""
def tearDown(self):

View file

@ -2,14 +2,12 @@
import copy
import shutil
import tempfile
import unittest
import josepy as jose
import mock
import pkg_resources
import zope.component
from certbot import configuration
from certbot import util
from certbot.compat import os
from certbot.plugins import common
@ -19,11 +17,14 @@ from certbot_nginx import configurator
from certbot_nginx import nginxparser
class NginxTest(unittest.TestCase): # pylint: disable=too-few-public-methods
class NginxTest(test_util.ConfigTestCase):
def setUp(self):
super(NginxTest, self).setUp()
self.configuration = self.config
self.config = None
self.temp_dir, self.config_dir, self.work_dir = common.dir_setup(
"etc_nginx", "certbot_nginx.tests")
self.logs_dir = tempfile.mkdtemp('logs')
@ -45,6 +46,41 @@ class NginxTest(unittest.TestCase): # pylint: disable=too-few-public-methods
shutil.rmtree(self.work_dir)
shutil.rmtree(self.logs_dir)
def get_nginx_configurator(self, config_path, config_dir, work_dir, logs_dir,
version=(1, 6, 2), openssl_version="1.0.2g"):
"""Create an Nginx Configurator with the specified options."""
backups = os.path.join(work_dir, "backups")
self.configuration.nginx_server_root = config_path
self.configuration.le_vhost_ext = "-le-ssl.conf"
self.configuration.config_dir = config_dir
self.configuration.work_dir = work_dir
self.configuration.logs_dir = logs_dir
self.configuration.backup_dir = backups
self.configuration.temp_checkpoint_dir = os.path.join(work_dir, "temp_checkpoints")
self.configuration.in_progress_dir = os.path.join(backups, "IN_PROGRESS")
self.configuration.server = "https://acme-server.org:443/new"
self.configuration.http01_port = 80
self.configuration.https_port = 5001
with mock.patch("certbot_nginx.configurator.NginxConfigurator."
"config_test"):
with mock.patch("certbot_nginx.configurator.util."
"exe_exists") as mock_exe_exists:
mock_exe_exists.return_value = True
config = configurator.NginxConfigurator(
self.configuration,
name="nginx",
version=version,
openssl_version=openssl_version)
config.prepare()
# Provide general config utility.
zope.component.provideUtility(self.configuration)
return config
def get_data_filename(filename):
"""Gets the filename of a test data file."""
@ -53,43 +89,6 @@ def get_data_filename(filename):
"testdata", "etc_nginx", filename))
def get_nginx_configurator(
config_path, config_dir, work_dir, logs_dir, version=(1, 6, 2), openssl_version="1.0.2g"):
"""Create an Nginx Configurator with the specified options."""
backups = os.path.join(work_dir, "backups")
with mock.patch("certbot_nginx.configurator.NginxConfigurator."
"config_test"):
with mock.patch("certbot_nginx.configurator.util."
"exe_exists") as mock_exe_exists:
mock_exe_exists.return_value = True
config = configurator.NginxConfigurator(
config=mock.MagicMock(
nginx_server_root=config_path,
le_vhost_ext="-le-ssl.conf",
config_dir=config_dir,
work_dir=work_dir,
logs_dir=logs_dir,
backup_dir=backups,
temp_checkpoint_dir=os.path.join(work_dir, "temp_checkpoints"),
in_progress_dir=os.path.join(backups, "IN_PROGRESS"),
server="https://acme-server.org:443/new",
http01_port=80,
https_port=5001,
),
name="nginx",
version=version,
openssl_version=openssl_version)
config.prepare()
# Provide general config utility.
nsconfig = configuration.NamespaceConfig(config.config)
zope.component.provideUtility(nsconfig)
return config
def filter_comments(tree):
"""Filter comment nodes from parsed configurations."""

View file

@ -16,7 +16,7 @@ from cryptography.hazmat.primitives import serialization
from acme import fields as acme_fields
from acme import messages
from certbot import constants
from certbot._internal import constants
from certbot import errors
from certbot import interfaces
from certbot import util
@ -25,7 +25,7 @@ from certbot.compat import os
logger = logging.getLogger(__name__)
class Account(object): # pylint: disable=too-few-public-methods
class Account(object):
"""ACME protocol registration.
:ivar .RegistrationResource regr: Registration Resource

View file

@ -33,7 +33,7 @@ def update_live_symlinks(config):
.. note:: This assumes that the installation is using a Reverter object.
:param config: Configuration.
:type config: :class:`certbot.configuration.NamespaceConfig`
:type config: :class:`certbot._internal.configuration.NamespaceConfig`
"""
for renewal_file in storage.renewal_conf_files(config):
@ -43,7 +43,7 @@ def rename_lineage(config):
"""Rename the specified lineage to the new name.
:param config: Configuration.
:type config: :class:`certbot.configuration.NamespaceConfig`
:type config: :class:`certbot._internal.configuration.NamespaceConfig`
"""
disp = zope.component.getUtility(interfaces.IDisplay)
@ -70,7 +70,7 @@ def certificates(config):
"""Display information about certs configured with Certbot
:param config: Configuration.
:type config: :class:`certbot.configuration.NamespaceConfig`
:type config: :class:`certbot._internal.configuration.NamespaceConfig`
"""
parsed_certs = []
parse_failures = []
@ -136,7 +136,7 @@ def find_duplicative_certs(config, domains):
undefined.
:param config: Configuration.
:type config: :class:`certbot.configuration.NamespaceConfig`
:type config: :class:`certbot._internal.configuration.NamespaceConfig`
:param domains: List of domain names
:type domains: `list` of `str`

View file

@ -21,16 +21,16 @@ from acme.magic_typing import Any, Dict, Optional
import certbot
import certbot.plugins.enhancements as enhancements
import certbot.plugins.selection as plugin_selection
from certbot import constants
import certbot._internal.plugins.selection as plugin_selection
from certbot._internal import constants
from certbot import crypto_util
from certbot import errors
from certbot import hooks
from certbot._internal import hooks
from certbot import interfaces
from certbot import util
from certbot.compat import os
from certbot.display import util as display_util
from certbot.plugins import disco as plugins_disco
from certbot._internal.plugins import disco as plugins_disco
logger = logging.getLogger(__name__)
@ -870,7 +870,7 @@ def _add_all_groups(helpful):
helpful.add_group(name, description=docs["opts"])
def prepare_and_parse_args(plugins, args, detect_defaults=False): # pylint: disable=too-many-statements
def prepare_and_parse_args(plugins, args, detect_defaults=False):
"""Returns parsed command line arguments.
:param .PluginsRegistry plugins: available plugins
@ -881,7 +881,6 @@ def prepare_and_parse_args(plugins, args, detect_defaults=False): # pylint: dis
"""
# pylint: disable=too-many-statements
helpful = HelpfulArgumentParser(args, plugins, detect_defaults)
_add_all_groups(helpful)
@ -980,12 +979,6 @@ def prepare_and_parse_args(plugins, args, detect_defaults=False): # pylint: dis
"certificates. Updates to the Subscriber Agreement will still "
"affect you, and will be effective 14 days after posting an "
"update to the web site.")
# TODO: When `certbot register --update-registration` is fully deprecated,
# delete following helpful.add
helpful.add(
"register", "--update-registration", action="store_true",
default=flag_default("update_registration"), dest="update_registration",
help=argparse.SUPPRESS)
helpful.add(
["register", "update_account", "unregister", "automation"], "-m", "--email",
default=flag_default("email"),

View file

@ -20,8 +20,8 @@ from acme.magic_typing import Optional, List # pylint: disable=unused-import,no
import certbot
from certbot._internal import account
from certbot._internal import auth_handler
from certbot import cli
from certbot import constants
from certbot._internal import cli
from certbot._internal import constants
from certbot import crypto_util
from certbot._internal import eff
from certbot._internal import error_handler
@ -32,7 +32,7 @@ from certbot import util
from certbot.compat import os
from certbot._internal.display import enhancements
from certbot.display import ops as display_ops
from certbot.plugins import selection as plugin_selection
from certbot._internal.plugins import selection as plugin_selection
logger = logging.getLogger(__name__)

View file

@ -4,7 +4,7 @@ import copy
import zope.interface
from six.moves.urllib import parse # pylint: disable=relative-import
from certbot import constants
from certbot._internal import constants
from certbot import errors
from certbot import interfaces
from certbot import util
@ -20,7 +20,7 @@ class NamespaceConfig(object):
:class:`certbot.interfaces.IConfig`. However, note that
the following attributes are dynamically resolved using
:attr:`~certbot.interfaces.IConfig.work_dir` and relative
paths defined in :py:mod:`certbot.constants`:
paths defined in :py:mod:`certbot._internal.constants`:
- `accounts_dir`
- `csr_dir`
@ -30,7 +30,7 @@ class NamespaceConfig(object):
And the following paths are dynamically resolved using
:attr:`~certbot.interfaces.IConfig.config_dir` and relative
paths defined in :py:mod:`certbot.constants`:
paths defined in :py:mod:`certbot._internal.constants`:
- `default_archive_dir`
- `live_dir`

View file

@ -32,7 +32,6 @@ CLI_DEFAULTS = dict(
certname=None,
dry_run=False,
register_unsafely_without_email=False,
update_registration=False,
email=None,
eff_email=None,
reinstall=False,
@ -147,18 +146,6 @@ RENEWER_DEFAULTS = dict(
)
"""Defaults for renewer script."""
ENHANCEMENTS = ["redirect", "ensure-http-header", "ocsp-stapling"]
"""List of possible :class:`certbot.interfaces.IInstaller`
enhancements.
List of expected options parameters:
- redirect: None
- ensure-http-header: name of header (i.e. Strict-Transport-Security)
- ocsp-stapling: certificate chain file path
"""
ARCHIVE_DIR = "archive"
"""Archive directory, relative to `IConfig.config_dir`."""

View file

@ -18,7 +18,7 @@ def ask(enhancement):
"""Display the enhancement to the user.
:param str enhancement: One of the
:class:`certbot.CONFIG.ENHANCEMENTS` enhancements
:const:`~certbot.plugins.enhancements.ENHANCEMENTS` enhancements
:returns: True if feature is desired, False otherwise
:rtype: bool

View file

@ -4,7 +4,7 @@ import logging
import requests
import zope.component
from certbot import constants
from certbot._internal import constants
from certbot import interfaces

View file

@ -24,7 +24,7 @@ import traceback
from acme import messages
from certbot import constants
from certbot._internal import constants
from certbot import errors
from certbot import util
from certbot.compat import os
@ -41,7 +41,7 @@ def pre_arg_parse_setup():
"""Setup logging before command line arguments are parsed.
Terminal logging is setup using
`certbot.constants.QUIET_LOGGING_LEVEL` so Certbot is as quiet as
`certbot._internal.constants.QUIET_LOGGING_LEVEL` so Certbot is as quiet as
possible. File logging is setup so that logging messages are
buffered in memory. If Certbot exits before `post_arg_parse_setup`
is called, these buffered messages are written to a temporary file.

View file

@ -16,14 +16,14 @@ from acme.magic_typing import Union # pylint: disable=unused-import, no-name-in
import certbot
from certbot._internal import account
from certbot._internal import cert_manager
from certbot import cli
from certbot._internal import cli
from certbot._internal import client
from certbot import configuration
from certbot import constants
from certbot._internal import configuration
from certbot._internal import constants
from certbot import crypto_util
from certbot._internal import eff
from certbot import errors
from certbot import hooks
from certbot._internal import hooks
from certbot import interfaces
from certbot._internal import log
from certbot._internal import renewal
@ -35,9 +35,9 @@ from certbot.compat import filesystem
from certbot.compat import misc
from certbot.compat import os
from certbot.display import util as display_util, ops as display_ops
from certbot.plugins import disco as plugins_disco
from certbot._internal.plugins import disco as plugins_disco
from certbot.plugins import enhancements
from certbot.plugins import selection as plug_sel
from certbot._internal.plugins import selection as plug_sel
USER_CANCELLED = ("User chose to cancel the operation and may "
"reinvoke the client.")
@ -532,7 +532,7 @@ def _determine_account(config):
return acc, acme
def _delete_if_appropriate(config): # pylint: disable=too-many-locals,too-many-branches
def _delete_if_appropriate(config):
"""Does the user want to delete their now-revoked certs? If run in non-interactive mode,
deleting happens automatically.
@ -668,14 +668,6 @@ def register(config, unused_plugins):
:rtype: None or str
"""
# TODO: When `certbot register --update-registration` is fully deprecated,
# delete the true case of if block
if config.update_registration:
msg = ("Usage 'certbot register --update-registration' is deprecated.\n"
"Please use 'certbot update_account [options]' instead.\n")
logger.warning(msg)
return update_account(config, unused_plugins)
# Portion of _determine_account logic to see whether accounts already
# exist or not.
account_storage = account.AccountFileStorage(config)
@ -1076,7 +1068,7 @@ def revoke(config, unused_plugins):
return None
def run(config, plugins): # pylint: disable=too-many-branches,too-many-locals
def run(config, plugins):
"""Obtain a certificate and install.
:param config: Configuration object

View file

@ -0,0 +1 @@
"""Certbot plugins."""

View file

@ -10,7 +10,7 @@ import zope.interface
import zope.interface.verify
from acme.magic_typing import Dict # pylint: disable=unused-import, no-name-in-module
from certbot import constants
from certbot._internal import constants
from certbot import errors
from certbot import interfaces

View file

@ -7,7 +7,7 @@ from acme.magic_typing import Dict # pylint: disable=unused-import, no-name-in-
from certbot import achallenges # pylint: disable=unused-import
from certbot import errors
from certbot import hooks
from certbot._internal import hooks
from certbot import interfaces
from certbot import reverter
from certbot.compat import os

View file

@ -43,7 +43,7 @@ def get_unprepared_installer(config, plugins):
Get an unprepared interfaces.IInstaller object.
:param certbot.interfaces.IConfig config: Configuration
:param certbot.plugins.disco.PluginsRegistry plugins:
:param certbot._internal.plugins.disco.PluginsRegistry plugins:
All plugins registered as entry points.
:returns: Unprepared installer plugin or None
@ -73,7 +73,7 @@ def pick_plugin(config, default, plugins, question, ifaces):
:param certbot.interfaces.IConfig: Configuration
:param str default: Plugin name supplied by user or ``None``.
:param certbot.plugins.disco.PluginsRegistry plugins:
: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.
@ -175,7 +175,6 @@ def record_chosen_plugins(config, plugins, auth, inst):
def choose_configurator_plugins(config, plugins, verb):
# pylint: disable=too-many-branches
"""
Figure out which configurator we're going to use, modifies
config.authenticator and config.installer strings to reflect that choice if
@ -197,7 +196,7 @@ def choose_configurator_plugins(config, plugins, verb):
# Which plugins do we need?
if verb == "run":
need_inst = need_auth = True
from certbot.cli import cli_command
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}'
@ -254,7 +253,7 @@ def set_configurator(previously, now):
return now
def cli_plugin_requests(config): # pylint: disable=too-many-branches
def cli_plugin_requests(config):
"""
Figure out which plugins the user requested with CLI and config options
@ -328,7 +327,7 @@ def diagnose_configurator_problem(cfg_type, requested, plugins):
"your existing configuration.\nThe error was: {1!r}"
.format(requested, plugins[requested].problem))
elif cfg_type == "installer":
from certbot.cli import cli_command
from certbot._internal.cli import cli_command
msg = ('Certbot doesn\'t know how to automatically configure the web '
'server on this system. However, it can still get a certificate for '
'you. Please run "{0} certonly" to do so. You\'ll need to '

View file

@ -15,7 +15,7 @@ from acme.magic_typing import Dict, Set, DefaultDict, List
# pylint: enable=unused-import, no-name-in-module
from certbot import achallenges # pylint: disable=unused-import
from certbot import cli
from certbot._internal import cli
from certbot import errors
from certbot import interfaces
from certbot.compat import os

View file

@ -15,16 +15,16 @@ import zope.component
from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module
from certbot import cli
from certbot._internal import cli
from certbot import crypto_util
from certbot import errors
from certbot import hooks
from certbot._internal import hooks
from certbot import interfaces
from certbot._internal import storage
from certbot._internal import updater
from certbot import util
from certbot.compat import os
from certbot.plugins import disco as plugins_disco
from certbot._internal.plugins import disco as plugins_disco
logger = logging.getLogger(__name__)
@ -372,7 +372,7 @@ def _renew_describe_results(config, renew_successes, renew_failures,
disp.notification("\n".join(out), wrap=False)
def handle_renewal_request(config): # pylint: disable=too-many-locals,too-many-branches,too-many-statements
def handle_renewal_request(config):
"""Examine each lineage; renew if due and report results"""
# This is trivially False if config.domains is empty

View file

@ -12,8 +12,8 @@ import pytz
import six
import certbot
from certbot import cli
from certbot import constants
from certbot._internal import cli
from certbot._internal import constants
from certbot import crypto_util
from certbot._internal import error_handler
from certbot import errors
@ -21,7 +21,7 @@ from certbot import util
from certbot.compat import os
from certbot.compat import filesystem
from certbot.plugins import common as plugins_common
from certbot.plugins import disco as plugins_disco
from certbot._internal.plugins import disco as plugins_disco
logger = logging.getLogger(__name__)
@ -377,7 +377,6 @@ def delete_files(config, certname):
class RenewableCert(object):
# pylint: disable=too-many-instance-attributes,too-many-public-methods
"""Renewable certificate.
Represents a lineage of certificates that is under the management of
@ -952,7 +951,6 @@ class RenewableCert(object):
@classmethod
def new_lineage(cls, lineagename, cert, privkey, chain, cli_config):
# pylint: disable=too-many-locals
"""Create a new certificate lineage.
Attempts to create a certificate lineage -- enrolled for

View file

@ -4,7 +4,7 @@ import logging
from certbot import errors
from certbot import interfaces
from certbot.plugins import selection as plug_sel
from certbot._internal.plugins import selection as plug_sel
import certbot.plugins.enhancements as enhancements
logger = logging.getLogger(__name__)

View file

@ -27,7 +27,6 @@ from acme import challenges
logger = logging.getLogger(__name__)
# pylint: disable=too-few-public-methods
class AnnotatedChallenge(jose.ImmutableMap):
"""Client annotated challenge.

View file

@ -588,7 +588,11 @@ def _get_current_user():
"""
Return the pySID corresponding to the current user.
"""
account_name = win32api.GetUserNameEx(win32api.NameSamCompatible)
# We craft the account_name ourselves instead of calling for instance win32api.GetUserNameEx,
# because this function returns nonsense values when Certbot is run under NT AUTHORITY\SYSTEM.
# To run Certbot under NT AUTHORITY\SYSTEM, you can open a shell using the instructions here:
# https://blogs.technet.microsoft.com/ben_parker/2010/10/27/how-do-i-run-powershell-execommand-prompt-as-the-localsystem-account-on-windows-7/
account_name = r"{0}\{1}".format(win32api.GetDomainName(), win32api.GetUserName())
# LookupAccountName() expects the system name as first parameter. By passing None to it,
# we instruct Windows to first search the matching account in the machine local accounts,
# then into the primary domain accounts, if the machine has joined a domain, then finally

View file

@ -5,7 +5,7 @@ import textwrap
import zope.interface
from certbot import constants
from certbot._internal import constants
from certbot import errors
from certbot import interfaces
from certbot.compat import misc
@ -89,7 +89,6 @@ def input_with_timeout(prompt=None, timeout=36000.0):
@zope.interface.implementer(interfaces.IDisplay)
class FileDisplay(object):
"""File-based display."""
# pylint: disable=too-many-arguments
# see https://github.com/certbot/certbot/issues/3915
def __init__(self, outfile, force_interactive):
@ -482,7 +481,7 @@ class NoninteractiveDisplay(object):
def menu(self, message, choices, ok_label=None, cancel_label=None,
help_label=None, default=None, cli_flag=None, **unused_kwargs):
# pylint: disable=unused-argument,too-many-arguments
# pylint: disable=unused-argument
"""Avoid displaying a menu.
:param str message: title of menu

View file

@ -4,7 +4,6 @@ import six
import zope.interface
# pylint: disable=no-self-argument,no-method-argument,no-init,inherit-non-class
# pylint: disable=too-few-public-methods
@six.add_metaclass(abc.ABCMeta)
@ -295,10 +294,10 @@ class IInstaller(IPlugin):
:param str domain: domain for which to provide enhancement
:param str enhancement: An enhancement as defined in
:const:`~certbot.constants.ENHANCEMENTS`
:const:`~certbot.plugins.enhancements.ENHANCEMENTS`
:param options: Flexible options parameter for enhancement.
Check documentation of
:const:`~certbot.constants.ENHANCEMENTS`
:const:`~certbot.plugins.enhancements.ENHANCEMENTS`
for expected options for each enhancement.
:raises .PluginError: If Enhancement is not supported, or if
@ -310,7 +309,7 @@ class IInstaller(IPlugin):
"""Returns a `collections.Iterable` of supported enhancements.
:returns: supported enhancements which should be a subset of
:const:`~certbot.constants.ENHANCEMENTS`
:const:`~certbot.plugins.enhancements.ENHANCEMENTS`
:rtype: :class:`collections.Iterable` of :class:`str`
"""
@ -372,7 +371,6 @@ class IInstaller(IPlugin):
class IDisplay(zope.interface.Interface):
"""Generic display."""
# pylint: disable=too-many-arguments
# see https://github.com/certbot/certbot/issues/3915
def notification(message, pause, wrap=True, force_interactive=False):

View file

@ -1 +1 @@
"""Certbot client.plugins."""
"""Certbot plugins."""

View file

@ -14,7 +14,7 @@ from josepy import util as jose_util
from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module
from certbot import achallenges # pylint: disable=unused-import
from certbot import constants
from certbot._internal import constants
from certbot import crypto_util
from certbot import errors
from certbot import interfaces

View file

@ -167,11 +167,11 @@ class InstallerTest(test_util.ConfigTestCase):
self.assertTrue(os.path.isfile(self.installer.ssl_dhparams))
def _current_ssl_dhparams_hash(self):
from certbot.constants import SSL_DHPARAMS_SRC
from certbot._internal.constants import SSL_DHPARAMS_SRC
return crypto_util.sha256sum(SSL_DHPARAMS_SRC)
def test_current_file_hash_in_all_hashes(self):
from certbot.constants import ALL_SSL_DHPARAMS_HASHES
from certbot._internal.constants import ALL_SSL_DHPARAMS_HASHES
self.assertTrue(self._current_ssl_dhparams_hash() in ALL_SSL_DHPARAMS_HASHES,
"Constants.ALL_SSL_DHPARAMS_HASHES must be appended"
" with the sha256 hash of self.config.ssl_dhparams when it is updated.")

View file

@ -1,4 +1,4 @@
"""Tests for certbot.plugins.disco."""
"""Tests for certbot._internal.plugins.disco."""
import functools
import string
import unittest
@ -12,21 +12,21 @@ from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-
from certbot import errors
from certbot import interfaces
from certbot.plugins import standalone
from certbot.plugins import webroot
from certbot._internal.plugins import standalone
from certbot._internal.plugins import webroot
EP_SA = pkg_resources.EntryPoint(
"sa", "certbot.plugins.standalone",
"sa", "certbot._internal.plugins.standalone",
attrs=("Authenticator",),
dist=mock.MagicMock(key="certbot"))
EP_WR = pkg_resources.EntryPoint(
"wr", "certbot.plugins.webroot",
"wr", "certbot._internal.plugins.webroot",
attrs=("Authenticator",),
dist=mock.MagicMock(key="certbot"))
class PluginEntryPointTest(unittest.TestCase):
"""Tests for certbot.plugins.disco.PluginEntryPoint."""
"""Tests for certbot._internal.plugins.disco.PluginEntryPoint."""
def setUp(self):
self.ep1 = pkg_resources.EntryPoint(
@ -40,11 +40,11 @@ class PluginEntryPointTest(unittest.TestCase):
self.ep3 = pkg_resources.EntryPoint(
"ep3", "a.ep3", dist=mock.MagicMock(key="p3"))
from certbot.plugins.disco import PluginEntryPoint
from certbot._internal.plugins.disco import PluginEntryPoint
self.plugin_ep = PluginEntryPoint(EP_SA)
def test_entry_point_to_plugin_name(self):
from certbot.plugins.disco import PluginEntryPoint
from certbot._internal.plugins.disco import PluginEntryPoint
names = {
self.ep1: "p1:ep1",
@ -119,7 +119,7 @@ class PluginEntryPointTest(unittest.TestCase):
self.plugin_ep._initialized = plugin = mock.MagicMock()
exceptions = zope.interface.exceptions
with mock.patch("certbot.plugins."
with mock.patch("certbot._internal.plugins."
"disco.zope.interface") as mock_zope:
mock_zope.exceptions = exceptions
@ -183,11 +183,11 @@ class PluginEntryPointTest(unittest.TestCase):
class PluginsRegistryTest(unittest.TestCase):
"""Tests for certbot.plugins.disco.PluginsRegistry."""
"""Tests for certbot._internal.plugins.disco.PluginsRegistry."""
@classmethod
def _create_new_registry(cls, plugins):
from certbot.plugins.disco import PluginsRegistry
from certbot._internal.plugins.disco import PluginsRegistry
return PluginsRegistry(plugins)
def setUp(self):
@ -198,8 +198,8 @@ class PluginsRegistryTest(unittest.TestCase):
self.reg = self._create_new_registry(self.plugins)
def test_find_all(self):
from certbot.plugins.disco import PluginsRegistry
with mock.patch("certbot.plugins.disco.pkg_resources") as mock_pkg:
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()

View file

@ -2,10 +2,21 @@
import abc
import six
from certbot import constants
from certbot._internal import constants
from acme.magic_typing import Dict, List, Any # pylint: disable=unused-import, no-name-in-module
ENHANCEMENTS = ["redirect", "ensure-http-header", "ocsp-stapling"]
"""List of possible :class:`certbot.interfaces.IInstaller`
enhancements.
List of expected options parameters:
- redirect: None
- ensure-http-header: name of header (i.e. Strict-Transport-Security)
- ocsp-stapling: certificate chain file path
"""
def enabled_enhancements(config):
"""
Generator to yield the enabled new style enhancements.
@ -67,9 +78,9 @@ def enable(lineage, domains, installer, config):
def populate_cli(add):
"""
Populates the command line flags for certbot.cli.HelpfulParser
Populates the command line flags for certbot._internal.cli.HelpfulParser
:param add: Add function of certbot.cli.HelpfulParser
:param add: Add function of certbot._internal.cli.HelpfulParser
:type add: func
"""
for enh in _INDEX:

View file

@ -3,7 +3,7 @@ import unittest
import mock
from certbot.plugins import enhancements
from certbot.plugins import null
from certbot._internal.plugins import null
import certbot.tests.util as test_util

View file

@ -1,4 +1,4 @@
"""Tests for certbot.plugins.manual"""
"""Tests for certbot._internal.plugins.manual"""
import unittest
import sys
@ -15,7 +15,7 @@ from certbot.tests import util as test_util
class AuthenticatorTest(test_util.TempDirTestCase):
"""Tests for certbot.plugins.manual.Authenticator."""
"""Tests for certbot._internal.plugins.manual.Authenticator."""
def setUp(self):
super(AuthenticatorTest, self).setUp()
@ -39,7 +39,7 @@ class AuthenticatorTest(test_util.TempDirTestCase):
self.tempdir, "temp_checkpoint_dir"),
in_progress_dir=os.path.join(self.tempdir, "in_progess"))
from certbot.plugins.manual import Authenticator
from certbot._internal.plugins.manual import Authenticator
self.auth = Authenticator(self.config, name='manual')
def test_prepare_no_hook_noninteractive(self):

View file

@ -1,4 +1,4 @@
"""Tests for certbot.plugins.null."""
"""Tests for certbot._internal.plugins.null."""
import unittest
import six
@ -6,10 +6,10 @@ import mock
class InstallerTest(unittest.TestCase):
"""Tests for certbot.plugins.null.Installer."""
"""Tests for certbot._internal.plugins.null.Installer."""
def setUp(self):
from certbot.plugins.null import Installer
from certbot._internal.plugins.null import Installer
self.installer = Installer(config=mock.MagicMock(), name="null")
def test_it(self):

View file

@ -11,40 +11,40 @@ from certbot import errors
from certbot import interfaces
from certbot.compat import os
from certbot.display import util as display_util
from certbot.plugins.disco import PluginsRegistry
from certbot._internal.plugins.disco import PluginsRegistry
from certbot.tests import util as test_util
class ConveniencePickPluginTest(unittest.TestCase):
"""Tests for certbot.plugins.selection.pick_*."""
"""Tests for certbot._internal.plugins.selection.pick_*."""
def _test(self, fun, ifaces):
config = mock.Mock()
default = mock.Mock()
plugins = mock.Mock()
with mock.patch("certbot.plugins.selection.pick_plugin") as mock_p:
with mock.patch("certbot._internal.plugins.selection.pick_plugin") as mock_p:
mock_p.return_value = "foo"
self.assertEqual("foo", fun(config, default, plugins, "Question?"))
mock_p.assert_called_once_with(
config, default, plugins, "Question?", ifaces)
def test_authenticator(self):
from certbot.plugins.selection import pick_authenticator
from certbot._internal.plugins.selection import pick_authenticator
self._test(pick_authenticator, (interfaces.IAuthenticator,))
def test_installer(self):
from certbot.plugins.selection import pick_installer
from certbot._internal.plugins.selection import pick_installer
self._test(pick_installer, (interfaces.IInstaller,))
def test_configurator(self):
from certbot.plugins.selection import pick_configurator
from certbot._internal.plugins.selection import pick_configurator
self._test(pick_configurator,
(interfaces.IAuthenticator, interfaces.IInstaller))
class PickPluginTest(unittest.TestCase):
"""Tests for certbot.plugins.selection.pick_plugin."""
"""Tests for certbot._internal.plugins.selection.pick_plugin."""
def setUp(self):
self.config = mock.Mock(noninteractive_mode=False)
@ -54,7 +54,7 @@ class PickPluginTest(unittest.TestCase):
self.ifaces = [] # type: List[interfaces.IPlugin]
def _call(self):
from certbot.plugins.selection import pick_plugin
from certbot._internal.plugins.selection import pick_plugin
return pick_plugin(self.config, self.default, self.reg,
self.question, self.ifaces)
@ -95,7 +95,7 @@ class PickPluginTest(unittest.TestCase):
"bar": plugin_ep,
"baz": plugin_ep,
}
with mock.patch("certbot.plugins.selection.choose_plugin") as mock_choose:
with mock.patch("certbot._internal.plugins.selection.choose_plugin") as mock_choose:
mock_choose.return_value = plugin_ep
self.assertEqual("foo", self._call())
mock_choose.assert_called_once_with(
@ -107,13 +107,13 @@ class PickPluginTest(unittest.TestCase):
"baz": None,
}
with mock.patch("certbot.plugins.selection.choose_plugin") as mock_choose:
with mock.patch("certbot._internal.plugins.selection.choose_plugin") as mock_choose:
mock_choose.return_value = None
self.assertTrue(self._call() is None)
class ChoosePluginTest(unittest.TestCase):
"""Tests for certbot.plugins.selection.choose_plugin."""
"""Tests for certbot._internal.plugins.selection.choose_plugin."""
def setUp(self):
zope.component.provideUtility(display_util.FileDisplay(sys.stdout,
@ -130,17 +130,17 @@ class ChoosePluginTest(unittest.TestCase):
]
def _call(self):
from certbot.plugins.selection import choose_plugin
from certbot._internal.plugins.selection import choose_plugin
return choose_plugin(self.plugins, "Question?")
@test_util.patch_get_utility("certbot.plugins.selection.z_util")
@test_util.patch_get_utility("certbot._internal.plugins.selection.z_util")
def test_selection(self, mock_util):
mock_util().menu.side_effect = [(display_util.OK, 0),
(display_util.OK, 1)]
self.assertEqual(self.mock_stand, self._call())
self.assertEqual(mock_util().notification.call_count, 1)
@test_util.patch_get_utility("certbot.plugins.selection.z_util")
@test_util.patch_get_utility("certbot._internal.plugins.selection.z_util")
def test_more_info(self, mock_util):
mock_util().menu.side_effect = [
(display_util.OK, 1),
@ -148,12 +148,12 @@ class ChoosePluginTest(unittest.TestCase):
self.assertEqual(self.mock_stand, self._call())
@test_util.patch_get_utility("certbot.plugins.selection.z_util")
@test_util.patch_get_utility("certbot._internal.plugins.selection.z_util")
def test_no_choice(self, mock_util):
mock_util().menu.return_value = (display_util.CANCEL, 0)
self.assertTrue(self._call() is None)
@test_util.patch_get_utility("certbot.plugins.selection.z_util")
@test_util.patch_get_utility("certbot._internal.plugins.selection.z_util")
def test_new_interaction_avoidance(self, mock_util):
mock_nginx = mock.Mock(
description_with_name="n", misconfigured=False)
@ -174,7 +174,7 @@ class ChoosePluginTest(unittest.TestCase):
self.assertTrue("default" in mock_util().menu.call_args[1])
class GetUnpreparedInstallerTest(test_util.ConfigTestCase):
"""Tests for certbot.plugins.selection.get_unprepared_installer."""
"""Tests for certbot._internal.plugins.selection.get_unprepared_installer."""
def setUp(self):
super(GetUnpreparedInstallerTest, self).setUp()
@ -192,7 +192,7 @@ class GetUnpreparedInstallerTest(test_util.ConfigTestCase):
})
def _call(self):
from certbot.plugins.selection import get_unprepared_installer
from certbot._internal.plugins.selection import get_unprepared_installer
return get_unprepared_installer(self.config, self.plugins)
def test_no_installer_defined(self):

View file

@ -1,4 +1,4 @@
"""Tests for certbot.plugins.standalone."""
"""Tests for certbot._internal.plugins.standalone."""
import socket
# https://github.com/python/typeshed/blob/master/stdlib/2and3/socket.pyi
from socket import errno as socket_errors # type: ignore
@ -22,10 +22,10 @@ from certbot.tests import util as test_util
class ServerManagerTest(unittest.TestCase):
"""Tests for certbot.plugins.standalone.ServerManager."""
"""Tests for certbot._internal.plugins.standalone.ServerManager."""
def setUp(self):
from certbot.plugins.standalone import ServerManager
from certbot._internal.plugins.standalone import ServerManager
self.certs = {} # type: Dict[bytes, Tuple[OpenSSL.crypto.PKey, OpenSSL.crypto.X509]]
self.http_01_resources = {} \
# type: Set[acme_standalone.HTTP01RequestHandler.HTTP01Resource]
@ -82,10 +82,10 @@ def get_open_port():
class AuthenticatorTest(unittest.TestCase):
"""Tests for certbot.plugins.standalone.Authenticator."""
"""Tests for certbot._internal.plugins.standalone.Authenticator."""
def setUp(self):
from certbot.plugins.standalone import Authenticator
from certbot._internal.plugins.standalone import Authenticator
self.config = mock.MagicMock(http01_port=get_open_port())
self.auth = Authenticator(self.config, name="standalone")

View file

@ -1,4 +1,4 @@
"""Tests for certbot.plugins.webroot."""
"""Tests for certbot._internal.plugins.webroot."""
from __future__ import print_function
@ -27,13 +27,13 @@ KEY = jose.JWKRSA.load(test_util.load_vector("rsa512_key.pem"))
class AuthenticatorTest(unittest.TestCase):
"""Tests for certbot.plugins.webroot.Authenticator."""
"""Tests for certbot._internal.plugins.webroot.Authenticator."""
achall = achallenges.KeyAuthorizationAnnotatedChallenge(
challb=acme_util.HTTP01_P, domain="thing.com", account_key=KEY)
def setUp(self):
from certbot.plugins.webroot import Authenticator
from certbot._internal.plugins.webroot import Authenticator
# On Linux directories created by tempfile.mkdtemp inherit their permissions from their
# parent directory. So the actual permissions are inconsistent over various tests env.
# To circumvent this, a dedicated sub-workspace is created under the workspace, using
@ -147,7 +147,7 @@ class AuthenticatorTest(unittest.TestCase):
self.assertRaises(errors.PluginError, self.auth.perform, [])
filesystem.chmod(self.path, 0o700)
@mock.patch("certbot.plugins.webroot.filesystem.copy_ownership_and_apply_mode")
@mock.patch("certbot._internal.plugins.webroot.filesystem.copy_ownership_and_apply_mode")
def test_failed_chown(self, mock_ownership):
mock_ownership.side_effect = OSError(errno.EACCES, "msg")
self.auth.perform([self.achall]) # exception caught and logged
@ -262,7 +262,7 @@ class WebrootActionTest(unittest.TestCase):
challb=acme_util.HTTP01_P, domain="thing.com", account_key=KEY)
def setUp(self):
from certbot.plugins.webroot import Authenticator
from certbot._internal.plugins.webroot import Authenticator
self.path = tempfile.mkdtemp()
self.parser = argparse.ArgumentParser()
self.parser.add_argument("-d", "--domains",
@ -308,7 +308,7 @@ class WebrootActionTest(unittest.TestCase):
self.assertEqual(args.webroot_path, [self.path, other_webroot_path])
def _get_config_after_perform(self, config):
from certbot.plugins.webroot import Authenticator
from certbot._internal.plugins.webroot import Authenticator
auth = Authenticator(config, "webroot")
auth.perform([self.achall])
return auth.config

View file

@ -9,7 +9,7 @@ import traceback
import six
from certbot import constants
from certbot._internal import constants
from certbot import errors
from certbot import util
from certbot.compat import os

View file

@ -93,7 +93,6 @@ class AccountMemoryStorageTest(unittest.TestCase):
class AccountFileStorageTest(test_util.ConfigTestCase):
"""Tests for certbot._internal.account.AccountFileStorage."""
#pylint: disable=too-many-public-methods
def setUp(self):
super(AccountFileStorageTest, self).setUp()
@ -278,7 +277,7 @@ class AccountFileStorageTest(test_util.ConfigTestCase):
self._set_server('https://acme-staging.api.letsencrypt.org/directory')
self.storage.save(self.acc, self.mock_client)
# ensure v2 isn't already linked to it
with mock.patch('certbot.constants.LE_REUSE_SERVERS', {}):
with mock.patch('certbot._internal.constants.LE_REUSE_SERVERS', {}):
self._set_server('https://acme-staging-v02.api.letsencrypt.org/directory')
self.assertRaises(errors.AccountNotFound, self.storage.load, self.acc.id)

View file

@ -56,7 +56,7 @@ class ChallengeFactoryTest(unittest.TestCase):
errors.Error, self.handler._challenge_factory, authzr, [0])
class HandleAuthorizationsTest(unittest.TestCase): # pylint: disable=too-many-public-methods
class HandleAuthorizationsTest(unittest.TestCase):
"""handle_authorizations test.
This tests everything except for all functions under _poll_challenges.

View file

@ -9,7 +9,7 @@ import unittest
import configobj
import mock
from certbot import configuration
from certbot._internal import configuration
from certbot import errors
from certbot.compat import os
from certbot.compat import filesystem
@ -68,7 +68,6 @@ class UpdateLiveSymlinksTest(BaseCertManagerTest):
"""
def test_update_live_symlinks(self):
"""Test update_live_symlinks"""
# pylint: disable=too-many-statements
# create files with incorrect symlinks
from certbot._internal import cert_manager
archive_paths = {}
@ -202,7 +201,7 @@ class CertificatesTest(BaseCertManagerTest):
shutil.rmtree(empty_tempdir)
@mock.patch('certbot._internal.cert_manager.ocsp.RevocationChecker.ocsp_revoked')
def test_report_human_readable(self, mock_revoked): #pylint: disable=too-many-statements
def test_report_human_readable(self, mock_revoked):
mock_revoked.return_value = None
from certbot._internal import cert_manager
import datetime

View file

@ -1,4 +1,4 @@
"""Tests for certbot.cli."""
"""Tests for certbot._internal.cli."""
import argparse
import copy
import tempfile
@ -11,12 +11,12 @@ from six.moves import reload_module # pylint: disable=import-error
from acme import challenges
import certbot.tests.util as test_util
from certbot import cli
from certbot import constants
from certbot._internal import cli
from certbot._internal import constants
from certbot import errors
from certbot.compat import os
from certbot.compat import filesystem
from certbot.plugins import disco
from certbot._internal.plugins import disco
from certbot.tests.util import TempDirTestCase
PLUGINS = disco.PluginsRegistry.find_all()
@ -60,7 +60,7 @@ class FlagDefaultTest(unittest.TestCase):
self.assertEqual(cli.flag_default('logs_dir'), 'C:\\Certbot\\log')
class ParseTest(unittest.TestCase): # pylint: disable=too-many-public-methods
class ParseTest(unittest.TestCase):
'''Test the cli args entrypoint'''
@ -94,7 +94,7 @@ class ParseTest(unittest.TestCase): # pylint: disable=too-many-public-methods
return output.getvalue()
@mock.patch("certbot.cli.flag_default")
@mock.patch("certbot._internal.cli.flag_default")
def test_cli_ini_domains(self, mock_flag_default):
with tempfile.NamedTemporaryFile() as tmp_config:
tmp_config.close() # close now because of compatibility issues on Windows
@ -366,7 +366,7 @@ class ParseTest(unittest.TestCase): # pylint: disable=too-many-public-methods
errors.Error, self.parse, "-n --force-interactive".split())
def test_deploy_hook_conflict(self):
with mock.patch("certbot.cli.sys.stderr"):
with mock.patch("certbot._internal.cli.sys.stderr"):
self.assertRaises(SystemExit, self.parse,
"--renew-hook foo --deploy-hook bar".split())
@ -386,7 +386,7 @@ class ParseTest(unittest.TestCase): # pylint: disable=too-many-public-methods
self.assertEqual(namespace.renew_hook, value)
def test_renew_hook_conflict(self):
with mock.patch("certbot.cli.sys.stderr"):
with mock.patch("certbot._internal.cli.sys.stderr"):
self.assertRaises(SystemExit, self.parse,
"--deploy-hook foo --renew-hook bar".split())
@ -406,7 +406,7 @@ class ParseTest(unittest.TestCase): # pylint: disable=too-many-public-methods
self.assertEqual(namespace.renew_hook, value)
def test_max_log_backups_error(self):
with mock.patch('certbot.cli.sys.stderr'):
with mock.patch('certbot._internal.cli.sys.stderr'):
self.assertRaises(
SystemExit, self.parse, "--max-log-backups foo".split())
self.assertRaises(
@ -462,7 +462,7 @@ class ParseTest(unittest.TestCase): # pylint: disable=too-many-public-methods
class DefaultTest(unittest.TestCase):
"""Tests for certbot.cli._Default."""
"""Tests for certbot._internal.cli._Default."""
def setUp(self):
@ -536,7 +536,7 @@ class SetByCliTest(unittest.TestCase):
def _call_set_by_cli(var, args, verb):
with mock.patch('certbot.cli.helpful_parser') as mock_parser:
with mock.patch('certbot._internal.cli.helpful_parser') as mock_parser:
with test_util.patch_get_utility():
mock_parser.args = args
mock_parser.verb = verb

View file

@ -462,9 +462,8 @@ class ClientTest(ClientTestCommon):
names = [call[0][0] for call in mock_storage.call_args_list]
self.assertEqual(names, ["example_cert", "example.com", "example.com"])
@mock.patch("certbot.cli.helpful_parser")
@mock.patch("certbot._internal.cli.helpful_parser")
def test_save_certificate(self, mock_parser):
# pylint: disable=too-many-locals
certs = ["cert_512.pem", "cert-san_512.pem"]
tmp_path = tempfile.mkdtemp()
filesystem.chmod(tmp_path, 0o755) # TODO: really??

View file

@ -1,9 +1,9 @@
"""Tests for certbot.configuration."""
"""Tests for certbot._internal.configuration."""
import unittest
import mock
from certbot import constants
from certbot._internal import constants
from certbot import errors
from certbot.compat import misc
from certbot.compat import os
@ -11,18 +11,18 @@ from certbot.tests import util as test_util
class NamespaceConfigTest(test_util.ConfigTestCase):
"""Tests for certbot.configuration.NamespaceConfig."""
"""Tests for certbot._internal.configuration.NamespaceConfig."""
def setUp(self):
super(NamespaceConfigTest, self).setUp()
self.config.foo = 'bar'
self.config.foo = 'bar' # pylint: disable=blacklisted-name
self.config.server = 'https://acme-server.org:443/new'
self.config.https_port = 1234
self.config.http01_port = 4321
def test_init_same_ports(self):
self.config.namespace.https_port = 4321
from certbot.configuration import NamespaceConfig
from certbot._internal.configuration import NamespaceConfig
self.assertRaises(errors.Error, NamespaceConfig, self.config.namespace)
def test_proxy_getattr(self):
@ -38,7 +38,7 @@ class NamespaceConfigTest(test_util.ConfigTestCase):
self.assertEqual(['user:pass@acme.server:443', 'p', 'a', 't', 'h'],
self.config.server_path.split(os.path.sep))
@mock.patch('certbot.configuration.constants')
@mock.patch('certbot._internal.configuration.constants')
def test_dynamic_dirs(self, mock_constants):
mock_constants.ACCOUNTS_DIR = 'acc'
mock_constants.BACKUP_DIR = 'backups'
@ -70,7 +70,7 @@ class NamespaceConfigTest(test_util.ConfigTestCase):
os.path.normpath(os.path.join(self.config.work_dir, 't')))
def test_absolute_paths(self):
from certbot.configuration import NamespaceConfig
from certbot._internal.configuration import NamespaceConfig
config_base = "foo"
work_base = "bar"
@ -103,7 +103,7 @@ class NamespaceConfigTest(test_util.ConfigTestCase):
self.assertTrue(os.path.isabs(config.key_dir))
self.assertTrue(os.path.isabs(config.temp_checkpoint_dir))
@mock.patch('certbot.configuration.constants')
@mock.patch('certbot._internal.configuration.constants')
def test_renewal_dynamic_dirs(self, mock_constants):
mock_constants.ARCHIVE_DIR = 'a'
mock_constants.LIVE_DIR = 'l'
@ -118,7 +118,7 @@ class NamespaceConfigTest(test_util.ConfigTestCase):
self.config.config_dir, 'renewal_configs'))
def test_renewal_absolute_paths(self):
from certbot.configuration import NamespaceConfig
from certbot._internal.configuration import NamespaceConfig
config_base = "foo"
work_base = "bar"

View file

@ -164,7 +164,7 @@ class ImportCSRFileTest(unittest.TestCase):
test_util.load_vector('cert_512.pem'))
class MakeKeyTest(unittest.TestCase): # pylint: disable=too-few-public-methods
class MakeKeyTest(unittest.TestCase):
"""Tests for certbot.crypto_util.make_key."""
def test_it(self): # pylint: disable=no-self-use

View file

@ -354,7 +354,6 @@ class ChooseNamesTest(unittest.TestCase):
class SuccessInstallationTest(unittest.TestCase):
# pylint: disable=too-few-public-methods
"""Test the success installation message."""
@classmethod
def _call(cls, names):
@ -376,7 +375,6 @@ class SuccessInstallationTest(unittest.TestCase):
class SuccessRenewalTest(unittest.TestCase):
# pylint: disable=too-few-public-methods
"""Test the success renewal message."""
@classmethod
def _call(cls, names):
@ -397,7 +395,6 @@ class SuccessRenewalTest(unittest.TestCase):
self.assertTrue(name in arg)
class SuccessRevocationTest(unittest.TestCase):
# pylint: disable=too-few-public-methods
"""Test the success revocation message."""
@classmethod
def _call(cls, path):

View file

@ -58,7 +58,6 @@ class FileOutputDisplayTest(unittest.TestCase):
functions look to a user, uncomment the test_visual function.
"""
# pylint:disable=too-many-public-methods
def setUp(self):
super(FileOutputDisplayTest, self).setUp()
self.mock_stdout = mock.MagicMock()

View file

@ -4,7 +4,7 @@ import unittest
import mock
import requests
from certbot import constants
from certbot._internal import constants
import certbot.tests.util as test_util

View file

@ -1,4 +1,4 @@
"""Tests for certbot.hooks."""
"""Tests for certbot._internal.hooks."""
import unittest
import mock
@ -12,14 +12,14 @@ from certbot.tests import util as test_util
class ValidateHooksTest(unittest.TestCase):
"""Tests for certbot.hooks.validate_hooks."""
"""Tests for certbot._internal.hooks.validate_hooks."""
@classmethod
def _call(cls, *args, **kwargs):
from certbot.hooks import validate_hooks
from certbot._internal.hooks import validate_hooks
return validate_hooks(*args, **kwargs)
@mock.patch("certbot.hooks.validate_hook")
@mock.patch("certbot._internal.hooks.validate_hook")
def test_it(self, mock_validate_hook):
config = mock.MagicMock()
self._call(config)
@ -31,30 +31,30 @@ class ValidateHooksTest(unittest.TestCase):
class ValidateHookTest(test_util.TempDirTestCase):
"""Tests for certbot.hooks.validate_hook."""
"""Tests for certbot._internal.hooks.validate_hook."""
@classmethod
def _call(cls, *args, **kwargs):
from certbot.hooks import validate_hook
from certbot._internal.hooks import validate_hook
return validate_hook(*args, **kwargs)
def test_hook_not_executable(self):
# prevent unnecessary modifications to PATH
with mock.patch("certbot.hooks.plug_util.path_surgery"):
with mock.patch("certbot._internal.hooks.plug_util.path_surgery"):
# We just mock out filesystem.is_executable since on Windows, it is difficult
# to get a fully working test around executable permissions. See
# certbot.tests.compat.filesystem::NotExecutableTest for more in-depth tests.
with mock.patch("certbot.hooks.filesystem.is_executable", return_value=False):
with mock.patch("certbot._internal.hooks.filesystem.is_executable", return_value=False):
self.assertRaises(errors.HookCommandNotFound, self._call, 'dummy', "foo")
@mock.patch("certbot.hooks.util.exe_exists")
@mock.patch("certbot._internal.hooks.util.exe_exists")
def test_not_found(self, mock_exe_exists):
mock_exe_exists.return_value = False
with mock.patch("certbot.hooks.plug_util.path_surgery") as mock_ps:
with mock.patch("certbot._internal.hooks.plug_util.path_surgery") as mock_ps:
self.assertRaises(errors.HookCommandNotFound, self._call, "foo", "bar")
self.assertTrue(mock_ps.called)
@mock.patch("certbot.hooks._prog")
@mock.patch("certbot._internal.hooks._prog")
def test_unset(self, mock_prog):
self._call(None, "foo")
self.assertFalse(mock_prog.called)
@ -70,24 +70,24 @@ class HookTest(test_util.ConfigTestCase):
@classmethod
def _call_with_mock_execute(cls, *args, **kwargs):
"""Calls self._call after mocking out certbot.hooks.execute.
"""Calls self._call after mocking out certbot._internal.hooks.execute.
The mock execute object is returned rather than the return value
of self._call.
"""
with mock.patch("certbot.hooks.execute") as mock_execute:
with mock.patch("certbot._internal.hooks.execute") as mock_execute:
mock_execute.return_value = ("", "")
cls._call(*args, **kwargs)
return mock_execute
class PreHookTest(HookTest):
"""Tests for certbot.hooks.pre_hook."""
"""Tests for certbot._internal.hooks.pre_hook."""
@classmethod
def _call(cls, *args, **kwargs):
from certbot.hooks import pre_hook
from certbot._internal.hooks import pre_hook
return pre_hook(*args, **kwargs)
def setUp(self):
@ -107,7 +107,7 @@ class PreHookTest(HookTest):
super(PreHookTest, self).tearDown()
def _reset_pre_hook_already(self):
from certbot.hooks import executed_pre_hooks
from certbot._internal.hooks import executed_pre_hooks
executed_pre_hooks.clear()
def test_certonly(self):
@ -128,7 +128,7 @@ class PreHookTest(HookTest):
self.config.verb = "renew"
os.remove(self.dir_hook)
with mock.patch("certbot.hooks.logger") as mock_logger:
with mock.patch("certbot._internal.hooks.logger") as mock_logger:
mock_execute = self._call_with_mock_execute(self.config)
self.assertFalse(mock_execute.called)
self.assertFalse(mock_logger.info.called)
@ -154,18 +154,18 @@ class PreHookTest(HookTest):
self._test_no_executions_common()
def _test_no_executions_common(self):
with mock.patch("certbot.hooks.logger") as mock_logger:
with mock.patch("certbot._internal.hooks.logger") as mock_logger:
mock_execute = self._call_with_mock_execute(self.config)
self.assertFalse(mock_execute.called)
self.assertTrue(mock_logger.info.called)
class PostHookTest(HookTest):
"""Tests for certbot.hooks.post_hook."""
"""Tests for certbot._internal.hooks.post_hook."""
@classmethod
def _call(cls, *args, **kwargs):
from certbot.hooks import post_hook
from certbot._internal.hooks import post_hook
return post_hook(*args, **kwargs)
def setUp(self):
@ -185,7 +185,7 @@ class PostHookTest(HookTest):
super(PostHookTest, self).tearDown()
def _reset_post_hook_eventually(self):
from certbot.hooks import post_hooks
from certbot._internal.hooks import post_hooks
del post_hooks[:]
def test_certonly_and_run_with_hook(self):
@ -239,27 +239,27 @@ class PostHookTest(HookTest):
self.assertEqual(self._get_eventually(), expected)
def _get_eventually(self):
from certbot.hooks import post_hooks
from certbot._internal.hooks import post_hooks
return post_hooks
class RunSavedPostHooksTest(HookTest):
"""Tests for certbot.hooks.run_saved_post_hooks."""
"""Tests for certbot._internal.hooks.run_saved_post_hooks."""
@classmethod
def _call(cls, *args, **kwargs):
from certbot.hooks import run_saved_post_hooks
from certbot._internal.hooks import run_saved_post_hooks
return run_saved_post_hooks()
def _call_with_mock_execute_and_eventually(self, *args, **kwargs):
"""Call run_saved_post_hooks but mock out execute and eventually
certbot.hooks.post_hooks is replaced with
certbot._internal.hooks.post_hooks is replaced with
self.eventually. The mock execute object is returned rather than
the return value of run_saved_post_hooks.
"""
eventually_path = "certbot.hooks.post_hooks"
eventually_path = "certbot._internal.hooks.post_hooks"
with mock.patch(eventually_path, new=self.eventually):
return self._call_with_mock_execute(*args, **kwargs)
@ -290,7 +290,7 @@ class RenewalHookTest(HookTest):
# pylint: disable=abstract-method
def _call_with_mock_execute(self, *args, **kwargs):
"""Calls self._call after mocking out certbot.hooks.execute.
"""Calls self._call after mocking out certbot._internal.hooks.execute.
The mock execute object is returned rather than the return value
of self._call. The mock execute object asserts that environment
@ -311,7 +311,7 @@ class RenewalHookTest(HookTest):
self.assertEqual(os.environ["RENEWED_LINEAGE"], lineage)
return ("", "")
with mock.patch("certbot.hooks.execute") as mock_execute:
with mock.patch("certbot._internal.hooks.execute") as mock_execute:
mock_execute.side_effect = execute_side_effect
self._call(*args, **kwargs)
return mock_execute
@ -329,14 +329,14 @@ class RenewalHookTest(HookTest):
class DeployHookTest(RenewalHookTest):
"""Tests for certbot.hooks.deploy_hook."""
"""Tests for certbot._internal.hooks.deploy_hook."""
@classmethod
def _call(cls, *args, **kwargs):
from certbot.hooks import deploy_hook
from certbot._internal.hooks import deploy_hook
return deploy_hook(*args, **kwargs)
@mock.patch("certbot.hooks.logger")
@mock.patch("certbot._internal.hooks.logger")
def test_dry_run(self, mock_logger):
self.config.deploy_hook = "foo"
self.config.dry_run = True
@ -345,7 +345,7 @@ class DeployHookTest(RenewalHookTest):
self.assertFalse(mock_execute.called)
self.assertTrue(mock_logger.warning.called)
@mock.patch("certbot.hooks.logger")
@mock.patch("certbot._internal.hooks.logger")
def test_no_hook(self, mock_logger):
self.config.deploy_hook = None
mock_execute = self._call_with_mock_execute(
@ -363,11 +363,11 @@ class DeployHookTest(RenewalHookTest):
class RenewHookTest(RenewalHookTest):
"""Tests for certbot.hooks.renew_hook"""
"""Tests for certbot._internal.hooks.renew_hook"""
@classmethod
def _call(cls, *args, **kwargs):
from certbot.hooks import renew_hook
from certbot._internal.hooks import renew_hook
return renew_hook(*args, **kwargs)
def setUp(self):
@ -385,7 +385,7 @@ class RenewHookTest(RenewalHookTest):
self.config, ["example.org"], "/foo/bar")
mock_execute.assert_called_once_with("deploy-hook", self.config.renew_hook)
@mock.patch("certbot.hooks.logger")
@mock.patch("certbot._internal.hooks.logger")
def test_dry_run(self, mock_logger):
self.config.dry_run = True
mock_execute = self._call_with_mock_execute(
@ -397,7 +397,7 @@ class RenewHookTest(RenewalHookTest):
self.config.renew_hook = None
os.remove(self.dir_hook)
with mock.patch("certbot.hooks.logger") as mock_logger:
with mock.patch("certbot._internal.hooks.logger") as mock_logger:
mock_execute = self._call_with_mock_execute(
self.config, ["example.org"], "/foo/bar")
self.assertFalse(mock_execute.called)
@ -417,11 +417,11 @@ class RenewHookTest(RenewalHookTest):
class ExecuteTest(unittest.TestCase):
"""Tests for certbot.hooks.execute."""
"""Tests for certbot._internal.hooks.execute."""
@classmethod
def _call(cls, *args, **kwargs):
from certbot.hooks import execute
from certbot._internal.hooks import execute
return execute(*args, **kwargs)
def test_it(self):
@ -433,10 +433,10 @@ class ExecuteTest(unittest.TestCase):
def _test_common(self, returncode, stdout, stderr):
given_command = "foo"
given_name = "foo-hook"
with mock.patch("certbot.hooks.Popen") as mock_popen:
with mock.patch("certbot._internal.hooks.Popen") as mock_popen:
mock_popen.return_value.communicate.return_value = (stdout, stderr)
mock_popen.return_value.returncode = returncode
with mock.patch("certbot.hooks.logger") as mock_logger:
with mock.patch("certbot._internal.hooks.logger") as mock_logger:
self.assertEqual(self._call(given_name, given_command), (stderr, stdout))
executed_command = mock_popen.call_args[1].get(
@ -453,11 +453,11 @@ class ExecuteTest(unittest.TestCase):
class ListHooksTest(test_util.TempDirTestCase):
"""Tests for certbot.hooks.list_hooks."""
"""Tests for certbot._internal.hooks.list_hooks."""
@classmethod
def _call(cls, *args, **kwargs):
from certbot.hooks import list_hooks
from certbot._internal.hooks import list_hooks
return list_hooks(*args, **kwargs)
def test_empty(self):

View file

@ -11,7 +11,7 @@ import six
from acme import messages
from acme.magic_typing import Optional # pylint: disable=unused-import, no-name-in-module
from certbot import constants
from certbot._internal import constants
from certbot import errors
from certbot import util
from certbot.compat import filesystem

View file

@ -22,9 +22,9 @@ from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-
import certbot.tests.util as test_util
from certbot._internal import account
from certbot import cli
from certbot import configuration
from certbot import constants
from certbot._internal import cli
from certbot._internal import configuration
from certbot._internal import constants
from certbot import crypto_util
from certbot import errors
from certbot import interfaces # pylint: disable=unused-import
@ -33,10 +33,10 @@ from certbot._internal import updater
from certbot import util
from certbot.compat import os
from certbot.compat import filesystem
from certbot.plugins import disco
from certbot._internal.plugins import disco
from certbot.plugins import enhancements
from certbot.plugins import manual
from certbot.plugins import null
from certbot._internal.plugins import manual
from certbot._internal.plugins import null
CERT_PATH = test_util.vector_path('cert_512.pem')
CERT = test_util.vector_path('cert_512.pem')
@ -356,7 +356,6 @@ class DeleteIfAppropriateTest(test_util.ConfigTestCase):
util_mock.yesno.return_value = False
self._test_delete_opt_out_common(mock_get_utility)
# pylint: disable=too-many-arguments
@mock.patch('certbot._internal.storage.renewal_file_for_certname')
@mock.patch('certbot._internal.cert_manager.delete')
@mock.patch('certbot._internal.cert_manager.match_and_check_overlaps')
@ -376,7 +375,6 @@ class DeleteIfAppropriateTest(test_util.ConfigTestCase):
self._call(config)
mock_delete.assert_not_called()
# pylint: disable=too-many-arguments
@mock.patch('certbot._internal.storage.renewal_file_for_certname')
@mock.patch('certbot._internal.cert_manager.match_and_check_overlaps')
@mock.patch('certbot._internal.storage.full_archive_path')
@ -395,7 +393,6 @@ class DeleteIfAppropriateTest(test_util.ConfigTestCase):
self._call(config)
self.assertEqual(mock_delete.call_count, 1)
# pylint: disable=too-many-arguments
@mock.patch('certbot._internal.storage.renewal_file_for_certname')
@mock.patch('certbot._internal.cert_manager.match_and_check_overlaps')
@mock.patch('certbot._internal.storage.full_archive_path')
@ -416,7 +413,6 @@ class DeleteIfAppropriateTest(test_util.ConfigTestCase):
self._call(config)
self.assertEqual(mock_delete.call_count, 1)
# pylint: disable=too-many-arguments
@mock.patch('certbot._internal.storage.renewal_file_for_certname')
@mock.patch('certbot._internal.cert_manager.match_and_check_overlaps')
@mock.patch('certbot._internal.storage.full_archive_path')
@ -507,7 +503,7 @@ class DetermineAccountTest(test_util.ConfigTestCase):
self.assertEqual('other email', self.config.email)
class MainTest(test_util.ConfigTestCase): # pylint: disable=too-many-public-methods
class MainTest(test_util.ConfigTestCase):
"""Tests for different commands."""
def setUp(self):
@ -715,7 +711,7 @@ class MainTest(test_util.ConfigTestCase): # pylint: disable=too-many-public-met
# This needed two calls to find_all(), which we're avoiding for now
# because of possible side effects:
# https://github.com/letsencrypt/letsencrypt/commit/51ed2b681f87b1eb29088dd48718a54f401e4855
#with mock.patch('certbot.cli.plugins_testable') as plugins:
#with mock.patch('certbot._internal.cli.plugins_testable') as plugins:
# plugins.return_value = {"apache": True, "nginx": True}
# ret, _, _, _ = self._call(args)
# self.assertTrue("Too many flags setting" in ret)
@ -970,7 +966,6 @@ class MainTest(test_util.ConfigTestCase): # pylint: disable=too-many-public-met
args=None, should_renew=True, error_expected=False,
quiet_mode=False, expiry_date=datetime.datetime.now(),
reuse_key=False):
# pylint: disable=too-many-locals,too-many-arguments,too-many-branches
cert_path = test_util.vector_path('cert_512.pem')
chain_path = os.path.normpath(os.path.join(self.config.config_dir,
'live/foo.bar/fullchain.pem'))
@ -1145,7 +1140,7 @@ class MainTest(test_util.ConfigTestCase): # pylint: disable=too-many-public-met
test_util.make_lineage(self.config.config_dir, 'sample-renewal.conf')
args = ["renew", "--dry-run", "--post-hook=no-such-command",
"--disable-hook-validation"]
with mock.patch("certbot.hooks.post_hook"):
with mock.patch("certbot._internal.hooks.post_hook"):
self._test_renewal_common(True, [], args=args, should_renew=True,
error_expected=False)
@ -1220,7 +1215,7 @@ class MainTest(test_util.ConfigTestCase): # pylint: disable=too-many-public-met
self._test_renew_common(renewalparams=renewalparams, error_expected=True,
names=names, assert_oc_called=False)
@mock.patch('certbot.plugins.selection.choose_configurator_plugins')
@mock.patch('certbot._internal.plugins.selection.choose_configurator_plugins')
def test_renew_with_configurator(self, mock_sel):
mock_sel.return_value = (mock.MagicMock(), mock.MagicMock())
renewalparams = {'authenticator': 'webroot'}
@ -1400,33 +1395,6 @@ class MainTest(test_util.ConfigTestCase): # pylint: disable=too-many-public-met
"user@example.org"])
self.assertTrue("Could not find an existing account" in x[0])
# TODO: When `certbot register --update-registration` is fully deprecated,
# delete the following test
def test_update_registration_no_existing_accounts_deprecated(self):
# with mock.patch('certbot._internal.main.client') as mocked_client:
with mock.patch('certbot._internal.main.account') as mocked_account:
mocked_storage = mock.MagicMock()
mocked_account.AccountFileStorage.return_value = mocked_storage
mocked_storage.find_all.return_value = []
x = self._call_no_clientmock(
["register", "--update-registration", "--email",
"user@example.org"])
self.assertTrue("Could not find an existing account" in x[0])
# TODO: When `certbot register --update-registration` is fully deprecated,
# delete the following test
def test_update_registration_unsafely_deprecated(self):
# This test will become obsolete when register --update-registration
# supports removing an e-mail address from the account
with mock.patch('certbot._internal.main.account') as mocked_account:
mocked_storage = mock.MagicMock()
mocked_account.AccountFileStorage.return_value = mocked_storage
mocked_storage.find_all.return_value = ["an account"]
x = self._call_no_clientmock(
"register --update-registration "
"--register-unsafely-without-email".split())
self.assertTrue("--register-unsafely-without-email" in x[0])
@mock.patch('certbot._internal.main.display_ops.get_email')
@test_util.patch_get_utility()
def test_update_account_with_email(self, mock_utility, mock_email):
@ -1457,43 +1425,7 @@ class MainTest(test_util.ConfigTestCase): # pylint: disable=too-many-public-met
email in mock_utility().add_message.call_args[0][0])
self.assertTrue(mock_handle.called)
# TODO: When `certbot register --update-registration` is fully deprecated,
# delete the following test
@mock.patch('certbot._internal.main.display_ops.get_email')
@test_util.patch_get_utility()
def test_update_registration_with_email_deprecated(self, mock_utility, mock_email):
email = "user@example.com"
mock_email.return_value = email
with mock.patch('certbot._internal.eff.handle_subscription') as mock_handle:
with mock.patch('certbot._internal.main._determine_account') as mocked_det:
with mock.patch('certbot._internal.main.account') as mocked_account:
with mock.patch('certbot._internal.main.client') as mocked_client:
mocked_storage = mock.MagicMock()
mocked_account.AccountFileStorage.return_value = mocked_storage
mocked_storage.find_all.return_value = ["an account"]
mock_acc = mock.MagicMock()
mock_regr = mock_acc.regr
mocked_det.return_value = (mock_acc, "foo")
cb_client = mock.MagicMock()
mocked_client.Client.return_value = cb_client
x = self._call_no_clientmock(
["register", "--update-registration"])
# When registration change succeeds, the return value
# of register() is None
self.assertTrue(x[0] is None)
# and we got supposedly did update the registration from
# the server
reg_arg = cb_client.acme.update_registration.call_args[0][0]
# Test the return value of .update() was used because
# the regr is immutable.
self.assertEqual(reg_arg, mock_regr.update())
# and we saved the updated registration on disk
self.assertTrue(mocked_storage.save_regr.called)
self.assertTrue(
email in mock_utility().add_message.call_args[0][0])
self.assertTrue(mock_handle.called)
@mock.patch('certbot.plugins.selection.choose_configurator_plugins')
@mock.patch('certbot._internal.plugins.selection.choose_configurator_plugins')
@mock.patch('certbot._internal.updater._run_updaters')
def test_plugin_selection_error(self, mock_run, mock_choose):
mock_choose.side_effect = errors.PluginSelectionError

View file

@ -4,7 +4,7 @@ import mock
from acme import challenges
from certbot import configuration
from certbot._internal import configuration
from certbot import errors
from certbot._internal import storage
@ -12,7 +12,7 @@ import certbot.tests.util as test_util
class RenewalTest(test_util.ConfigTestCase):
@mock.patch('certbot.cli.set_by_cli')
@mock.patch('certbot._internal.cli.set_by_cli')
def test_ancient_webroot_renewal_conf(self, mock_set_by_cli):
mock_set_by_cli.return_value = False
rc_path = test_util.make_lineage(
@ -31,7 +31,8 @@ class RenewalTest(test_util.ConfigTestCase):
@mock.patch('certbot._internal.renewal.cli.set_by_cli')
def test_webroot_params_conservation(self, mock_set_by_cli):
# For more details about why this test is important, see:
# certbot.plugins.webroot_test::WebrootActionTest::test_webroot_map_partial_without_perform
# certbot._internal.plugins.webroot_test::
# WebrootActionTest::test_webroot_map_partial_without_perform
from certbot._internal import renewal
mock_set_by_cli.return_value = False

View file

@ -22,8 +22,8 @@ class RenewUpdaterTest(test_util.ConfigTestCase):
self.mockinstaller = mock.MagicMock(spec=enhancements.AutoHSTSEnhancement)
@mock.patch('certbot._internal.main._get_and_save_cert')
@mock.patch('certbot.plugins.selection.choose_configurator_plugins')
@mock.patch('certbot.plugins.selection.get_unprepared_installer')
@mock.patch('certbot._internal.plugins.selection.choose_configurator_plugins')
@mock.patch('certbot._internal.plugins.selection.get_unprepared_installer')
@test_util.patch_get_utility()
def test_server_updates(self, _, mock_geti, mock_select, mock_getsave):
mock_getsave.return_value = mock.MagicMock()
@ -64,7 +64,7 @@ class RenewUpdaterTest(test_util.ConfigTestCase):
self.assertEqual(mock_log.call_args[0][0],
"Skipping renewal deployer in dry-run mode.")
@mock.patch('certbot.plugins.selection.get_unprepared_installer')
@mock.patch('certbot._internal.plugins.selection.get_unprepared_installer')
def test_enhancement_updates(self, mock_geti):
mock_geti.return_value = self.mockinstaller
updater.run_generic_updaters(self.config, mock.MagicMock(), None)
@ -76,7 +76,7 @@ class RenewUpdaterTest(test_util.ConfigTestCase):
self.mockinstaller)
self.assertTrue(self.mockinstaller.deploy_autohsts.called)
@mock.patch('certbot.plugins.selection.get_unprepared_installer')
@mock.patch('certbot._internal.plugins.selection.get_unprepared_installer')
def test_enhancement_updates_not_called(self, mock_geti):
self.config.disable_renew_updates = True
mock_geti.return_value = self.mockinstaller
@ -89,7 +89,7 @@ class RenewUpdaterTest(test_util.ConfigTestCase):
self.mockinstaller)
self.assertFalse(self.mockinstaller.deploy_autohsts.called)
@mock.patch('certbot.plugins.selection.get_unprepared_installer')
@mock.patch('certbot._internal.plugins.selection.get_unprepared_installer')
def test_enhancement_no_updater(self, mock_geti):
FAKEINDEX = [
{

View file

@ -14,7 +14,6 @@ from certbot.tests import util as test_util
class ReverterCheckpointLocalTest(test_util.ConfigTestCase):
# pylint: disable=too-many-instance-attributes, too-many-public-methods
"""Test the Reverter Class."""
def setUp(self):
super(ReverterCheckpointLocalTest, self).setUp()
@ -277,7 +276,6 @@ class ReverterCheckpointLocalTest(test_util.ConfigTestCase):
class TestFullCheckpointsReverter(test_util.ConfigTestCase):
# pylint: disable=too-many-instance-attributes
"""Tests functions having to deal with full checkpoints."""
def setUp(self):
super(TestFullCheckpointsReverter, self).setUp()

View file

@ -43,8 +43,8 @@ class RelevantValuesTest(unittest.TestCase):
from certbot._internal.storage import relevant_values
return relevant_values(*args, **kwargs)
@mock.patch("certbot.cli.option_was_set")
@mock.patch("certbot.plugins.disco.PluginsRegistry.find_all")
@mock.patch("certbot._internal.cli.option_was_set")
@mock.patch("certbot._internal.plugins.disco.PluginsRegistry.find_all")
def test_namespace(self, mock_find_all, mock_option_was_set):
mock_find_all.return_value = ["certbot-foo:bar"]
mock_option_was_set.return_value = True
@ -53,7 +53,7 @@ class RelevantValuesTest(unittest.TestCase):
self.assertEqual(
self._call(self.values.copy()), self.values)
@mock.patch("certbot.cli.option_was_set")
@mock.patch("certbot._internal.cli.option_was_set")
def test_option_set(self, mock_option_was_set):
mock_option_was_set.return_value = True
@ -65,7 +65,7 @@ class RelevantValuesTest(unittest.TestCase):
self.assertEqual(self._call(self.values), expected_relevant_values)
@mock.patch("certbot.cli.option_was_set")
@mock.patch("certbot._internal.cli.option_was_set")
def test_option_unset(self, mock_option_was_set):
mock_option_was_set.return_value = False
@ -140,7 +140,6 @@ class BaseRenewableCertTest(test_util.ConfigTestCase):
class RenewableCertTests(BaseRenewableCertTest):
# pylint: disable=too-many-public-methods
"""Tests for certbot._internal.storage."""
def test_initialization(self):
@ -202,7 +201,7 @@ class RenewableCertTests(BaseRenewableCertTest):
self.assertTrue("version" in mock_logger.info.call_args[0][0])
def test_consistent(self):
# pylint: disable=too-many-statements,protected-access
# pylint: disable=protected-access
oldcert = self.test_rc.cert
self.test_rc.cert = "relative/path"
# Absolute path for item requirement
@ -483,7 +482,6 @@ class RenewableCertTests(BaseRenewableCertTest):
def test_should_autorenew(self, mock_ocsp, mock_cli):
"""Test should_autorenew on the basis of reasons other than
expiry time window."""
# pylint: disable=too-many-statements
mock_cli.set_by_cli.return_value = False
# Autorenewal turned off
self.test_rc.configuration["renewalparams"] = {"autorenew": "False"}

View file

@ -19,8 +19,8 @@ from six.moves import reload_module # pylint: disable=import-error
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from certbot import configuration
from certbot import constants
from certbot._internal import configuration
from certbot._internal import constants
from certbot import interfaces
from certbot._internal import lock
from certbot._internal import storage

View file

@ -19,7 +19,7 @@ import six
from acme.magic_typing import Tuple, Union # pylint: disable=unused-import, no-name-in-module
from certbot import constants
from certbot._internal import constants
from certbot import errors
from certbot._internal import lock
from certbot.compat import os

View file

@ -1,5 +0,0 @@
:mod:`certbot.cli`
----------------------
.. automodule:: certbot.cli
:members:

View file

@ -1,5 +0,0 @@
:mod:`certbot.configuration`
--------------------------------
.. automodule:: certbot.configuration
:members:

View file

@ -1,9 +0,0 @@
:mod:`certbot.constants`
-----------------------------------
.. automodule:: certbot.constants
:members:
:exclude-members: SSL_DHPARAMS_SRC
.. autodata:: SSL_DHPARAMS_SRC
:annotation: = '/path/to/certbot/ssl-dhparams.pem'

View file

@ -1,5 +0,0 @@
:mod:`certbot.hooks`
------------------------
.. automodule:: certbot.hooks
:members:

View file

@ -1,5 +0,0 @@
:mod:`certbot.plugins.disco`
--------------------------------
.. automodule:: certbot.plugins.disco
:members:

View file

@ -1,5 +0,0 @@
:mod:`certbot.plugins.manual`
---------------------------------
.. automodule:: certbot.plugins.manual
:members:

View file

@ -1,5 +0,0 @@
:mod:`certbot.plugins.selection`
------------------------------------
.. automodule:: certbot.plugins.selection
:members:

View file

@ -1,5 +0,0 @@
:mod:`certbot.plugins.standalone`
-------------------------------------
.. automodule:: certbot.plugins.standalone
:members:

View file

@ -1,5 +0,0 @@
:mod:`certbot.plugins.webroot`
----------------------------------
.. automodule:: certbot.plugins.webroot
:members:

View file

@ -36,29 +36,36 @@ run Certbot in Docker. You can find instructions for how to do this :ref:`here
install dependencies and set up a virtual environment where you can run
Certbot.
Install the OS system dependencies required to run Certbot.
.. code-block:: shell
# For APT-based distributions (e.g. Debian, Ubuntu ...)
sudo apt update
sudo apt install python3-dev python3-venv gcc libaugeas0 libssl-dev \
libffi-dev ca-certificates openssl
# For RPM-based distributions (e.g. Fedora, CentOS ...)
# NB1: old distributions will use yum instead of dnf
# NB2: RHEL-based distributions use python3X-devel instead of python3-devel (e.g. python36-devel)
sudo dnf install python3-devel gcc augeas-libs openssl-devel libffi-devel \
redhat-rpm-config ca-certificates openssl
Set up the Python virtual environment that will host your Certbot local instance.
.. code-block:: shell
cd certbot
./certbot-auto --debug --os-packages-only
python tools/venv.py
If you have Python3 available and want to use it, run the ``venv3.py`` script.
.. code-block:: shell
python tools/venv3.py
.. note:: You may need to repeat this when
Certbot's dependencies change or when a new plugin is introduced.
You can now run the copy of Certbot from git either by executing
``venv/bin/certbot``, or by activating the virtual environment. You can do the
``venv3/bin/certbot``, or by activating the virtual environment. You can do the
latter by running:
.. code-block:: shell
source venv/bin/activate
# or
source venv3/bin/activate
After running this command, ``certbot`` and development tools like ``ipdb``,

View file

@ -1145,63 +1145,70 @@ if [ "$1" = "--le-auto-phase2" ]; then
# ```
ConfigArgParse==0.14.0 \
--hash=sha256:2e2efe2be3f90577aca9415e32cb629aa2ecd92078adbe27b53a03e53ff12e91
asn1crypto==0.24.0 \
--hash=sha256:2f1adbb7546ed199e3c90ef23ec95c5cf3585bac7d11fb7eb562a3fe89c64e87 \
--hash=sha256:9d5c20441baf0cb60a4ac34cc447c6c189024b6b4c6cd7877034f4965c464e49
certifi==2019.6.16 \
--hash=sha256:046832c04d4e752f37383b628bc601a7ea7211496b4638f6514d0e5b9acc4939 \
--hash=sha256:945e3ba63a0b9f577b1395204e13c3a231f9bc0223888be653286534e5873695
cffi==1.12.3 \
--hash=sha256:041c81822e9f84b1d9c401182e174996f0bae9991f33725d059b771744290774 \
--hash=sha256:046ef9a22f5d3eed06334d01b1e836977eeef500d9b78e9ef693f9380ad0b83d \
--hash=sha256:066bc4c7895c91812eff46f4b1c285220947d4aa46fa0a2651ff85f2afae9c90 \
--hash=sha256:066c7ff148ae33040c01058662d6752fd73fbc8e64787229ea8498c7d7f4041b \
--hash=sha256:2444d0c61f03dcd26dbf7600cf64354376ee579acad77aef459e34efcb438c63 \
--hash=sha256:300832850b8f7967e278870c5d51e3819b9aad8f0a2c8dbe39ab11f119237f45 \
--hash=sha256:34c77afe85b6b9e967bd8154e3855e847b70ca42043db6ad17f26899a3df1b25 \
--hash=sha256:46de5fa00f7ac09f020729148ff632819649b3e05a007d286242c4882f7b1dc3 \
--hash=sha256:4aa8ee7ba27c472d429b980c51e714a24f47ca296d53f4d7868075b175866f4b \
--hash=sha256:4d0004eb4351e35ed950c14c11e734182591465a33e960a4ab5e8d4f04d72647 \
--hash=sha256:4e3d3f31a1e202b0f5a35ba3bc4eb41e2fc2b11c1eff38b362de710bcffb5016 \
--hash=sha256:50bec6d35e6b1aaeb17f7c4e2b9374ebf95a8975d57863546fa83e8d31bdb8c4 \
--hash=sha256:55cad9a6df1e2a1d62063f79d0881a414a906a6962bc160ac968cc03ed3efcfb \
--hash=sha256:5662ad4e4e84f1eaa8efce5da695c5d2e229c563f9d5ce5b0113f71321bcf753 \
--hash=sha256:59b4dc008f98fc6ee2bb4fd7fc786a8d70000d058c2bbe2698275bc53a8d3fa7 \
--hash=sha256:73e1ffefe05e4ccd7bcea61af76f36077b914f92b76f95ccf00b0c1b9186f3f9 \
--hash=sha256:a1f0fd46eba2d71ce1589f7e50a9e2ffaeb739fb2c11e8192aa2b45d5f6cc41f \
--hash=sha256:a2e85dc204556657661051ff4bab75a84e968669765c8a2cd425918699c3d0e8 \
--hash=sha256:a5457d47dfff24882a21492e5815f891c0ca35fefae8aa742c6c263dac16ef1f \
--hash=sha256:a8dccd61d52a8dae4a825cdbb7735da530179fea472903eb871a5513b5abbfdc \
--hash=sha256:ae61af521ed676cf16ae94f30fe202781a38d7178b6b4ab622e4eec8cefaff42 \
--hash=sha256:b012a5edb48288f77a63dba0840c92d0504aa215612da4541b7b42d849bc83a3 \
--hash=sha256:d2c5cfa536227f57f97c92ac30c8109688ace8fa4ac086d19d0af47d134e2909 \
--hash=sha256:d42b5796e20aacc9d15e66befb7a345454eef794fdb0737d1af593447c6c8f45 \
--hash=sha256:dee54f5d30d775f525894d67b1495625dd9322945e7fee00731952e0368ff42d \
--hash=sha256:e070535507bd6aa07124258171be2ee8dfc19119c28ca94c9dfb7efd23564512 \
--hash=sha256:e1ff2748c84d97b065cc95429814cdba39bcbd77c9c85c89344b317dc0d9cbff \
--hash=sha256:ed851c75d1e0e043cbf5ca9a8e1b13c4c90f3fbd863dacb01c0808e2b5204201
certifi==2019.9.11 \
--hash=sha256:e4f3620cfea4f83eedc95b24abd9cd56f3c4b146dd0177e83a21b4eb49e21e50 \
--hash=sha256:fd7c7c74727ddcf00e9acd26bba8da604ffec95bf1c2144e67aff7a8b50e6cef
cffi==1.13.2 \
--hash=sha256:0b49274afc941c626b605fb59b59c3485c17dc776dc3cc7cc14aca74cc19cc42 \
--hash=sha256:0e3ea92942cb1168e38c05c1d56b0527ce31f1a370f6117f1d490b8dcd6b3a04 \
--hash=sha256:135f69aecbf4517d5b3d6429207b2dff49c876be724ac0c8bf8e1ea99df3d7e5 \
--hash=sha256:19db0cdd6e516f13329cba4903368bff9bb5a9331d3410b1b448daaadc495e54 \
--hash=sha256:2781e9ad0e9d47173c0093321bb5435a9dfae0ed6a762aabafa13108f5f7b2ba \
--hash=sha256:291f7c42e21d72144bb1c1b2e825ec60f46d0a7468f5346841860454c7aa8f57 \
--hash=sha256:2c5e309ec482556397cb21ede0350c5e82f0eb2621de04b2633588d118da4396 \
--hash=sha256:2e9c80a8c3344a92cb04661115898a9129c074f7ab82011ef4b612f645939f12 \
--hash=sha256:32a262e2b90ffcfdd97c7a5e24a6012a43c61f1f5a57789ad80af1d26c6acd97 \
--hash=sha256:3c9fff570f13480b201e9ab69453108f6d98244a7f495e91b6c654a47486ba43 \
--hash=sha256:415bdc7ca8c1c634a6d7163d43fb0ea885a07e9618a64bda407e04b04333b7db \
--hash=sha256:42194f54c11abc8583417a7cf4eaff544ce0de8187abaf5d29029c91b1725ad3 \
--hash=sha256:4424e42199e86b21fc4db83bd76909a6fc2a2aefb352cb5414833c030f6ed71b \
--hash=sha256:4a43c91840bda5f55249413037b7a9b79c90b1184ed504883b72c4df70778579 \
--hash=sha256:599a1e8ff057ac530c9ad1778293c665cb81a791421f46922d80a86473c13346 \
--hash=sha256:5c4fae4e9cdd18c82ba3a134be256e98dc0596af1e7285a3d2602c97dcfa5159 \
--hash=sha256:5ecfa867dea6fabe2a58f03ac9186ea64da1386af2159196da51c4904e11d652 \
--hash=sha256:62f2578358d3a92e4ab2d830cd1c2049c9c0d0e6d3c58322993cc341bdeac22e \
--hash=sha256:6471a82d5abea994e38d2c2abc77164b4f7fbaaf80261cb98394d5793f11b12a \
--hash=sha256:6d4f18483d040e18546108eb13b1dfa1000a089bcf8529e30346116ea6240506 \
--hash=sha256:71a608532ab3bd26223c8d841dde43f3516aa5d2bf37b50ac410bb5e99053e8f \
--hash=sha256:74a1d8c85fb6ff0b30fbfa8ad0ac23cd601a138f7509dc617ebc65ef305bb98d \
--hash=sha256:7b93a885bb13073afb0aa73ad82059a4c41f4b7d8eb8368980448b52d4c7dc2c \
--hash=sha256:7d4751da932caaec419d514eaa4215eaf14b612cff66398dd51129ac22680b20 \
--hash=sha256:7f627141a26b551bdebbc4855c1157feeef18241b4b8366ed22a5c7d672ef858 \
--hash=sha256:8169cf44dd8f9071b2b9248c35fc35e8677451c52f795daa2bb4643f32a540bc \
--hash=sha256:aa00d66c0fab27373ae44ae26a66a9e43ff2a678bf63a9c7c1a9a4d61172827a \
--hash=sha256:ccb032fda0873254380aa2bfad2582aedc2959186cce61e3a17abc1a55ff89c3 \
--hash=sha256:d754f39e0d1603b5b24a7f8484b22d2904fa551fe865fd0d4c3332f078d20d4e \
--hash=sha256:d75c461e20e29afc0aee7172a0950157c704ff0dd51613506bd7d82b718e7410 \
--hash=sha256:dcd65317dd15bc0451f3e01c80da2216a31916bdcffd6221ca1202d96584aa25 \
--hash=sha256:e570d3ab32e2c2861c4ebe6ffcad6a8abf9347432a37608fe1fbd157b3f0036b \
--hash=sha256:fd43a88e045cf992ed09fa724b5315b790525f2676883a6ea64e3263bae6549d
chardet==3.0.4 \
--hash=sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae \
--hash=sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691
configobj==5.0.6 \
--hash=sha256:a2f5650770e1c87fb335af19a9b7eb73fc05ccf22144eb68db7d00cd2bcb0902
cryptography==2.7 \
--hash=sha256:24b61e5fcb506424d3ec4e18bca995833839bf13c59fc43e530e488f28d46b8c \
--hash=sha256:25dd1581a183e9e7a806fe0543f485103232f940fcfc301db65e630512cce643 \
--hash=sha256:3452bba7c21c69f2df772762be0066c7ed5dc65df494a1d53a58b683a83e1216 \
--hash=sha256:41a0be220dd1ed9e998f5891948306eb8c812b512dc398e5a01846d855050799 \
--hash=sha256:5751d8a11b956fbfa314f6553d186b94aa70fdb03d8a4d4f1c82dcacf0cbe28a \
--hash=sha256:5f61c7d749048fa6e3322258b4263463bfccefecb0dd731b6561cb617a1d9bb9 \
--hash=sha256:72e24c521fa2106f19623a3851e9f89ddfdeb9ac63871c7643790f872a305dfc \
--hash=sha256:7b97ae6ef5cba2e3bb14256625423413d5ce8d1abb91d4f29b6d1a081da765f8 \
--hash=sha256:961e886d8a3590fd2c723cf07be14e2a91cf53c25f02435c04d39e90780e3b53 \
--hash=sha256:96d8473848e984184b6728e2c9d391482008646276c3ff084a1bd89e15ff53a1 \
--hash=sha256:ae536da50c7ad1e002c3eee101871d93abdc90d9c5f651818450a0d3af718609 \
--hash=sha256:b0db0cecf396033abb4a93c95d1602f268b3a68bb0a9cc06a7cff587bb9a7292 \
--hash=sha256:cfee9164954c186b191b91d4193989ca994703b2fff406f71cf454a2d3c7327e \
--hash=sha256:e6347742ac8f35ded4a46ff835c60e68c22a536a8ae5c4422966d06946b6d4c6 \
--hash=sha256:f27d93f0139a3c056172ebb5d4f9056e770fdf0206c2f422ff2ebbad142e09ed \
--hash=sha256:f57b76e46a58b63d1c6375017f4564a28f19a5ca912691fd2e4261b3414b618d
cryptography==2.8 \
--hash=sha256:02079a6addc7b5140ba0825f542c0869ff4df9a69c360e339ecead5baefa843c \
--hash=sha256:1df22371fbf2004c6f64e927668734070a8953362cd8370ddd336774d6743595 \
--hash=sha256:369d2346db5934345787451504853ad9d342d7f721ae82d098083e1f49a582ad \
--hash=sha256:3cda1f0ed8747339bbdf71b9f38ca74c7b592f24f65cdb3ab3765e4b02871651 \
--hash=sha256:44ff04138935882fef7c686878e1c8fd80a723161ad6a98da31e14b7553170c2 \
--hash=sha256:4b1030728872c59687badcca1e225a9103440e467c17d6d1730ab3d2d64bfeff \
--hash=sha256:58363dbd966afb4f89b3b11dfb8ff200058fbc3b947507675c19ceb46104b48d \
--hash=sha256:6ec280fb24d27e3d97aa731e16207d58bd8ae94ef6eab97249a2afe4ba643d42 \
--hash=sha256:7270a6c29199adc1297776937a05b59720e8a782531f1f122f2eb8467f9aab4d \
--hash=sha256:73fd30c57fa2d0a1d7a49c561c40c2f79c7d6c374cc7750e9ac7c99176f6428e \
--hash=sha256:7f09806ed4fbea8f51585231ba742b58cbcfbfe823ea197d8c89a5e433c7e912 \
--hash=sha256:90df0cc93e1f8d2fba8365fb59a858f51a11a394d64dbf3ef844f783844cc793 \
--hash=sha256:971221ed40f058f5662a604bd1ae6e4521d84e6cad0b7b170564cc34169c8f13 \
--hash=sha256:a518c153a2b5ed6b8cc03f7ae79d5ffad7315ad4569b2d5333a13c38d64bd8d7 \
--hash=sha256:b0de590a8b0979649ebeef8bb9f54394d3a41f66c5584fff4220901739b6b2f0 \
--hash=sha256:b43f53f29816ba1db8525f006fa6f49292e9b029554b3eb56a189a70f2a40879 \
--hash=sha256:d31402aad60ed889c7e57934a03477b572a03af7794fa8fb1780f21ea8f6551f \
--hash=sha256:de96157ec73458a7f14e3d26f17f8128c959084931e8997b9e655a39c8fde9f9 \
--hash=sha256:df6b4dca2e11865e6cfbfb708e800efb18370f5a46fd601d3755bc7f85b3a8a2 \
--hash=sha256:ecadccc7ba52193963c0475ac9f6fa28ac01e01349a2ca48509667ef41ffd2cf \
--hash=sha256:fb81c17e0ebe3358486cd8cc3ad78adbae58af12fc2bf2bc0bb84e8090fa5ce8
distro==1.4.0 \
--hash=sha256:362dde65d846d23baee4b5c058c8586f219b5a54be1cf5fc6ff55c4578392f57 \
--hash=sha256:eedf82a470ebe7d010f1872c17237c79ab04097948800029994fa458e52fb4b4
@ -1213,14 +1220,14 @@ enum34==1.1.6 \
funcsigs==1.0.2 \
--hash=sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca \
--hash=sha256:a7bb0f2cf3a3fd1ab2732cb49eba4252c2af4240442415b4abce3b87022a8f50
future==0.17.1 \
--hash=sha256:67045236dcfd6816dc439556d009594abf643e5eb48992e36beac09c2ca659b8
future==0.18.2 \
--hash=sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d
idna==2.8 \
--hash=sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407 \
--hash=sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c
ipaddress==1.0.22 \
--hash=sha256:64b28eec5e78e7510698f6d4da08800a5c575caa4a286c93d651c5d3ff7b6794 \
--hash=sha256:b146c751ea45cad6188dd6cf2d9b757f6f4f8d6ffb96a023e6f2e26eea02a72c
ipaddress==1.0.23 \
--hash=sha256:6e0f4a39e66cb5bb9a137b00276a2eff74f93b71dcbdad6f10ff7df9d3557fcc \
--hash=sha256:b7f8e0369580bb4a24d5ba1d7cc29660a4a6987763faf1d8a8046830e020e7e2
josepy==1.2.0 \
--hash=sha256:8ea15573203f28653c00f4ac0142520777b1c59d9eddd8da3f256c6ba3cac916 \
--hash=sha256:9cec9a839fe9520f0420e4f38e7219525daccce4813296627436fe444cd002d3
@ -1230,9 +1237,9 @@ mock==1.3.0 \
parsedatetime==2.4 \
--hash=sha256:3d817c58fb9570d1eec1dd46fa9448cd644eeed4fb612684b02dfda3a79cb84b \
--hash=sha256:9ee3529454bf35c40a77115f5a596771e59e1aee8c53306f346c461b8e913094
pbr==5.4.2 \
--hash=sha256:56e52299170b9492513c64be44736d27a512fa7e606f21942160b68ce510b4bc \
--hash=sha256:9b321c204a88d8ab5082699469f52cc94c5da45c51f114113d01b3d993c24cdf
pbr==5.4.3 \
--hash=sha256:2c8e420cd4ed4cec4e7999ee47409e876af575d4c35a45840d59e8b5f3155ab8 \
--hash=sha256:b32c8ccaac7b1a20c0ce00ce317642e6cf231cf038f9875e0280e28af5bf7ac9
pyOpenSSL==19.0.0 \
--hash=sha256:aeca66338f6de19d1aa46ed634c3b9ae519a64b458f8468aec688e7e3c20f200 \
--hash=sha256:c727930ad54b10fc157015014b666f2d8b41f70c0d03e83ab67624fd3dd5d1e6
@ -1241,29 +1248,28 @@ pyRFC3339==1.1 \
--hash=sha256:81b8cbe1519cdb79bed04910dd6fa4e181faf8c88dff1e1b987b5f7ab23a5b1a
pycparser==2.19 \
--hash=sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3
pyparsing==2.4.2 \
--hash=sha256:6f98a7b9397e206d78cc01df10131398f1c8b8510a2f4d97d9abd82e1aacdd80 \
--hash=sha256:d9338df12903bbf5d65a0e4e87c2161968b10d2e489652bb47001d82a9b028b4
pyparsing==2.4.5 \
--hash=sha256:20f995ecd72f2a1f4bf6b072b63b22e2eb457836601e76d6e5dfcd75436acc1f \
--hash=sha256:4ca62001be367f01bd3e92ecbb79070272a9d4964dce6a48a82ff0b8bc7e683a
python-augeas==0.5.0 \
--hash=sha256:67d59d66cdba8d624e0389b87b2a83a176f21f16a87553b50f5703b23f29bac2
pytz==2019.2 \
--hash=sha256:26c0b32e437e54a18161324a2fca3c4b9846b74a8dccddd843113109e1116b32 \
--hash=sha256:c894d57500a4cd2d5c71114aaab77dbab5eabd9022308ce5ac9bb93a60a6f0c7
pytz==2019.3 \
--hash=sha256:1c557d7d0e871de1f5ccd5833f60fb2550652da6be2693c1e02300743d21500d \
--hash=sha256:b02c06db6cf09c12dd25137e563b31700d3b80fcc4ad23abb7a315f2789819be
requests==2.21.0 \
--hash=sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e \
--hash=sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b
requests-toolbelt==0.9.1 \
--hash=sha256:380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f \
--hash=sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0
six==1.12.0 \
--hash=sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c \
--hash=sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73
six==1.13.0 \
--hash=sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd \
--hash=sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66
urllib3==1.24.3 \
--hash=sha256:2393a695cd12afedd0dcb26fe5d50d0cf248e5a66f75dbd89a3d4eb333a61af4 \
--hash=sha256:a637e5fae88995b256e3409dc4d52c2e2e0ba32c42a6365fee8bbd2238de3cfb
zope.component==4.5 \
--hash=sha256:6edfd626c3b593b72895a8cfcf79bff41f4619194ce996a85bce31ac02b94e55 \
--hash=sha256:984a06ba3def0b02b1117fa4c45b56e772e8c29c0340820fbf367e440a93a3a4
zope.component==4.6 \
--hash=sha256:ec2afc5bbe611dcace98bb39822c122d44743d635dafc7315b9aef25097db9e6
zope.deferredimport==4.3.1 \
--hash=sha256:57b2345e7b5eef47efcd4f634ff16c93e4265de3dcf325afc7315ade48d909e1 \
--hash=sha256:9a0c211df44aa95f1c4e6d2626f90b400f56989180d3ef96032d708da3d23e0a
@ -1314,18 +1320,46 @@ zope.interface==4.6.0 \
--hash=sha256:d788a3999014ddf416f2dc454efa4a5dbeda657c6aba031cf363741273804c6b \
--hash=sha256:eed88ae03e1ef3a75a0e96a55a99d7937ed03e53d0cffc2451c208db445a2966 \
--hash=sha256:f99451f3a579e73b5dd58b1b08d1179791d49084371d9a47baad3b22417f0317
zope.proxy==4.3.2 \
--hash=sha256:320a7619992e42142549ebf61e14ce27683b4d14b0cbc45f7c037ba64edb560c \
--hash=sha256:824d4dbabbb7deb84f25fdb96ea1eeca436a1802c3c8d323b3eb4ac9d527d41c \
--hash=sha256:8a32eb9c94908f3544da2dae3f4a9e6961d78819b88ac6b6f4a51cee2d65f4a0 \
--hash=sha256:96265fd3bc3ea646f98482e16307a69de21402eeaaaaf4b841c1161ac2f71bb0 \
--hash=sha256:ab6d6975d9c51c13cac828ff03168de21fb562b0664c59bcdc4a4b10f39a5b17 \
--hash=sha256:af10cb772391772463f65a58348e2de5ecc06693c16d2078be276dc068bcbb54 \
--hash=sha256:b8fd3a3de3f7b6452775e92af22af5977b17b69ac86a38a3ddfe870e40a0d05f \
--hash=sha256:bb7088f1bed3b8214284a5e425dc23da56f2f28e8815b7580bfed9e245b6c0b6 \
--hash=sha256:bc29b3665eac34f14c4aef5224bef045efcfb1a7d12d78c8685858de5fbf21c0 \
--hash=sha256:c39fa6a159affeae5fe31b49d9f5b12bd674fe77271a9a324408b271440c50a7 \
--hash=sha256:e946a036ac5b9f897e986ac9dc950a34cffc857d88eae6727b8434fbc4752366
zope.proxy==4.3.3 \
--hash=sha256:04646ac04ffa9c8e32fb2b5c3cd42995b2548ea14251f3c21ca704afae88e42c \
--hash=sha256:07b6bceea232559d24358832f1cd2ed344bbf05ca83855a5b9698b5f23c5ed60 \
--hash=sha256:1ef452cc02e0e2f8e3c917b1a5b936ef3280f2c2ca854ee70ac2164d1655f7e6 \
--hash=sha256:22bf61857c5977f34d4e391476d40f9a3b8c6ab24fb0cac448d42d8f8b9bf7b2 \
--hash=sha256:299870e3428cbff1cd9f9b34144e76ecdc1d9e3192a8cf5f1b0258f47a239f58 \
--hash=sha256:2bfc36bfccbe047671170ea5677efd3d5ab730a55d7e45611d76d495e5b96766 \
--hash=sha256:32e82d5a640febc688c0789e15ea875bf696a10cf358f049e1ed841f01710a9b \
--hash=sha256:3b2051bdc4bc3f02fa52483f6381cf40d4d48167645241993f9d7ebbd142ed9b \
--hash=sha256:3f734bd8a08f5185a64fb6abb8f14dc97ec27a689ca808fb7a83cdd38d745e4f \
--hash=sha256:3f78dd8de3112df8bbd970f0916ac876dc3fbe63810bd1cf7cc5eec4cbac4f04 \
--hash=sha256:4eabeb48508953ba1f3590ad0773b8daea9e104eec66d661917e9bbcd7125a67 \
--hash=sha256:4f05ecc33808187f430f249cb1ccab35c38f570b181f2d380fbe253da94b18d8 \
--hash=sha256:4f4f4cbf23d3afc1526294a31e7b3eaa0f682cc28ac5366065dc1d6bb18bd7be \
--hash=sha256:5483d5e70aacd06f0aa3effec9fed597c0b50f45060956eeeb1203c44d4338c3 \
--hash=sha256:56a5f9b46892b115a75d0a1f2292431ad5988461175826600acc69a24cb3edee \
--hash=sha256:64bb63af8a06f736927d260efdd4dfc5253d42244f281a8063e4b9eea2ddcbc5 \
--hash=sha256:653f8cbefcf7c6ac4cece2cdef367c4faa2b7c19795d52bd7cbec11a8739a7c1 \
--hash=sha256:664211d63306e4bd4eec35bf2b4bd9db61c394037911cf2d1804c43b511a49f1 \
--hash=sha256:6651e6caed66a8fff0fef1a3e81c0ed2253bf361c0fdc834500488732c5d16e9 \
--hash=sha256:6c1fba6cdfdf105739d3069cf7b07664f2944d82a8098218ab2300a82d8f40fc \
--hash=sha256:6e64246e6e9044a4534a69dca1283c6ddab6e757be5e6874f69024329b3aa61f \
--hash=sha256:838390245c7ec137af4993c0c8052f49d5ec79e422b4451bfa37fee9b9ccaa01 \
--hash=sha256:856b410a14793069d8ba35f33fff667213ea66f2df25a0024cc72a7493c56d4c \
--hash=sha256:8b932c364c1d1605a91907a41128ed0ee8a2d326fc0fafb2c55cd46f545f4599 \
--hash=sha256:9086cf6d20f08dae7f296a78f6c77d1f8d24079d448f023ee0eb329078dd35e1 \
--hash=sha256:9698533c14afa0548188de4968a7932d1f3f965f3f5ba1474de673596bb875af \
--hash=sha256:9b12b05dd7c28f5068387c1afee8cb94f9d02501e7ef495a7c5c7e27139b96ad \
--hash=sha256:a884c7426a5bc6fb7fc71a55ad14e66818e13f05b78b20a6f37175f324b7acb8 \
--hash=sha256:abe9e7f1a3e76286c5f5baf2bf5162d41dc0310da493b34a2c36555f38d928f7 \
--hash=sha256:bd6fde63b015a27262be06bd6bbdd895273cc2bdf2d4c7e1c83711d26a8fbace \
--hash=sha256:bda7c62c954f47b87ed9a89f525eee1b318ec7c2162dfdba76c2ccfa334e0caa \
--hash=sha256:be8a4908dd3f6e965993c0068b006bdbd0474fbcbd1da4893b49356e73fc1557 \
--hash=sha256:ced65fc3c7d7205267506d854bb1815bb445899cca9d21d1d4b949070a635546 \
--hash=sha256:dac4279aa05055d3897ab5e5ee5a7b39db121f91df65a530f8b1ac7f9bd93119 \
--hash=sha256:e4f1863056e3e4f399c285b67fa816f411a7bfa1c81ef50e186126164e396e59 \
--hash=sha256:ecd85f68b8cd9ab78a0141e87ea9a53b2f31fd9b1350a1c44da1f7481b5363ef \
--hash=sha256:ed269b83750413e8fc5c96276372f49ee3fcb7ed61c49fe8e5a67f54459a5a4a \
--hash=sha256:f19b0b80cba73b204dee68501870b11067711d21d243fb6774256d3ca2e5391f \
--hash=sha256:ffdafb98db7574f9da84c489a10a5d582079a888cb43c64e9e6b0e3fe1034685
# Contains the requirements for the letsencrypt package.
#

View file

@ -11,63 +11,70 @@
# ```
ConfigArgParse==0.14.0 \
--hash=sha256:2e2efe2be3f90577aca9415e32cb629aa2ecd92078adbe27b53a03e53ff12e91
asn1crypto==0.24.0 \
--hash=sha256:2f1adbb7546ed199e3c90ef23ec95c5cf3585bac7d11fb7eb562a3fe89c64e87 \
--hash=sha256:9d5c20441baf0cb60a4ac34cc447c6c189024b6b4c6cd7877034f4965c464e49
certifi==2019.6.16 \
--hash=sha256:046832c04d4e752f37383b628bc601a7ea7211496b4638f6514d0e5b9acc4939 \
--hash=sha256:945e3ba63a0b9f577b1395204e13c3a231f9bc0223888be653286534e5873695
cffi==1.12.3 \
--hash=sha256:041c81822e9f84b1d9c401182e174996f0bae9991f33725d059b771744290774 \
--hash=sha256:046ef9a22f5d3eed06334d01b1e836977eeef500d9b78e9ef693f9380ad0b83d \
--hash=sha256:066bc4c7895c91812eff46f4b1c285220947d4aa46fa0a2651ff85f2afae9c90 \
--hash=sha256:066c7ff148ae33040c01058662d6752fd73fbc8e64787229ea8498c7d7f4041b \
--hash=sha256:2444d0c61f03dcd26dbf7600cf64354376ee579acad77aef459e34efcb438c63 \
--hash=sha256:300832850b8f7967e278870c5d51e3819b9aad8f0a2c8dbe39ab11f119237f45 \
--hash=sha256:34c77afe85b6b9e967bd8154e3855e847b70ca42043db6ad17f26899a3df1b25 \
--hash=sha256:46de5fa00f7ac09f020729148ff632819649b3e05a007d286242c4882f7b1dc3 \
--hash=sha256:4aa8ee7ba27c472d429b980c51e714a24f47ca296d53f4d7868075b175866f4b \
--hash=sha256:4d0004eb4351e35ed950c14c11e734182591465a33e960a4ab5e8d4f04d72647 \
--hash=sha256:4e3d3f31a1e202b0f5a35ba3bc4eb41e2fc2b11c1eff38b362de710bcffb5016 \
--hash=sha256:50bec6d35e6b1aaeb17f7c4e2b9374ebf95a8975d57863546fa83e8d31bdb8c4 \
--hash=sha256:55cad9a6df1e2a1d62063f79d0881a414a906a6962bc160ac968cc03ed3efcfb \
--hash=sha256:5662ad4e4e84f1eaa8efce5da695c5d2e229c563f9d5ce5b0113f71321bcf753 \
--hash=sha256:59b4dc008f98fc6ee2bb4fd7fc786a8d70000d058c2bbe2698275bc53a8d3fa7 \
--hash=sha256:73e1ffefe05e4ccd7bcea61af76f36077b914f92b76f95ccf00b0c1b9186f3f9 \
--hash=sha256:a1f0fd46eba2d71ce1589f7e50a9e2ffaeb739fb2c11e8192aa2b45d5f6cc41f \
--hash=sha256:a2e85dc204556657661051ff4bab75a84e968669765c8a2cd425918699c3d0e8 \
--hash=sha256:a5457d47dfff24882a21492e5815f891c0ca35fefae8aa742c6c263dac16ef1f \
--hash=sha256:a8dccd61d52a8dae4a825cdbb7735da530179fea472903eb871a5513b5abbfdc \
--hash=sha256:ae61af521ed676cf16ae94f30fe202781a38d7178b6b4ab622e4eec8cefaff42 \
--hash=sha256:b012a5edb48288f77a63dba0840c92d0504aa215612da4541b7b42d849bc83a3 \
--hash=sha256:d2c5cfa536227f57f97c92ac30c8109688ace8fa4ac086d19d0af47d134e2909 \
--hash=sha256:d42b5796e20aacc9d15e66befb7a345454eef794fdb0737d1af593447c6c8f45 \
--hash=sha256:dee54f5d30d775f525894d67b1495625dd9322945e7fee00731952e0368ff42d \
--hash=sha256:e070535507bd6aa07124258171be2ee8dfc19119c28ca94c9dfb7efd23564512 \
--hash=sha256:e1ff2748c84d97b065cc95429814cdba39bcbd77c9c85c89344b317dc0d9cbff \
--hash=sha256:ed851c75d1e0e043cbf5ca9a8e1b13c4c90f3fbd863dacb01c0808e2b5204201
certifi==2019.9.11 \
--hash=sha256:e4f3620cfea4f83eedc95b24abd9cd56f3c4b146dd0177e83a21b4eb49e21e50 \
--hash=sha256:fd7c7c74727ddcf00e9acd26bba8da604ffec95bf1c2144e67aff7a8b50e6cef
cffi==1.13.2 \
--hash=sha256:0b49274afc941c626b605fb59b59c3485c17dc776dc3cc7cc14aca74cc19cc42 \
--hash=sha256:0e3ea92942cb1168e38c05c1d56b0527ce31f1a370f6117f1d490b8dcd6b3a04 \
--hash=sha256:135f69aecbf4517d5b3d6429207b2dff49c876be724ac0c8bf8e1ea99df3d7e5 \
--hash=sha256:19db0cdd6e516f13329cba4903368bff9bb5a9331d3410b1b448daaadc495e54 \
--hash=sha256:2781e9ad0e9d47173c0093321bb5435a9dfae0ed6a762aabafa13108f5f7b2ba \
--hash=sha256:291f7c42e21d72144bb1c1b2e825ec60f46d0a7468f5346841860454c7aa8f57 \
--hash=sha256:2c5e309ec482556397cb21ede0350c5e82f0eb2621de04b2633588d118da4396 \
--hash=sha256:2e9c80a8c3344a92cb04661115898a9129c074f7ab82011ef4b612f645939f12 \
--hash=sha256:32a262e2b90ffcfdd97c7a5e24a6012a43c61f1f5a57789ad80af1d26c6acd97 \
--hash=sha256:3c9fff570f13480b201e9ab69453108f6d98244a7f495e91b6c654a47486ba43 \
--hash=sha256:415bdc7ca8c1c634a6d7163d43fb0ea885a07e9618a64bda407e04b04333b7db \
--hash=sha256:42194f54c11abc8583417a7cf4eaff544ce0de8187abaf5d29029c91b1725ad3 \
--hash=sha256:4424e42199e86b21fc4db83bd76909a6fc2a2aefb352cb5414833c030f6ed71b \
--hash=sha256:4a43c91840bda5f55249413037b7a9b79c90b1184ed504883b72c4df70778579 \
--hash=sha256:599a1e8ff057ac530c9ad1778293c665cb81a791421f46922d80a86473c13346 \
--hash=sha256:5c4fae4e9cdd18c82ba3a134be256e98dc0596af1e7285a3d2602c97dcfa5159 \
--hash=sha256:5ecfa867dea6fabe2a58f03ac9186ea64da1386af2159196da51c4904e11d652 \
--hash=sha256:62f2578358d3a92e4ab2d830cd1c2049c9c0d0e6d3c58322993cc341bdeac22e \
--hash=sha256:6471a82d5abea994e38d2c2abc77164b4f7fbaaf80261cb98394d5793f11b12a \
--hash=sha256:6d4f18483d040e18546108eb13b1dfa1000a089bcf8529e30346116ea6240506 \
--hash=sha256:71a608532ab3bd26223c8d841dde43f3516aa5d2bf37b50ac410bb5e99053e8f \
--hash=sha256:74a1d8c85fb6ff0b30fbfa8ad0ac23cd601a138f7509dc617ebc65ef305bb98d \
--hash=sha256:7b93a885bb13073afb0aa73ad82059a4c41f4b7d8eb8368980448b52d4c7dc2c \
--hash=sha256:7d4751da932caaec419d514eaa4215eaf14b612cff66398dd51129ac22680b20 \
--hash=sha256:7f627141a26b551bdebbc4855c1157feeef18241b4b8366ed22a5c7d672ef858 \
--hash=sha256:8169cf44dd8f9071b2b9248c35fc35e8677451c52f795daa2bb4643f32a540bc \
--hash=sha256:aa00d66c0fab27373ae44ae26a66a9e43ff2a678bf63a9c7c1a9a4d61172827a \
--hash=sha256:ccb032fda0873254380aa2bfad2582aedc2959186cce61e3a17abc1a55ff89c3 \
--hash=sha256:d754f39e0d1603b5b24a7f8484b22d2904fa551fe865fd0d4c3332f078d20d4e \
--hash=sha256:d75c461e20e29afc0aee7172a0950157c704ff0dd51613506bd7d82b718e7410 \
--hash=sha256:dcd65317dd15bc0451f3e01c80da2216a31916bdcffd6221ca1202d96584aa25 \
--hash=sha256:e570d3ab32e2c2861c4ebe6ffcad6a8abf9347432a37608fe1fbd157b3f0036b \
--hash=sha256:fd43a88e045cf992ed09fa724b5315b790525f2676883a6ea64e3263bae6549d
chardet==3.0.4 \
--hash=sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae \
--hash=sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691
configobj==5.0.6 \
--hash=sha256:a2f5650770e1c87fb335af19a9b7eb73fc05ccf22144eb68db7d00cd2bcb0902
cryptography==2.7 \
--hash=sha256:24b61e5fcb506424d3ec4e18bca995833839bf13c59fc43e530e488f28d46b8c \
--hash=sha256:25dd1581a183e9e7a806fe0543f485103232f940fcfc301db65e630512cce643 \
--hash=sha256:3452bba7c21c69f2df772762be0066c7ed5dc65df494a1d53a58b683a83e1216 \
--hash=sha256:41a0be220dd1ed9e998f5891948306eb8c812b512dc398e5a01846d855050799 \
--hash=sha256:5751d8a11b956fbfa314f6553d186b94aa70fdb03d8a4d4f1c82dcacf0cbe28a \
--hash=sha256:5f61c7d749048fa6e3322258b4263463bfccefecb0dd731b6561cb617a1d9bb9 \
--hash=sha256:72e24c521fa2106f19623a3851e9f89ddfdeb9ac63871c7643790f872a305dfc \
--hash=sha256:7b97ae6ef5cba2e3bb14256625423413d5ce8d1abb91d4f29b6d1a081da765f8 \
--hash=sha256:961e886d8a3590fd2c723cf07be14e2a91cf53c25f02435c04d39e90780e3b53 \
--hash=sha256:96d8473848e984184b6728e2c9d391482008646276c3ff084a1bd89e15ff53a1 \
--hash=sha256:ae536da50c7ad1e002c3eee101871d93abdc90d9c5f651818450a0d3af718609 \
--hash=sha256:b0db0cecf396033abb4a93c95d1602f268b3a68bb0a9cc06a7cff587bb9a7292 \
--hash=sha256:cfee9164954c186b191b91d4193989ca994703b2fff406f71cf454a2d3c7327e \
--hash=sha256:e6347742ac8f35ded4a46ff835c60e68c22a536a8ae5c4422966d06946b6d4c6 \
--hash=sha256:f27d93f0139a3c056172ebb5d4f9056e770fdf0206c2f422ff2ebbad142e09ed \
--hash=sha256:f57b76e46a58b63d1c6375017f4564a28f19a5ca912691fd2e4261b3414b618d
cryptography==2.8 \
--hash=sha256:02079a6addc7b5140ba0825f542c0869ff4df9a69c360e339ecead5baefa843c \
--hash=sha256:1df22371fbf2004c6f64e927668734070a8953362cd8370ddd336774d6743595 \
--hash=sha256:369d2346db5934345787451504853ad9d342d7f721ae82d098083e1f49a582ad \
--hash=sha256:3cda1f0ed8747339bbdf71b9f38ca74c7b592f24f65cdb3ab3765e4b02871651 \
--hash=sha256:44ff04138935882fef7c686878e1c8fd80a723161ad6a98da31e14b7553170c2 \
--hash=sha256:4b1030728872c59687badcca1e225a9103440e467c17d6d1730ab3d2d64bfeff \
--hash=sha256:58363dbd966afb4f89b3b11dfb8ff200058fbc3b947507675c19ceb46104b48d \
--hash=sha256:6ec280fb24d27e3d97aa731e16207d58bd8ae94ef6eab97249a2afe4ba643d42 \
--hash=sha256:7270a6c29199adc1297776937a05b59720e8a782531f1f122f2eb8467f9aab4d \
--hash=sha256:73fd30c57fa2d0a1d7a49c561c40c2f79c7d6c374cc7750e9ac7c99176f6428e \
--hash=sha256:7f09806ed4fbea8f51585231ba742b58cbcfbfe823ea197d8c89a5e433c7e912 \
--hash=sha256:90df0cc93e1f8d2fba8365fb59a858f51a11a394d64dbf3ef844f783844cc793 \
--hash=sha256:971221ed40f058f5662a604bd1ae6e4521d84e6cad0b7b170564cc34169c8f13 \
--hash=sha256:a518c153a2b5ed6b8cc03f7ae79d5ffad7315ad4569b2d5333a13c38d64bd8d7 \
--hash=sha256:b0de590a8b0979649ebeef8bb9f54394d3a41f66c5584fff4220901739b6b2f0 \
--hash=sha256:b43f53f29816ba1db8525f006fa6f49292e9b029554b3eb56a189a70f2a40879 \
--hash=sha256:d31402aad60ed889c7e57934a03477b572a03af7794fa8fb1780f21ea8f6551f \
--hash=sha256:de96157ec73458a7f14e3d26f17f8128c959084931e8997b9e655a39c8fde9f9 \
--hash=sha256:df6b4dca2e11865e6cfbfb708e800efb18370f5a46fd601d3755bc7f85b3a8a2 \
--hash=sha256:ecadccc7ba52193963c0475ac9f6fa28ac01e01349a2ca48509667ef41ffd2cf \
--hash=sha256:fb81c17e0ebe3358486cd8cc3ad78adbae58af12fc2bf2bc0bb84e8090fa5ce8
distro==1.4.0 \
--hash=sha256:362dde65d846d23baee4b5c058c8586f219b5a54be1cf5fc6ff55c4578392f57 \
--hash=sha256:eedf82a470ebe7d010f1872c17237c79ab04097948800029994fa458e52fb4b4
@ -79,14 +86,14 @@ enum34==1.1.6 \
funcsigs==1.0.2 \
--hash=sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca \
--hash=sha256:a7bb0f2cf3a3fd1ab2732cb49eba4252c2af4240442415b4abce3b87022a8f50
future==0.17.1 \
--hash=sha256:67045236dcfd6816dc439556d009594abf643e5eb48992e36beac09c2ca659b8
future==0.18.2 \
--hash=sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d
idna==2.8 \
--hash=sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407 \
--hash=sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c
ipaddress==1.0.22 \
--hash=sha256:64b28eec5e78e7510698f6d4da08800a5c575caa4a286c93d651c5d3ff7b6794 \
--hash=sha256:b146c751ea45cad6188dd6cf2d9b757f6f4f8d6ffb96a023e6f2e26eea02a72c
ipaddress==1.0.23 \
--hash=sha256:6e0f4a39e66cb5bb9a137b00276a2eff74f93b71dcbdad6f10ff7df9d3557fcc \
--hash=sha256:b7f8e0369580bb4a24d5ba1d7cc29660a4a6987763faf1d8a8046830e020e7e2
josepy==1.2.0 \
--hash=sha256:8ea15573203f28653c00f4ac0142520777b1c59d9eddd8da3f256c6ba3cac916 \
--hash=sha256:9cec9a839fe9520f0420e4f38e7219525daccce4813296627436fe444cd002d3
@ -96,9 +103,9 @@ mock==1.3.0 \
parsedatetime==2.4 \
--hash=sha256:3d817c58fb9570d1eec1dd46fa9448cd644eeed4fb612684b02dfda3a79cb84b \
--hash=sha256:9ee3529454bf35c40a77115f5a596771e59e1aee8c53306f346c461b8e913094
pbr==5.4.2 \
--hash=sha256:56e52299170b9492513c64be44736d27a512fa7e606f21942160b68ce510b4bc \
--hash=sha256:9b321c204a88d8ab5082699469f52cc94c5da45c51f114113d01b3d993c24cdf
pbr==5.4.3 \
--hash=sha256:2c8e420cd4ed4cec4e7999ee47409e876af575d4c35a45840d59e8b5f3155ab8 \
--hash=sha256:b32c8ccaac7b1a20c0ce00ce317642e6cf231cf038f9875e0280e28af5bf7ac9
pyOpenSSL==19.0.0 \
--hash=sha256:aeca66338f6de19d1aa46ed634c3b9ae519a64b458f8468aec688e7e3c20f200 \
--hash=sha256:c727930ad54b10fc157015014b666f2d8b41f70c0d03e83ab67624fd3dd5d1e6
@ -107,29 +114,28 @@ pyRFC3339==1.1 \
--hash=sha256:81b8cbe1519cdb79bed04910dd6fa4e181faf8c88dff1e1b987b5f7ab23a5b1a
pycparser==2.19 \
--hash=sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3
pyparsing==2.4.2 \
--hash=sha256:6f98a7b9397e206d78cc01df10131398f1c8b8510a2f4d97d9abd82e1aacdd80 \
--hash=sha256:d9338df12903bbf5d65a0e4e87c2161968b10d2e489652bb47001d82a9b028b4
pyparsing==2.4.5 \
--hash=sha256:20f995ecd72f2a1f4bf6b072b63b22e2eb457836601e76d6e5dfcd75436acc1f \
--hash=sha256:4ca62001be367f01bd3e92ecbb79070272a9d4964dce6a48a82ff0b8bc7e683a
python-augeas==0.5.0 \
--hash=sha256:67d59d66cdba8d624e0389b87b2a83a176f21f16a87553b50f5703b23f29bac2
pytz==2019.2 \
--hash=sha256:26c0b32e437e54a18161324a2fca3c4b9846b74a8dccddd843113109e1116b32 \
--hash=sha256:c894d57500a4cd2d5c71114aaab77dbab5eabd9022308ce5ac9bb93a60a6f0c7
pytz==2019.3 \
--hash=sha256:1c557d7d0e871de1f5ccd5833f60fb2550652da6be2693c1e02300743d21500d \
--hash=sha256:b02c06db6cf09c12dd25137e563b31700d3b80fcc4ad23abb7a315f2789819be
requests==2.21.0 \
--hash=sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e \
--hash=sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b
requests-toolbelt==0.9.1 \
--hash=sha256:380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f \
--hash=sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0
six==1.12.0 \
--hash=sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c \
--hash=sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73
six==1.13.0 \
--hash=sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd \
--hash=sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66
urllib3==1.24.3 \
--hash=sha256:2393a695cd12afedd0dcb26fe5d50d0cf248e5a66f75dbd89a3d4eb333a61af4 \
--hash=sha256:a637e5fae88995b256e3409dc4d52c2e2e0ba32c42a6365fee8bbd2238de3cfb
zope.component==4.5 \
--hash=sha256:6edfd626c3b593b72895a8cfcf79bff41f4619194ce996a85bce31ac02b94e55 \
--hash=sha256:984a06ba3def0b02b1117fa4c45b56e772e8c29c0340820fbf367e440a93a3a4
zope.component==4.6 \
--hash=sha256:ec2afc5bbe611dcace98bb39822c122d44743d635dafc7315b9aef25097db9e6
zope.deferredimport==4.3.1 \
--hash=sha256:57b2345e7b5eef47efcd4f634ff16c93e4265de3dcf325afc7315ade48d909e1 \
--hash=sha256:9a0c211df44aa95f1c4e6d2626f90b400f56989180d3ef96032d708da3d23e0a
@ -180,15 +186,43 @@ zope.interface==4.6.0 \
--hash=sha256:d788a3999014ddf416f2dc454efa4a5dbeda657c6aba031cf363741273804c6b \
--hash=sha256:eed88ae03e1ef3a75a0e96a55a99d7937ed03e53d0cffc2451c208db445a2966 \
--hash=sha256:f99451f3a579e73b5dd58b1b08d1179791d49084371d9a47baad3b22417f0317
zope.proxy==4.3.2 \
--hash=sha256:320a7619992e42142549ebf61e14ce27683b4d14b0cbc45f7c037ba64edb560c \
--hash=sha256:824d4dbabbb7deb84f25fdb96ea1eeca436a1802c3c8d323b3eb4ac9d527d41c \
--hash=sha256:8a32eb9c94908f3544da2dae3f4a9e6961d78819b88ac6b6f4a51cee2d65f4a0 \
--hash=sha256:96265fd3bc3ea646f98482e16307a69de21402eeaaaaf4b841c1161ac2f71bb0 \
--hash=sha256:ab6d6975d9c51c13cac828ff03168de21fb562b0664c59bcdc4a4b10f39a5b17 \
--hash=sha256:af10cb772391772463f65a58348e2de5ecc06693c16d2078be276dc068bcbb54 \
--hash=sha256:b8fd3a3de3f7b6452775e92af22af5977b17b69ac86a38a3ddfe870e40a0d05f \
--hash=sha256:bb7088f1bed3b8214284a5e425dc23da56f2f28e8815b7580bfed9e245b6c0b6 \
--hash=sha256:bc29b3665eac34f14c4aef5224bef045efcfb1a7d12d78c8685858de5fbf21c0 \
--hash=sha256:c39fa6a159affeae5fe31b49d9f5b12bd674fe77271a9a324408b271440c50a7 \
--hash=sha256:e946a036ac5b9f897e986ac9dc950a34cffc857d88eae6727b8434fbc4752366
zope.proxy==4.3.3 \
--hash=sha256:04646ac04ffa9c8e32fb2b5c3cd42995b2548ea14251f3c21ca704afae88e42c \
--hash=sha256:07b6bceea232559d24358832f1cd2ed344bbf05ca83855a5b9698b5f23c5ed60 \
--hash=sha256:1ef452cc02e0e2f8e3c917b1a5b936ef3280f2c2ca854ee70ac2164d1655f7e6 \
--hash=sha256:22bf61857c5977f34d4e391476d40f9a3b8c6ab24fb0cac448d42d8f8b9bf7b2 \
--hash=sha256:299870e3428cbff1cd9f9b34144e76ecdc1d9e3192a8cf5f1b0258f47a239f58 \
--hash=sha256:2bfc36bfccbe047671170ea5677efd3d5ab730a55d7e45611d76d495e5b96766 \
--hash=sha256:32e82d5a640febc688c0789e15ea875bf696a10cf358f049e1ed841f01710a9b \
--hash=sha256:3b2051bdc4bc3f02fa52483f6381cf40d4d48167645241993f9d7ebbd142ed9b \
--hash=sha256:3f734bd8a08f5185a64fb6abb8f14dc97ec27a689ca808fb7a83cdd38d745e4f \
--hash=sha256:3f78dd8de3112df8bbd970f0916ac876dc3fbe63810bd1cf7cc5eec4cbac4f04 \
--hash=sha256:4eabeb48508953ba1f3590ad0773b8daea9e104eec66d661917e9bbcd7125a67 \
--hash=sha256:4f05ecc33808187f430f249cb1ccab35c38f570b181f2d380fbe253da94b18d8 \
--hash=sha256:4f4f4cbf23d3afc1526294a31e7b3eaa0f682cc28ac5366065dc1d6bb18bd7be \
--hash=sha256:5483d5e70aacd06f0aa3effec9fed597c0b50f45060956eeeb1203c44d4338c3 \
--hash=sha256:56a5f9b46892b115a75d0a1f2292431ad5988461175826600acc69a24cb3edee \
--hash=sha256:64bb63af8a06f736927d260efdd4dfc5253d42244f281a8063e4b9eea2ddcbc5 \
--hash=sha256:653f8cbefcf7c6ac4cece2cdef367c4faa2b7c19795d52bd7cbec11a8739a7c1 \
--hash=sha256:664211d63306e4bd4eec35bf2b4bd9db61c394037911cf2d1804c43b511a49f1 \
--hash=sha256:6651e6caed66a8fff0fef1a3e81c0ed2253bf361c0fdc834500488732c5d16e9 \
--hash=sha256:6c1fba6cdfdf105739d3069cf7b07664f2944d82a8098218ab2300a82d8f40fc \
--hash=sha256:6e64246e6e9044a4534a69dca1283c6ddab6e757be5e6874f69024329b3aa61f \
--hash=sha256:838390245c7ec137af4993c0c8052f49d5ec79e422b4451bfa37fee9b9ccaa01 \
--hash=sha256:856b410a14793069d8ba35f33fff667213ea66f2df25a0024cc72a7493c56d4c \
--hash=sha256:8b932c364c1d1605a91907a41128ed0ee8a2d326fc0fafb2c55cd46f545f4599 \
--hash=sha256:9086cf6d20f08dae7f296a78f6c77d1f8d24079d448f023ee0eb329078dd35e1 \
--hash=sha256:9698533c14afa0548188de4968a7932d1f3f965f3f5ba1474de673596bb875af \
--hash=sha256:9b12b05dd7c28f5068387c1afee8cb94f9d02501e7ef495a7c5c7e27139b96ad \
--hash=sha256:a884c7426a5bc6fb7fc71a55ad14e66818e13f05b78b20a6f37175f324b7acb8 \
--hash=sha256:abe9e7f1a3e76286c5f5baf2bf5162d41dc0310da493b34a2c36555f38d928f7 \
--hash=sha256:bd6fde63b015a27262be06bd6bbdd895273cc2bdf2d4c7e1c83711d26a8fbace \
--hash=sha256:bda7c62c954f47b87ed9a89f525eee1b318ec7c2162dfdba76c2ccfa334e0caa \
--hash=sha256:be8a4908dd3f6e965993c0068b006bdbd0474fbcbd1da4893b49356e73fc1557 \
--hash=sha256:ced65fc3c7d7205267506d854bb1815bb445899cca9d21d1d4b949070a635546 \
--hash=sha256:dac4279aa05055d3897ab5e5ee5a7b39db121f91df65a530f8b1ac7f9bd93119 \
--hash=sha256:e4f1863056e3e4f399c285b67fa816f411a7bfa1c81ef50e186126164e396e59 \
--hash=sha256:ecd85f68b8cd9ab78a0141e87ea9a53b2f31fd9b1350a1c44da1f7481b5363ef \
--hash=sha256:ed269b83750413e8fc5c96276372f49ee3fcb7ed61c49fe8e5a67f54459a5a4a \
--hash=sha256:f19b0b80cba73b204dee68501870b11067711d21d243fb6774256d3ca2e5391f \
--hash=sha256:ffdafb98db7574f9da84c489a10a5d582079a888cb43c64e9e6b0e3fe1034685

Some files were not shown because too many files have changed in this diff Show more