Merge pull request #9401 from alexzorin/update-2.0.x

Merge master into 2.0.x
This commit is contained in:
alexzorin 2022-09-09 09:59:52 +10:00 committed by GitHub
commit f4db687130
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
52 changed files with 326 additions and 257 deletions

View file

@ -2,7 +2,7 @@ jobs:
- job: extended_test
variables:
- name: IMAGE_NAME
value: ubuntu-18.04
value: ubuntu-22.04
- name: PYTHON_VERSION
value: 3.10
- group: certbot-common
@ -47,13 +47,13 @@ jobs:
nginx-compat:
TOXENV: nginx_compat
linux-integration-rfc2136:
IMAGE_NAME: ubuntu-18.04
IMAGE_NAME: ubuntu-22.04
PYTHON_VERSION: 3.8
TOXENV: integration-dns-rfc2136
docker-dev:
TOXENV: docker_dev
le-modification:
IMAGE_NAME: ubuntu-18.04
IMAGE_NAME: ubuntu-22.04
TOXENV: modification
farmtest-apache2:
PYTHON_VERSION: 3.8

View file

@ -1,7 +1,7 @@
jobs:
- job: docker_build
pool:
vmImage: ubuntu-18.04
vmImage: ubuntu-22.04
strategy:
matrix:
amd64:
@ -37,7 +37,7 @@ jobs:
- job: docker_run
dependsOn: docker_build
pool:
vmImage: ubuntu-18.04
vmImage: ubuntu-22.04
steps:
- task: DownloadPipelineArtifact@2
inputs:
@ -116,7 +116,7 @@ jobs:
displayName: Run certbot integration tests
- job: snaps_build
pool:
vmImage: ubuntu-18.04
vmImage: ubuntu-22.04
strategy:
matrix:
amd64:
@ -164,7 +164,7 @@ jobs:
- job: snap_run
dependsOn: snaps_build
pool:
vmImage: ubuntu-18.04
vmImage: ubuntu-22.04
steps:
- task: UsePythonVersion@0
inputs:
@ -194,7 +194,7 @@ jobs:
- job: snap_dns_run
dependsOn: snaps_build
pool:
vmImage: ubuntu-18.04
vmImage: ubuntu-22.04
steps:
- script: |
set -e

View file

@ -5,11 +5,11 @@ jobs:
strategy:
matrix:
macos-py37-cover:
IMAGE_NAME: macOS-10.15
IMAGE_NAME: macOS-12
PYTHON_VERSION: 3.7
TOXENV: py37-cover
macos-py310-cover:
IMAGE_NAME: macOS-10.15
IMAGE_NAME: macOS-12
PYTHON_VERSION: 3.10
TOXENV: py310-cover
windows-py37:
@ -25,42 +25,42 @@ jobs:
PYTHON_VERSION: 3.9
TOXENV: integration-certbot
linux-oldest-tests-1:
IMAGE_NAME: ubuntu-18.04
IMAGE_NAME: ubuntu-22.04
PYTHON_VERSION: 3.7
TOXENV: '{acme,apache,apache-v2,certbot}-oldest'
linux-oldest-tests-2:
IMAGE_NAME: ubuntu-18.04
IMAGE_NAME: ubuntu-22.04
PYTHON_VERSION: 3.7
TOXENV: '{dns,nginx}-oldest'
linux-py37:
IMAGE_NAME: ubuntu-18.04
IMAGE_NAME: ubuntu-22.04
PYTHON_VERSION: 3.7
TOXENV: py37
linux-py310-cover:
IMAGE_NAME: ubuntu-18.04
IMAGE_NAME: ubuntu-22.04
PYTHON_VERSION: 3.10
TOXENV: py310-cover
linux-py310-lint:
IMAGE_NAME: ubuntu-18.04
IMAGE_NAME: ubuntu-22.04
PYTHON_VERSION: 3.10
TOXENV: lint-posix
linux-py310-mypy:
IMAGE_NAME: ubuntu-18.04
IMAGE_NAME: ubuntu-22.04
PYTHON_VERSION: 3.10
TOXENV: mypy-posix
linux-integration:
IMAGE_NAME: ubuntu-18.04
IMAGE_NAME: ubuntu-22.04
PYTHON_VERSION: 3.8
TOXENV: integration
ACME_SERVER: pebble
apache-compat:
IMAGE_NAME: ubuntu-18.04
IMAGE_NAME: ubuntu-22.04
TOXENV: apache_compat
apacheconftest:
IMAGE_NAME: ubuntu-18.04
IMAGE_NAME: ubuntu-22.04
TOXENV: apacheconftest-with-pebble
nginxroundtrip:
IMAGE_NAME: ubuntu-18.04
IMAGE_NAME: ubuntu-22.04
TOXENV: nginxroundtrip
pool:
vmImage: $(IMAGE_NAME)

View file

@ -35,7 +35,7 @@ stages:
# more info.
- job: publish_snap
pool:
vmImage: ubuntu-18.04
vmImage: ubuntu-22.04
variables:
- group: certbot-common
strategy:
@ -71,7 +71,7 @@ stages:
displayName: Publish to Snap store
- job: publish_docker
pool:
vmImage: ubuntu-18.04
vmImage: ubuntu-22.04
strategy:
matrix:
amd64:
@ -96,11 +96,16 @@ stages:
# which was created by following the instructions at
# https://docs.microsoft.com/en-us/azure/devops/pipelines/library/service-endpoints?view=azure-devops&tabs=yaml#sep-docreg.
# The name given to this service account must match the value
# given to containerRegistry below. "Grant access to all
# pipelines" should also be checked. To revoke these
# credentials, we can change the password on the certbotbot
# Docker Hub account or remove the account from the
# Certbot organization on Docker Hub.
# given to containerRegistry below. The authentication used when
# creating this service account was a personal access token
# rather than a password to bypass 2FA. When Brad set this up,
# Azure Pipelines failed to verify the credentials with an error
# like "access is forbidden with a JWT issued from a personal
# access token", but after saving them without verification, the
# access token worked when the pipeline actually ran. "Grant
# access to all pipelines" should also be checked on the service
# account. The access token can be deleted on Docker Hub if
# these credentials need to be revoked.
containerRegistry: docker-hub
displayName: Login to Docker Hub
- bash: set -e && tools/docker/deploy.sh $(dockerTag) $DOCKER_ARCH

View file

@ -12,7 +12,7 @@ steps:
set -e
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
python-dev \
python3-dev \
gcc \
libaugeas0 \
libssl-dev \
@ -36,8 +36,8 @@ steps:
# problems with its lack of real dependency resolution.
- bash: |
set -e
python tools/pipstrap.py
python tools/pip_install.py -I tox virtualenv
python3 tools/pipstrap.py
python3 tools/pip_install.py -I tox virtualenv
displayName: Install runtime dependencies
- task: DownloadSecureFile@1
name: testFarmPem
@ -49,7 +49,7 @@ steps:
export TARGET_BRANCH="`echo "${BUILD_SOURCEBRANCH}" | sed -E 's!refs/(heads|tags)/!!g'`"
[ -z "${SYSTEM_PULLREQUEST_TARGETBRANCH}" ] || export TARGET_BRANCH="${SYSTEM_PULLREQUEST_TARGETBRANCH}"
env
python -m tox
python3 -m tox
env:
AWS_ACCESS_KEY_ID: $(AWS_ACCESS_KEY_ID)
AWS_SECRET_ACCESS_KEY: $(AWS_SECRET_ACCESS_KEY)

View file

@ -1,5 +1,6 @@
## Pull Request Checklist
- [ ] The Certbot team has recently expressed interest in reviewing a PR for this. If not, this PR may be closed due our limited resources and need to prioritize how we spend them.
- [ ] If the change being made is to a [distributed component](https://certbot.eff.org/docs/contributing.html#code-components-and-layout), edit the `master` section of `certbot/CHANGELOG.md` to include a description of the change being made.
- [ ] Add or update any documentation as needed to support the changes in this PR.
- [ ] Include your name in `AUTHORS.md` if you like.

View file

@ -178,6 +178,7 @@ Authors
* [Mathieu Leduc-Hamel](https://github.com/mlhamel)
* [Matt Bostock](https://github.com/mattbostock)
* [Matthew Ames](https://github.com/SuperMatt)
* [Matthew W. Thomas](https://github.com/mwt)
* [Michael Schumacher](https://github.com/schumaml)
* [Michael Strache](https://github.com/Jarodiv)
* [Michael Sverdlin](https://github.com/sveder)
@ -215,6 +216,7 @@ Authors
* [Pierre Jaury](https://github.com/kaiyou)
* [Piotr Kasprzyk](https://github.com/kwadrat)
* [Prayag Verma](https://github.com/pra85)
* [Preston Locke](https://github.com/Preston12321)
* [Rasesh Patel](https://github.com/raspat1)
* [Reinaldo de Souza Jr](https://github.com/juniorz)
* [Remi Rampin](https://github.com/remram44)

View file

@ -410,7 +410,7 @@ class TLSALPN01Response(KeyAuthorizationChallengeResponse):
"""
ID_PE_ACME_IDENTIFIER_V1 = b"1.3.6.1.5.5.7.1.30.1"
ACME_TLS_1_PROTOCOL = "acme-tls/1"
ACME_TLS_1_PROTOCOL = b"acme-tls/1"
@property
def h(self) -> bytes:

View file

@ -15,13 +15,20 @@ from typing import Set
from typing import Text
from typing import Tuple
from typing import Union
import warnings
import josepy as jose
import OpenSSL
import requests
from requests.adapters import HTTPAdapter
from requests.utils import parse_header_links
from requests_toolbelt.adapters.source import SourceAddressAdapter
# We're capturing the warnings described at
# https://github.com/requests/toolbelt/issues/331 until we can remove this
# dependency in Certbot 2.0.
with warnings.catch_warnings():
warnings.filterwarnings("ignore", "'urllib3.contrib.pyopenssl",
DeprecationWarning)
from requests_toolbelt.adapters.source import SourceAddressAdapter
from acme import challenges
from acme import crypto_util
@ -482,7 +489,8 @@ class ClientNetwork:
:param bool verify_ssl: Whether to verify certificates on SSL connections.
:param str user_agent: String to send as User-Agent header.
:param float timeout: Timeout for requests.
:param source_address: Optional source address to bind to when making requests.
:param source_address: Optional source address to bind to when making
requests. (deprecated since 1.30.0)
:type source_address: str or tuple(str, int)
"""
def __init__(self, key: jose.JWK, account: Optional[messages.RegistrationResource] = None,
@ -500,6 +508,8 @@ class ClientNetwork:
adapter = HTTPAdapter()
if source_address is not None:
warnings.warn("Support for source_address is deprecated and will be "
"removed soon.", DeprecationWarning, stacklevel=2)
adapter = SourceAddressAdapter(source_address)
self.session.mount("http://", adapter)

View file

@ -11,6 +11,7 @@ from typing import Callable
from typing import List
from typing import Mapping
from typing import Optional
from typing import Sequence
from typing import Set
from typing import Tuple
from typing import Union
@ -39,7 +40,9 @@ class _DefaultCertSelection:
def __call__(self, connection: SSL.Connection) -> Optional[Tuple[crypto.PKey, crypto.X509]]:
server_name = connection.get_servername()
return self.certs.get(server_name, None)
if server_name:
return self.certs.get(server_name, None)
return None # pragma: no cover
class SSLSocket: # pylint: disable=too-few-public-methods
@ -60,7 +63,8 @@ class SSLSocket: # pylint: disable=too-few-public-methods
method: int = _DEFAULT_SSL_METHOD,
alpn_selection: Optional[Callable[[SSL.Connection, List[bytes]], bytes]] = None,
cert_selection: Optional[Callable[[SSL.Connection],
Tuple[crypto.PKey, crypto.X509]]] = None
Optional[Tuple[crypto.PKey,
crypto.X509]]]] = None
) -> None:
self.sock = sock
self.alpn_selection = alpn_selection
@ -71,8 +75,8 @@ class SSLSocket: # pylint: disable=too-few-public-methods
raise ValueError("Both cert_selection and certs specified.")
actual_cert_selection: Union[_DefaultCertSelection,
Optional[Callable[[SSL.Connection],
Tuple[crypto.PKey,
crypto.X509]]]] = cert_selection
Optional[Tuple[crypto.PKey,
crypto.X509]]]]] = cert_selection
if actual_cert_selection is None:
actual_cert_selection = _DefaultCertSelection(certs if certs else {})
self.cert_selection = actual_cert_selection
@ -157,7 +161,7 @@ class SSLSocket: # pylint: disable=too-few-public-methods
def probe_sni(name: bytes, host: bytes, port: int = 443, timeout: int = 300, # pylint: disable=too-many-arguments
method: int = _DEFAULT_SSL_METHOD, source_address: Tuple[str, int] = ('', 0),
alpn_protocols: Optional[List[str]] = None) -> crypto.X509:
alpn_protocols: Optional[Sequence[bytes]] = None) -> crypto.X509:
"""Probe SNI server for SSL certificate.
:param bytes name: Byte string to send as the server name in the
@ -170,7 +174,7 @@ def probe_sni(name: bytes, host: bytes, port: int = 443, timeout: int = 300, #
of source interface). See `socket.creation_connection` for more
info. Available only in Python 2.7+.
:param alpn_protocols: Protocols to request using ALPN.
:type alpn_protocols: `list` of `str`
:type alpn_protocols: `Sequence` of `bytes`
:raises acme.errors.Error: In case of any problems.
@ -207,7 +211,9 @@ def probe_sni(name: bytes, host: bytes, port: int = 443, timeout: int = 300, #
client_ssl.shutdown()
except SSL.Error as error:
raise errors.Error(error)
return client_ssl.get_peer_certificate()
cert = client_ssl.get_peer_certificate()
assert cert # Appease mypy. We would have crashed out by now if there was no certificate.
return cert
def make_csr(private_key_pem: bytes, domains: Optional[Union[Set[str], List[str]]] = None,

View file

@ -46,10 +46,12 @@ class TLSServer(socketserver.TCPServer):
method=self.method))
def _cert_selection(self, connection: SSL.Connection
) -> Tuple[crypto.PKey, crypto.X509]: # pragma: no cover
) -> Optional[Tuple[crypto.PKey, crypto.X509]]: # pragma: no cover
"""Callback selecting certificate for connection."""
server_name = connection.get_servername()
return self.certs.get(server_name, None)
if server_name:
return self.certs.get(server_name, None)
return None
def server_bind(self) -> None:
self._wrap_sock()
@ -151,7 +153,7 @@ class TLSALPN01Server(TLSServer, ACMEServerMixin):
def __init__(self, server_address: Tuple[str, int],
certs: List[Tuple[crypto.PKey, crypto.X509]],
challenge_certs: Mapping[str, Tuple[crypto.PKey, crypto.X509]],
challenge_certs: Mapping[bytes, Tuple[crypto.PKey, crypto.X509]],
ipv6: bool = False) -> None:
# We don't need to implement a request handler here because the work
# (including logging) is being done by wrapped socket set up in the
@ -161,7 +163,8 @@ class TLSALPN01Server(TLSServer, ACMEServerMixin):
ipv6=ipv6)
self.challenge_certs = challenge_certs
def _cert_selection(self, connection: SSL.Connection) -> Tuple[crypto.PKey, crypto.X509]:
def _cert_selection(self, connection: SSL.Connection) -> Optional[Tuple[crypto.PKey,
crypto.X509]]:
# TODO: We would like to serve challenge cert only if asked for it via
# ALPN. To do this, we need to retrieve the list of protos from client
# hello, but this is currently impossible with openssl [0], and ALPN
@ -170,8 +173,10 @@ class TLSALPN01Server(TLSServer, ACMEServerMixin):
# handshake in alpn_selection() if ALPN protos are not what we expect.
# [0] https://github.com/openssl/openssl/issues/4952
server_name = connection.get_servername()
logger.debug("Serving challenge cert for server name %s", server_name)
return self.challenge_certs[server_name]
if server_name:
logger.debug("Serving challenge cert for server name %s", server_name)
return self.challenge_certs[server_name]
return None # pragma: no cover
def _alpn_selection(self, _connection: SSL.Connection, alpn_protos: List[bytes]) -> bytes:
"""Callback to select alpn protocol."""

View file

@ -3,7 +3,7 @@ import sys
from setuptools import find_packages
from setuptools import setup
version = '1.30.0.dev0'
version = '1.31.0.dev0'
install_requires = [
'cryptography>=2.5.0',

View file

@ -325,12 +325,12 @@ class TLSALPN01ResponseTest(unittest.TestCase):
mock_gethostbyname.assert_called_once_with('foo.com')
mock_probe_sni.assert_called_once_with(
host=b'127.0.0.1', port=self.response.PORT, name=b'foo.com',
alpn_protocols=['acme-tls/1'])
alpn_protocols=[b'acme-tls/1'])
self.response.probe_cert('foo.com', host='8.8.8.8')
mock_probe_sni.assert_called_with(
host=b'8.8.8.8', port=mock.ANY, name=b'foo.com',
alpn_protocols=['acme-tls/1'])
alpn_protocols=[b'acme-tls/1'])
@mock.patch('acme.challenges.TLSALPN01Response.probe_cert')
def test_simple_verify_false_on_probe_error(self, mock_probe_cert):

View file

@ -15,6 +15,7 @@ from acme import challenges
from acme import errors
from acme import jws as acme_jws
from acme import messages
from acme.client import ClientNetwork
from acme.client import ClientV2
import messages_test
import test_util
@ -410,7 +411,6 @@ class ClientNetworkTest(unittest.TestCase):
self.verify_ssl = mock.MagicMock()
self.wrap_in_jws = mock.MagicMock(return_value=mock.sentinel.wrapped)
from acme.client import ClientNetwork
self.net = ClientNetwork(
key=KEY, alg=jose.RS256, verify_ssl=self.verify_ssl,
user_agent='acme-python-test')
@ -638,7 +638,6 @@ class ClientNetworkWithMockedResponseTest(unittest.TestCase):
"""Tests for acme.client.ClientNetwork which mock out response."""
def setUp(self):
from acme.client import ClientNetwork
self.net = ClientNetwork(key=None, alg=None)
self.response = mock.MagicMock(ok=True, status_code=http_client.OK)
@ -800,15 +799,16 @@ class ClientNetworkSourceAddressBindingTest(unittest.TestCase):
self.source_address = "8.8.8.8"
def test_source_address_set(self):
from acme.client import ClientNetwork
net = ClientNetwork(key=None, alg=None, source_address=self.source_address)
with mock.patch('warnings.warn') as mock_warn:
net = ClientNetwork(key=None, alg=None, source_address=self.source_address)
mock_warn.assert_called_once()
self.assertIn('source_address', mock_warn.call_args[0][0])
for adapter in net.session.adapters.values():
self.assertIn(self.source_address, adapter.source_address)
def test_behavior_assumption(self):
"""This is a test that guardrails the HTTPAdapter behavior so that if the default for
a Session() changes, the assumptions here aren't violated silently."""
from acme.client import ClientNetwork
# Source address not specified, so the default adapter type should be bound -- this
# test should fail if the default adapter type is changed by requests
net = ClientNetwork(key=None, alg=None)

View file

@ -1,6 +1,7 @@
"""Tests for acme.fields."""
import datetime
import unittest
import warnings
import josepy as jose
import pytz

View file

@ -2,6 +2,7 @@
from typing import Dict
import unittest
from unittest import mock
import warnings
import josepy as jose

View file

@ -1,7 +1,7 @@
from setuptools import find_packages
from setuptools import setup
version = '1.30.0.dev0'
version = '1.31.0.dev0'
install_requires = [
# We specify the minimum acme and certbot version as the current plugin

View file

@ -125,7 +125,7 @@ def assert_equals_world_read_permissions(file1: str, file2: str) -> None:
mode_file1 = os.stat(file1).st_mode & 0o004
mode_file2 = os.stat(file2).st_mode & 0o004
else:
everybody = win32security.ConvertStringSidToSid(EVERYBODY_SID)
everybody = win32security.ConvertStringSidToSid(EVERYBODY_SID) # pylint: disable=used-before-assignment
security1 = win32security.GetFileSecurity(file1, win32security.DACL_SECURITY_INFORMATION)
dacl1 = security1.GetSecurityDescriptorDacl()
@ -135,7 +135,7 @@ def assert_equals_world_read_permissions(file1: str, file2: str) -> None:
'TrusteeType': win32security.TRUSTEE_IS_USER,
'Identifier': everybody,
})
mode_file1 = mode_file1 & ntsecuritycon.FILE_GENERIC_READ
mode_file1 = mode_file1 & ntsecuritycon.FILE_GENERIC_READ # pylint: disable=used-before-assignment
security2 = win32security.GetFileSecurity(file2, win32security.DACL_SECURITY_INFORMATION)
dacl2 = security2.GetSecurityDescriptorDacl()

View file

@ -133,18 +133,9 @@ class ACMEServer:
acme_xdist['directory_url'] = BOULDER_V2_DIRECTORY_URL
acme_xdist['challtestsrv_url'] = BOULDER_V2_CHALLTESTSRV_URL
acme_xdist['http_port'] = {
node: port for (node, port) in # pylint: disable=unnecessary-comprehension
zip(nodes, range(5200, 5200 + len(nodes)))
}
acme_xdist['https_port'] = {
node: port for (node, port) in # pylint: disable=unnecessary-comprehension
zip(nodes, range(5100, 5100 + len(nodes)))
}
acme_xdist['other_port'] = {
node: port for (node, port) in # pylint: disable=unnecessary-comprehension
zip(nodes, range(5300, 5300 + len(nodes)))
}
acme_xdist['http_port'] = dict(zip(nodes, range(5200, 5200 + len(nodes))))
acme_xdist['https_port'] = dict(zip(nodes, range(5100, 5100 + len(nodes))))
acme_xdist['other_port'] = dict(zip(nodes, range(5300, 5300 + len(nodes))))
self.acme_xdist = acme_xdist

View file

@ -1,7 +1,7 @@
from setuptools import find_packages
from setuptools import setup
version = '1.30.0.dev0'
version = '1.31.0.dev0'
install_requires = [
'certbot',

View file

@ -4,7 +4,7 @@ import sys
from setuptools import find_packages
from setuptools import setup
version = '1.30.0.dev0'
version = '1.31.0.dev0'
install_requires = [
'cloudflare>=1.5.1',

View file

@ -4,7 +4,7 @@ import sys
from setuptools import find_packages
from setuptools import setup
version = '1.30.0.dev0'
version = '1.31.0.dev0'
install_requires = [
'python-digitalocean>=1.11', # 1.15.0 or newer is recommended for TTL support

View file

@ -4,7 +4,7 @@ import sys
from setuptools import find_packages
from setuptools import setup
version = '1.30.0.dev0'
version = '1.31.0.dev0'
install_requires = [
# This version of lexicon is required to address the problem described in

View file

@ -4,7 +4,7 @@ import sys
from setuptools import find_packages
from setuptools import setup
version = '1.30.0.dev0'
version = '1.31.0.dev0'
install_requires = [
'dns-lexicon>=3.2.1',

View file

@ -4,7 +4,7 @@ import sys
from setuptools import find_packages
from setuptools import setup
version = '1.30.0.dev0'
version = '1.31.0.dev0'
install_requires = [
'dns-lexicon>=3.2.1',

View file

@ -4,7 +4,7 @@ import sys
from setuptools import find_packages
from setuptools import setup
version = '1.30.0.dev0'
version = '1.31.0.dev0'
install_requires = [
'google-api-python-client>=1.5.5',

View file

@ -4,7 +4,7 @@ import sys
from setuptools import find_packages
from setuptools import setup
version = '1.30.0.dev0'
version = '1.31.0.dev0'
install_requires = [
'dns-lexicon>=3.2.1',

View file

@ -4,7 +4,7 @@ import sys
from setuptools import find_packages
from setuptools import setup
version = '1.30.0.dev0'
version = '1.31.0.dev0'
install_requires = [
'dns-lexicon>=3.2.1',

View file

@ -4,7 +4,7 @@ import sys
from setuptools import find_packages
from setuptools import setup
version = '1.30.0.dev0'
version = '1.31.0.dev0'
install_requires = [
'dns-lexicon>=3.2.1',

View file

@ -4,7 +4,7 @@ import sys
from setuptools import find_packages
from setuptools import setup
version = '1.30.0.dev0'
version = '1.31.0.dev0'
install_requires = [
'dns-lexicon>=3.2.1',

View file

@ -4,7 +4,7 @@ import sys
from setuptools import find_packages
from setuptools import setup
version = '1.30.0.dev0'
version = '1.31.0.dev0'
install_requires = [
'dnspython>=1.15.0',

View file

@ -38,7 +38,8 @@ class Authenticator(dns_common.DNSAuthenticator):
def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(*args, **kwargs)
self.r53 = boto3.client("route53")
self._resource_records: DefaultDict[str, List[Dict[str, str]]] = collections.defaultdict(list)
self._resource_records: DefaultDict[str, List[Dict[str, str]]] = \
collections.defaultdict(list)
def more_info(self) -> str:
return "Solve a DNS01 challenge using AWS Route53"

View file

@ -4,7 +4,7 @@ import sys
from setuptools import find_packages
from setuptools import setup
version = '1.30.0.dev0'
version = '1.31.0.dev0'
install_requires = [
'boto3>=1.15.15',

View file

@ -4,7 +4,7 @@ import sys
from setuptools import find_packages
from setuptools import setup
version = '1.30.0.dev0'
version = '1.31.0.dev0'
install_requires = [
'dns-lexicon>=3.2.1',

View file

@ -1,7 +1,7 @@
from setuptools import find_packages
from setuptools import setup
version = '1.30.0.dev0'
version = '1.31.0.dev0'
install_requires = [
# We specify the minimum acme and certbot version as the current plugin

View file

@ -2,7 +2,7 @@
Certbot adheres to [Semantic Versioning](https://semver.org/).
## 1.30.0 - master
## 1.31.0 - master
### Added
@ -18,6 +18,35 @@ Certbot adheres to [Semantic Versioning](https://semver.org/).
More details about these changes can be found on our GitHub repo.
## 1.30.0 - 2022-09-07
### Added
*
### Changed
* `acme.client.ClientBase`, `acme.messages.Authorization.resolved_combinations`,
`acme.messages.Authorization.combinations`, `acme.mixins`, `acme.fields.resource`,
and `acme.fields.Resource` are deprecated and will be removed in a future release.
* `acme.messages.OLD_ERROR_PREFIX` (`urn:acme:error:`) is deprecated and support for
the old ACME error prefix in Certbot will be removed in the next major release of
Certbot.
* `acme.messages.Directory.register` is deprecated and will be removed in the next
major release of Certbot. Furthermore, `.Directory` will only support lookups
by the exact resource name string in the ACME directory (e.g. `directory['newOrder']`).
* The `certbot-dns-cloudxns` plugin is now deprecated and will be removed in the
next major release of Certbot.
* The `source_address` argument for `acme.client.ClientNetwork` is deprecated
and support for it will be removed in the next major release.
* Add UI text suggesting users create certs for multiple domains, when possible
### Fixed
*
More details about these changes can be found on our GitHub repo.
## 1.29.0 - 2022-07-05
### Added

View file

@ -1,3 +1,3 @@
"""Certbot client."""
# version number like 1.2.3a0, must have at least 2 parts, like 1.2
__version__ = '1.30.0.dev0'
__version__ = '1.31.0.dev0'

View file

@ -194,7 +194,7 @@ class _WindowsLockMechanism(_BaseLockMechanism):
low level APIs, and Python does not do it. As of Python 3.7 and below, Python developers
state that deleting a file opened by a process from another process is not possible with
os.open and io.open.
Consequently, mscvrt.locking is sufficient to obtain an effective lock, and the race
Consequently, msvcrt.locking is sufficient to obtain an effective lock, and the race
condition encountered on Linux is not possible on Windows, leading to a simpler workflow.
"""
def acquire(self) -> None:
@ -209,7 +209,7 @@ class _WindowsLockMechanism(_BaseLockMechanism):
# This "type: ignore" is currently needed because msvcrt methods
# are only defined on Windows. See
# https://github.com/python/typeshed/blob/16ae4c61201cd8b96b8b22cdfb2ab9e89ba5bcf2/stdlib/msvcrt.pyi.
msvcrt.locking(fd, msvcrt.LK_NBLCK, 1) # type: ignore
msvcrt.locking(fd, msvcrt.LK_NBLCK, 1) # type: ignore # pylint: disable=used-before-assignment
except (IOError, OSError) as err:
if fd:
os.close(fd)
@ -229,7 +229,7 @@ class _WindowsLockMechanism(_BaseLockMechanism):
# This "type: ignore" is currently needed because msvcrt methods
# are only defined on Windows. See
# https://github.com/python/typeshed/blob/16ae4c61201cd8b96b8b22cdfb2ab9e89ba5bcf2/stdlib/msvcrt.pyi.
msvcrt.locking(self._fd, msvcrt.LK_UNLCK, 1) # type: ignore
msvcrt.locking(self._fd, msvcrt.LK_UNLCK, 1) # type: ignore # pylint: disable=used-before-assignment
os.close(self._fd)
try:

View file

@ -47,7 +47,7 @@ class AnnotatedChallenge(jose.ImmutableMap):
class KeyAuthorizationAnnotatedChallenge(AnnotatedChallenge):
"""Client annotated `KeyAuthorizationChallenge` challenge."""
__slots__ = ('challb', 'domain', 'account_key')
__slots__ = ('challb', 'domain', 'account_key') # pylint: disable=redefined-slots-in-subclass
def response_and_validation(self, *args: Any, **kwargs: Any) -> Any:
"""Generate response and validation."""
@ -57,5 +57,5 @@ class KeyAuthorizationAnnotatedChallenge(AnnotatedChallenge):
class DNS(AnnotatedChallenge):
"""Client annotated "dns" ACME challenge."""
__slots__ = ('challb', 'domain')
__slots__ = ('challb', 'domain') # pylint: disable=redefined-slots-in-subclass
acme_type = challenges.DNS

View file

@ -181,7 +181,10 @@ def _filter_names(names: Iterable[str],
if override_question:
question = override_question
else:
question = "Which names would you like to activate HTTPS for?"
question = (
"Which names would you like to activate HTTPS for?\n"
"We recommend selecting either all domains, or all domains in a VirtualHost/server "
"block.")
code, names = display_util.checklist(
question, tags=sorted_names, cli_flag="--domains", force_interactive=True)
return code, [str(s) for s in names]

View file

@ -38,14 +38,12 @@ class _AuthenticatorCallableTestCase(Protocol):
See
https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertTrue
"""
...
def assertEqual(self, *unused_args: Any) -> None:
"""
See
https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertEqual
"""
...
class BaseAuthenticatorTest:

View file

@ -57,7 +57,6 @@ class _LexiconAwareTestCase(Protocol):
See
https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertRaises
"""
...
# These classes are intended to be subclassed/mixed in, so not all members are defined.

View file

@ -126,7 +126,7 @@ optional arguments:
case, and to know when to deprecate support for past
Python versions and flags. If you wish to hide this
information from the Let's Encrypt server, set this to
"". (default: CertbotACMEClient/1.29.0 (certbot;
"". (default: CertbotACMEClient/1.30.0 (certbot;
OS_NAME OS_VERSION) Authenticator/XXX Installer/YYY
(SUBCOMMAND; flags: FLAGS) Py/major.minor.patchlevel).
The flags encoded in the user agent are: --duplicate,
@ -236,7 +236,9 @@ testing:
(default: False)
--debug Show tracebacks in case of errors (default: False)
--no-verify-ssl Disable verification of the ACME server's certificate.
(default: False)
The root certificates trusted by Certbot can be
overriden by setting the REQUESTS_CA_BUNDLE
environment variable. (default: False)
--http-01-port HTTP01_PORT
Port used in the http-01 challenge. This only affects
the port Certbot listens on. A conforming ACME server

View file

@ -84,7 +84,7 @@ release = meta['version']
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
language = 'en'
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:

View file

@ -500,6 +500,9 @@ Submitting a pull request
Steps:
0. We recommend you talk with us in a GitHub issue or :ref:`Mattermost <ask for
help>` before writing a pull request to ensure the changes you're making is
something we have the time and interest to review.
1. Write your code! When doing this, you should add :ref:`mypy type annotations
<type annotations>` for any functions you add or modify. You can check that
you've done this correctly by running ``tox -e mypy`` on a machine that has

View file

@ -315,6 +315,8 @@ dns-lightsail_ Y N DNS Authentication using Amazon Lightsail DNS API
dns-inwx_ Y Y DNS Authentication for INWX through the XML API
dns-azure_ Y N DNS Authentication using Azure DNS
dns-godaddy_ Y N DNS Authentication using Godaddy DNS
dns-yandexcloud_ Y N DNS Authentication using Yandex Cloud DNS
dns-bunny_ Y N DNS Authentication using BunnyDNS
njalla_ Y N DNS Authentication for njalla
DuckDNS_ Y N DNS Authentication for DuckDNS
Porkbun_ Y N DNS Authentication for Porkbun
@ -335,6 +337,8 @@ Infomaniak_ Y N DNS Authentication using Infomaniak Domains API
.. _dns-inwx: https://github.com/oGGy990/certbot-dns-inwx/
.. _dns-azure: https://github.com/binkhq/certbot-dns-azure
.. _dns-godaddy: https://github.com/miigotu/certbot-dns-godaddy
.. _dns-yandexcloud: https://github.com/PykupeJIbc/certbot-dns-yandexcloud
.. _dns-bunny: https://github.com/mwt/certbot-dns-bunny
.. _njalla: https://github.com/chaptergy/certbot-dns-njalla
.. _DuckDNS: https://github.com/infinityofspace/certbot_dns_duckdns
.. _Porkbun: https://github.com/infinityofspace/certbot_dns_porkbun
@ -557,6 +561,11 @@ If you need to delete a certificate, use the ``delete`` subcommand.
.. note:: Read this and the `Safely deleting certificates`_ sections carefully. This is an irreversible operation and must
be done with care.
Certbot does not automatically revoke a certificate before deleting it. If you're no longer using a certificate and don't
plan to use it anywhere else, you may want to follow the instructions in `Revoking certificates`_ instead. Generally, there's
no need to revoke a certificate if its private key has not been compromised, but you may still receive expiration emails
from Let's Encrypt unless you revoke.
.. note:: Do not manually delete certificate files from inside ``/etc/letsencrypt/``. Always use the ``delete`` subcommand.
A certificate may be deleted by providing its name with ``--cert-name``. \

View file

@ -6,8 +6,8 @@
targets:
#-----------------------------------------------------------------------------
#Ubuntu
- ami: ami-0c2d5393cb5b518f6
name: ubuntu21.10
- ami: ami-051dcca84f1edfff1
name: ubuntu22.04
type: ubuntu
virt: hvm
user: ubuntu

View file

@ -13,19 +13,12 @@
# The current warnings being ignored are:
# 1) The warning raised when importing certbot.tests.util and the external mock
# library is installed.
# 2) The deprecation warning raised when importing deprecated attributes from
# the certbot.display.util module.
# 3) A deprecation warning is raised in dnspython==1.15.0 in the oldest tests for
# 2) A deprecation warning is raised in dnspython==1.15.0 in the oldest tests for
# certbot-dns-rfc2136.
# 4) The vendored version of six in botocore causes ImportWarnings in Python
# 3.10+. See https://github.com/boto/botocore/issues/2548.
# 5) botocore's default TLS settings raise deprecation warnings in Python
# 3.10+, but their values are sane from a security perspective. See
# https://github.com/boto/botocore/issues/2550.
# 3) botocore is currently using deprecated urllib3 functionality. See
# https://github.com/boto/botocore/issues/2744.
filterwarnings =
error
ignore:The external mock module:PendingDeprecationWarning
ignore:.*attribute in certbot.display.util module is deprecated:DeprecationWarning
ignore:decodestring\(\) is a deprecated alias:DeprecationWarning:dns
ignore:_SixMetaPathImporter.:ImportWarning
ignore:ssl.PROTOCOL_TLS:DeprecationWarning:botocore
ignore:'urllib3.contrib.pyopenssl:DeprecationWarning:botocore

View file

@ -63,7 +63,6 @@ pyasn1-modules==0.0.10; python_version >= "3.7"
pyasn1==0.1.9
pycparser==2.14
pylint==2.13.9
pylint==2.13.9; python_version >= "3.7"
pynacl==1.5.0; python_version >= "3.7"
pyopenssl==17.5.0
pyparsing==2.2.1

View file

@ -61,18 +61,27 @@ mock = "*"
# https://github.com/python-poetry/poetry/issues/1584. This version is required
# here in addition to certbot/setup.py because otherwise the pre-release
# version of poetry will not be installed.
poetry = ">=1.2.0a1"
#
# Additionally, newer versions of poetry/poetry-core include package extras
# (e.g. "docker[ssh]") in its `poetry export` output which is valid for
# requirements files, but not constraints files. We are currently using that
# output as constraints so let's also pin back poetry and poetry-core until we
# have a better workaround.
poetry = "1.2.0a2"
poetry-core = "1.1.0a7"
# setuptools-rust is a build dependency of cryptography, and since we don't have
# a great way of pinning build dependencies, we simply list it here to ensure a
# working version. Note: if build dependencies of setuptools-rust break at some
# point, it's probably worth enumerating and pinning them (and recursing to
# THEIR build dependencies) as well.
setuptools-rust = "*"
# A bad python_requires constraint in pylint 2.6.2 can sometimes crash poetry
# before it has finished resolving. No newer releases have the same issue. Remove
# this once we can upgrade to a release of Poetry containing this commit:
# https://github.com/python-poetry/poetry-core/commit/4e1f2ab582d1fef0033c0d3f35a3f2f2365a4bc9
pylint = ">2.6.2"
# pylint often adds new checks that we need to conform our code to when
# upgrading our dependencies. To help control when this needs to be done, we
# pin pylint to a compatible version here.
#
# If this pinning is removed, we may still need to add a lower bound for the
# pylint version. See https://github.com/certbot/certbot/pull/9229.
pylint = "2.13.9"
# Bug in poetry, where still installes yanked versions from pypi (source: https://github.com/python-poetry/poetry/issues/2453)
# this version of cryptography introduced a security vulnrability.

View file

@ -98,11 +98,13 @@ cython = "*"
# wheel 0.34.0 is buggy).
wheel = "<0.34.0"
# A bad python_requires constraint in pylint 2.6.2 can sometimes crash poetry
# before it has finished resolving. No newer releases have the same issue. Remove
# this once we can upgrade to a release of Poetry containing this commit:
# https://github.com/python-poetry/poetry-core/commit/4e1f2ab582d1fef0033c0d3f35a3f2f2365a4bc9
pylint = ">2.6.2"
# pylint often adds new checks that we need to conform our code to when
# upgrading our dependencies. To help control when this needs to be done, we
# pin pylint to a compatible version here.
#
# If this pinning is removed, we may still need to add a lower bound for the
# pylint version. See https://github.com/certbot/certbot/pull/9229.
pylint = "2.13.9"
[tool.poetry.dev-dependencies]

View file

@ -7,186 +7,186 @@
# for more info.
alabaster==0.7.12; python_version >= "3.7"
apacheconfig==0.3.2; python_version >= "3.7"
appdirs==1.4.4; python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" or python_version >= "3.7" and python_version < "4.0" and python_full_version >= "3.4.0"
appnope==0.1.2; python_version >= "3.7" and sys_platform == "darwin"
astroid==2.9.3; python_version >= "3.7" and python_full_version >= "3.6.2"
atomicwrites==1.4.0; python_version >= "3.7" and python_full_version < "3.0.0" and sys_platform == "win32" or sys_platform == "win32" and python_version >= "3.7" and python_full_version >= "3.4.0"
attrs==21.4.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.7"
awscli==1.22.75; python_version >= "3.6"
appdirs==1.4.4; python_version >= "3.7" and python_version < "4.0"
appnope==0.1.3; python_version >= "3.7" and sys_platform == "darwin"
astroid==2.11.7; python_version >= "3.7"
atomicwrites==1.4.1; sys_platform == "win32" and python_version >= "3.7"
attrs==22.1.0; python_version >= "3.7"
awscli==1.25.40
awscli==1.25.40; python_version >= "3.7"
azure-devops==6.0.0b4; python_version >= "3.7"
babel==2.9.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version >= "3.4.0"
babel==2.10.3; python_version >= "3.7"
backcall==0.2.0; python_version >= "3.7"
bcrypt==3.2.0; python_version >= "3.7"
beautifulsoup4==4.10.0; python_full_version > "3.0.0" and python_version >= "3.7" or python_version >= "3.7" and python_version < "4.0" and python_full_version > "3.0.0"
bleach==4.1.0; python_version >= "3.7"
boto3==1.21.20; python_version >= "3.7"
botocore==1.24.20; python_version >= "3.7"
cachecontrol==0.12.10; python_version >= "3.7" and python_version < "4.0"
cached-property==1.5.2; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.7"
cachetools==5.0.0; python_version >= "3.7" and python_version < "4.0" and (python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.7")
cachy==0.3.0; python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" or python_version >= "3.7" and python_version < "4.0" and python_full_version >= "3.4.0"
certifi==2021.10.8; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.7" or python_version >= "3.7"
cffi==1.15.0; python_version >= "3.7" or python_version >= "3.7"
charset-normalizer==2.0.12; python_full_version >= "3.6.0" and python_version >= "3.7"
cleo==1.0.0a4; python_version >= "3.7" and python_version < "4.0"
cloudflare==2.8.15; python_version >= "3.7"
colorama==0.4.3; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.7" or sys_platform == "win32" and python_full_version >= "3.6.2" and python_version >= "3.7" or python_version >= "3.7" and python_full_version < "3.0.0" and sys_platform == "win32" or python_full_version >= "3.5.0" and python_version >= "3.7" and sys_platform == "win32" or python_version >= "3.7" and python_full_version < "3.0.0" and platform_system == "Windows" or python_version >= "3.7" and python_full_version >= "3.5.0" and platform_system == "Windows"
configargparse==1.5.3; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.7"
bcrypt==3.2.2; python_version >= "3.7"
beautifulsoup4==4.11.1; python_version >= "3.7"
bleach==5.0.1; python_version >= "3.7"
boto3==1.24.40; python_version >= "3.7"
botocore==1.27.40; python_version >= "3.7"
cachecontrol==0.12.11; python_version >= "3.7" and python_version < "4.0"
cached-property==1.5.2; python_version >= "3.7"
cachetools==5.2.0; python_version >= "3.7" and python_version < "4.0"
cachy==0.3.0; python_version >= "3.7" and python_version < "4.0"
certifi==2022.6.15; python_version >= "3.7" and python_version < "4" or python_version >= "3.7"
cffi==1.15.1; python_version >= "3.7"
charset-normalizer==2.1.0; python_version >= "3.7" and python_version < "4"
cleo==1.0.0a5; python_version >= "3.7" and python_version < "4.0"
cloudflare==2.9.11; python_version >= "3.7"
colorama==0.4.4; python_version >= "3.7"
configargparse==1.5.3; python_version >= "3.7"
configobj==5.0.6; python_version >= "3.7"
coverage==6.3.2; python_version >= "3.7" or python_version >= "3.7"
coverage==6.4.2; python_version >= "3.7"
crashtest==0.3.1; python_version >= "3.7" and python_version < "4.0"
cryptography==36.0.2; python_version >= "3.7" and python_version < "4.0" or python_version >= "3.7" or python_version >= "3.7" and python_version < "4.0" and sys_platform == "linux"
cython==0.29.28; (python_version >= "2.6" and python_full_version < "3.0.0") or (python_full_version >= "3.3.0")
cryptography==37.0.4
cryptography==37.0.4; python_version >= "3.7"
cython==0.29.31
decorator==5.1.1; python_version >= "3.7"
deprecated==1.2.13; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version >= "3.4.0"
distlib==0.3.4; python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" or python_version >= "3.7" and python_version < "4.0" and python_full_version >= "3.4.0" or python_version >= "3.7"
distro==1.7.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.7" or python_version >= "3.7"
dns-lexicon==3.9.4; python_version >= "3.7" and python_version < "4.0"
dill==0.3.5.1; python_version >= "3.7"
distlib==0.3.5; python_version >= "3.7"
distro==1.7.0; python_version >= "3.7"
dns-lexicon==3.11.1; python_version >= "3.7" and python_version < "4.0"
dnspython==2.2.1; python_version >= "3.7" and python_version < "4.0"
docker-compose==1.26.2; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.7"
docker==4.2.2; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.7"
dockerpty==0.4.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.7"
docopt==0.6.2; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.7"
docutils==0.15.2; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.7" or python_version >= "3.7" and python_full_version >= "3.4.0"
docker-compose==1.26.2; python_version >= "3.7"
docker==4.2.2; python_version >= "3.7"
dockerpty==0.4.1; python_version >= "3.7"
docopt==0.6.2; python_version >= "3.7"
docutils==0.16; python_version >= "3.7"
entrypoints==0.3; python_version >= "3.7" and python_version < "4.0"
execnet==1.9.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.7"
fabric==2.6.0; python_version >= "3.7"
filelock==3.6.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version >= "3.5.0" or python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" or python_version >= "3.7" and python_version < "4.0" and python_full_version >= "3.4.0" or python_version >= "3.7" and python_version < "4.0"
google-api-core==2.7.1; python_version >= "3.7"
google-api-python-client==2.41.0; python_version >= "3.7"
execnet==1.9.0; python_version >= "3.7"
fabric==2.7.1; python_version >= "3.7"
filelock==3.7.1; python_version >= "3.7" or python_version >= "3.7" and python_version < "4.0"
google-api-core==2.8.2; python_version >= "3.7"
google-api-python-client==2.55.0; python_version >= "3.7"
google-auth-httplib2==0.1.0; python_version >= "3.7"
google-auth==2.6.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.7"
googleapis-common-protos==1.55.0; python_version >= "3.7"
html5lib==1.1; python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" or python_version >= "3.7" and python_version < "4.0" and python_full_version >= "3.5.0"
httplib2==0.20.4; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.7"
idna==3.3; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.7" or python_version >= "3.7" and python_version < "4.0"
imagesize==1.3.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version >= "3.4.0"
importlib-metadata==1.7.0; python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "3.8" or python_version >= "3.7" and python_version < "3.8" and python_full_version >= "3.5.0"
google-auth==2.9.1; python_version >= "3.7"
googleapis-common-protos==1.56.4; python_version >= "3.7"
html5lib==1.1; python_version >= "3.7" and python_version < "4.0"
httplib2==0.20.4; python_version >= "3.7"
idna==3.3; python_version >= "3.7" and python_version < "4" or python_version >= "3.7" and python_version < "4.0"
imagesize==1.4.1; python_version >= "3.7"
importlib-metadata==1.7.0; python_version >= "3.7" and python_version < "3.8"
iniconfig==1.1.1; python_version >= "3.7"
invoke==1.6.0; python_version >= "3.7"
invoke==1.7.1; python_version >= "3.7"
ipdb==0.13.9; python_version >= "3.7"
ipython==7.32.0; python_version >= "3.7"
ipython==7.34.0; python_version >= "3.7"
isodate==0.6.1; python_version >= "3.7"
isort==5.10.1; python_full_version >= "3.6.2" and python_version < "4.0" and python_version >= "3.7"
isort==5.10.1; python_version >= "3.7" and python_version < "4.0"
jedi==0.18.1; python_version >= "3.7"
jeepney==0.7.1; python_version >= "3.7" and python_version < "4.0" and sys_platform == "linux"
jinja2==3.0.3; python_version >= "3.7" or python_version >= "3.7"
jmespath==0.10.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.7"
jeepney==0.8.0; python_version >= "3.7" and python_version < "4.0" and sys_platform == "linux"
jinja2==3.1.2; python_version >= "3.7"
jmespath==1.0.1; python_version >= "3.7"
josepy==1.13.0; python_version >= "3.7"
jsonlines==3.0.0; python_version >= "3.7"
jsonpickle==2.1.0; python_version >= "3.7"
jsonschema==3.2.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.7"
jsonlines==3.1.0; python_version >= "3.7"
jsonpickle==2.2.0; python_version >= "3.7"
jsonschema==3.2.0; python_version >= "3.7"
keyring==22.3.0; python_version >= "3.7" and python_version < "4.0" or python_version >= "3.7"
lazy-object-proxy==1.7.1; python_version >= "3.7" and python_full_version >= "3.6.2"
lazy-object-proxy==1.7.1; python_version >= "3.7"
lockfile==0.12.2
markupsafe==2.1.1; python_version >= "3.7"
matplotlib-inline==0.1.3; python_version >= "3.7"
mccabe==0.6.1; python_version >= "3.7" and python_full_version >= "3.6.2"
mock==4.0.3; python_version >= "3.6"
msgpack==1.0.3; python_version >= "3.7" and python_version < "4.0"
mccabe==0.7.0; python_version >= "3.7"
mock==4.0.3
msgpack==1.0.4; python_version >= "3.7" and python_version < "4.0"
msrest==0.6.21; python_version >= "3.7"
mypy-extensions==0.4.3; python_version >= "3.7"
mypy==0.941; python_version >= "3.7"
mypy==0.971; python_version >= "3.7"
oauth2client==4.1.3; python_version >= "3.7"
oauthlib==3.2.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version >= "3.4.0"
packaging==20.9; python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" or python_version >= "3.7" and python_version < "4.0" and python_full_version >= "3.4.0" or python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.7" or python_version >= "3.7" and python_full_version >= "3.5.0"
paramiko==2.10.2; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.7" or python_version >= "3.7"
oauthlib==3.2.0; python_version >= "3.7"
packaging==20.9; python_version >= "3.7"
paramiko==2.11.0; python_version >= "3.7"
parsedatetime==2.6; python_version >= "3.7"
parso==0.8.3; python_version >= "3.7"
pathlib2==2.3.7.post1; python_version >= "3.7"
pexpect==4.8.0; python_version >= "3.7" and python_version < "4.0" or python_version >= "3.7" and sys_platform != "win32"
pickleshare==0.7.5; python_version >= "3.7"
pip==22.0.4; python_version >= "3.7"
pkginfo==1.8.2; python_version >= "3.7" and python_version < "4.0" or python_version >= "3.7"
platformdirs==2.5.1; python_version >= "3.7" and python_full_version >= "3.6.2"
pluggy==1.0.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version >= "3.5.0" or python_version >= "3.7"
pip==22.2.1; python_version >= "3.7"
pkginfo==1.8.3; python_version >= "3.7" and python_version < "4.0" or python_version >= "3.7"
platformdirs==2.5.2; python_version >= "3.7"
pluggy==1.0.0; python_version >= "3.7"
ply==3.11; python_version >= "3.7"
poetry-core==1.1.0a7; python_version >= "3.7" and python_version < "4.0"
poetry==1.2.0a2; python_version >= "3.6" and python_version < "4.0"
prompt-toolkit==3.0.28; python_version >= "3.7" and python_full_version >= "3.6.2"
protobuf==3.19.4; python_version >= "3.7"
poetry-core==1.1.0a7
poetry==1.2.0a2
prompt-toolkit==3.0.30; python_version >= "3.7"
protobuf==4.21.4; python_version >= "3.7"
ptyprocess==0.7.0; python_version >= "3.7" and python_version < "4.0"
py==1.11.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.7"
pyasn1-modules==0.2.8; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.7" or python_version >= "3.7"
pyasn1==0.4.8; python_version >= "3.7" and python_version < "4" or python_version >= "3.7"
pycparser==2.21; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.7"
pygithub==1.55; python_version >= "3.7"
pygments==2.11.2; python_version >= "3.7"
pyjwt==2.3.0; python_version >= "3.7"
py==1.11.0; python_version >= "3.7"
pyasn1-modules==0.2.8; python_version >= "3.7"
pyasn1==0.4.8; python_version >= "3.7"
pycparser==2.21; python_version >= "3.7"
pygments==2.12.0; python_version >= "3.7"
pylev==1.4.0; python_version >= "3.7" and python_version < "4.0"
pylint==2.12.2; python_full_version >= "3.6.2"
pynacl==1.5.0; python_version >= "3.7" or python_version >= "3.7"
pylint==2.13.9
pynacl==1.5.0; python_version >= "3.7"
pynsist==2.7; python_version >= "3.7"
pyopenssl==22.0.0; python_version >= "3.7"
pyparsing==3.0.7; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.7" or python_version >= "3.7" or python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" or python_version >= "3.7" and python_version < "4.0" and python_full_version >= "3.4.0"
pypiwin32==223; sys_platform == "win32" and python_version >= "3.6" and (python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.7")
pyparsing==3.0.9; python_version >= "3.7"
pypiwin32==223; sys_platform == "win32" and python_version >= "3.7"
pyrfc3339==1.1; python_version >= "3.7"
pyrsistent==0.18.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.7"
pytest-cov==3.0.0; python_version >= "3.7" or python_version >= "3.7"
pyrsistent==0.18.1; python_version >= "3.7"
pytest-cov==3.0.0; python_version >= "3.7"
pytest-forked==1.4.0; python_version >= "3.7"
pytest-xdist==2.5.0; python_version >= "3.7" or python_version >= "3.7"
pytest==7.1.0; python_version >= "3.7" or python_version >= "3.7"
pytest-xdist==2.5.0; python_version >= "3.7"
pytest==7.1.2; python_version >= "3.7"
python-augeas==1.1.0; python_version >= "3.7"
python-dateutil==2.8.2; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.7"
python-dateutil==2.8.2; python_version >= "3.7"
python-digitalocean==1.17.0; python_version >= "3.7"
python-dotenv==0.19.2; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.7"
pytz==2021.3; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version >= "3.4.0" or python_version >= "3.7"
python-dotenv==0.20.0; python_version >= "3.7"
pytz==2022.1; python_version >= "3.7"
pywin32-ctypes==0.2.0; python_version >= "3.7" and python_version < "4.0" and sys_platform == "win32"
pywin32==303; sys_platform == "win32" and python_version >= "3.7" or sys_platform == "win32" and python_version >= "3.6" and (python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.7")
pyyaml==5.4.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.7" or python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" or python_version >= "3.7" and python_version < "4.0" and python_full_version >= "3.6.0"
readme-renderer==34.0; python_version >= "3.7"
pywin32==304; sys_platform == "win32" and python_version >= "3.7"
pyyaml==5.4.1; python_version >= "3.7"
readme-renderer==35.0; python_version >= "3.7"
requests-download==0.1.2; python_version >= "3.7"
requests-file==1.5.1; python_version >= "3.7" and python_version < "4.0"
requests-oauthlib==1.3.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version >= "3.4.0"
requests-toolbelt==0.9.1; python_version >= "3.7" and python_version < "4.0" or python_version >= "3.7" or python_version >= "3.7"
requests==2.27.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.7" or python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" or python_version >= "3.7" and python_version < "4.0" and python_full_version >= "3.6.0"
requests-oauthlib==1.3.1; python_version >= "3.7"
requests-toolbelt==0.9.1; python_version >= "3.7"
requests==2.28.1; python_version >= "3.7" and python_version < "4"
rfc3986==2.0.0; python_version >= "3.7"
rsa==4.7.2; python_version >= "3.7" and python_version < "4" or python_version >= "3.5" and python_version < "4" and (python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.7")
s3transfer==0.5.2; python_version >= "3.7"
secretstorage==3.3.1; python_version >= "3.7" and python_version < "4.0" and sys_platform == "linux"
semantic-version==2.9.0; python_version >= "3.6"
setuptools-rust==1.1.2; python_version >= "3.6"
setuptools==60.9.3; python_version >= "3.7" or python_version >= "3.7" or python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.7" or python_version >= "3.7" and python_full_version >= "3.6.2" or python_full_version >= "3.4.0" and python_version >= "3.7"
rsa==4.7.2; python_version >= "3.7" and python_version < "4"
s3transfer==0.6.0; python_version >= "3.7"
secretstorage==3.3.2; python_version >= "3.7" and python_version < "4.0" and sys_platform == "linux"
semantic-version==2.10.0; python_version >= "3.7"
setuptools-rust==1.4.1
setuptools==63.2.0; python_version >= "3.7"
shellingham==1.4.0; python_version >= "3.7" and python_version < "4.0"
six==1.16.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.7" or python_full_version >= "3.3.0" and python_version >= "3.7" or python_version >= "3.7" and python_full_version >= "3.5.0" or python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" or python_version >= "3.7" and python_version < "4.0" and python_full_version >= "3.5.0" or python_version >= "3.7" and python_version < "4.0" and python_full_version >= "3.4.0" or python_full_version >= "3.6.0" and python_version >= "3.7" or python_version >= "3.7" and python_version < "4.0" and python_full_version >= "3.3.0"
six==1.16.0; python_version >= "3.7"
snowballstemmer==2.2.0; python_version >= "3.7"
soupsieve==2.3.1; python_full_version > "3.0.0" and python_version >= "3.7"
sphinx-rtd-theme==1.0.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version >= "3.4.0"
sphinx==4.3.2; python_version >= "3.7" or python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version >= "3.4.0"
soupsieve==2.3.2.post1; python_version >= "3.7"
sphinx-rtd-theme==1.0.0; python_version >= "3.7"
sphinx==4.3.2; python_version >= "3.7"
sphinxcontrib-applehelp==1.0.2; python_version >= "3.7"
sphinxcontrib-devhelp==1.0.2; python_version >= "3.7"
sphinxcontrib-htmlhelp==2.0.0; python_version >= "3.7"
sphinxcontrib-jsmath==1.0.1; python_version >= "3.7"
sphinxcontrib-qthelp==1.0.3; python_version >= "3.7"
sphinxcontrib-serializinghtml==1.1.5; python_version >= "3.7"
texttable==1.6.4; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.7"
tldextract==3.2.0; python_version >= "3.7" and python_version < "4.0"
toml==0.10.2; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version >= "3.3.0" or python_version >= "3.7" and python_full_version >= "3.6.2" or python_version >= "3.7" and python_full_version >= "3.5.0"
tomli==2.0.1; python_version >= "3.7" or python_version >= "3.7"
tomlkit==0.10.0; python_version >= "3.7" and python_version < "4.0"
tox==3.24.5; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version >= "3.5.0"
tqdm==4.63.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version >= "3.4.0"
traitlets==5.1.1; python_version >= "3.7"
texttable==1.6.4; python_version >= "3.7"
tldextract==3.3.1; python_version >= "3.7" and python_version < "4.0"
toml==0.10.2; python_version >= "3.7"
tomli==2.0.1; python_version < "3.11" and python_version >= "3.7" or python_full_version <= "3.11.0a6" and python_version >= "3.7" or python_version >= "3.7"
tomlkit==0.11.1; python_version >= "3.7" and python_version < "4.0"
tox==3.25.1; python_version >= "3.7"
tqdm==4.64.0; python_version >= "3.7"
traitlets==5.3.0; python_version >= "3.7"
twine==3.3.0; python_version >= "3.7"
typed-ast==1.5.2; python_version >= "3.7" and python_version < "3.8" or implementation_name == "cpython" and python_version < "3.8" and python_version >= "3.7" and python_full_version >= "3.6.2"
types-cryptography==3.3.18; python_version >= "3.7"
types-mock==4.0.11; python_version >= "3.7"
types-pyopenssl==22.0.0; python_version >= "3.7"
typed-ast==1.5.4; python_version >= "3.7" and python_version < "3.8" or implementation_name == "cpython" and python_version < "3.8" and python_version >= "3.7"
types-cryptography==3.3.21; python_version >= "3.7"
types-mock==4.0.15; python_version >= "3.7"
types-pyopenssl==22.0.9; python_version >= "3.7"
types-pyrfc3339==1.1.1; python_version >= "3.7"
types-python-dateutil==2.8.9; python_version >= "3.7"
types-pytz==2021.3.5; python_version >= "3.7"
types-requests==2.27.12; python_version >= "3.7"
types-setuptools==57.4.10; python_version >= "3.7"
types-six==1.16.12; python_version >= "3.7"
types-urllib3==1.26.11; python_version >= "3.7"
typing-extensions==4.1.1; python_version >= "3.7" or python_version >= "3.6" or python_version < "3.10" and python_full_version >= "3.6.2" and python_version >= "3.7" or python_version < "3.8" and python_version >= "3.7"
types-python-dateutil==2.8.19; python_version >= "3.7"
types-pytz==2022.1.2; python_version >= "3.7"
types-requests==2.28.5; python_version >= "3.7"
types-setuptools==63.2.2; python_version >= "3.7"
types-six==1.16.18; python_version >= "3.7"
types-urllib3==1.26.17; python_version >= "3.7"
typing-extensions==4.3.0; python_version >= "3.7" or python_version < "3.10" and python_version >= "3.7" or python_version < "3.8" and python_version >= "3.7"
uritemplate==4.1.1; python_version >= "3.7"
urllib3==1.26.8; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.7" or python_full_version >= "3.5.0" and python_version < "4" and python_version >= "3.7"
virtualenv==20.4.4; python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" or python_version >= "3.7" and python_version < "4.0" and python_full_version >= "3.4.0" or python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version >= "3.5.0"
wcwidth==0.2.5; python_version >= "3.7" and python_full_version >= "3.6.2"
webencodings==0.5.1; python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" or python_version >= "3.7" and python_version < "4.0" and python_full_version >= "3.5.0" or python_version >= "3.7"
websocket-client==0.59.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.7" or python_full_version >= "3.5.0" and python_version >= "3.7"
wheel==0.37.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version >= "3.5.0"
wrapt==1.13.3; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version >= "3.5.0" or python_version >= "3.7" and python_full_version >= "3.6.2"
urllib3==1.26.11; python_version >= "3.7" and python_version < "4"
virtualenv==20.4.4; python_version >= "3.7" and python_version < "4.0" or python_version >= "3.7"
wcwidth==0.2.5; python_version >= "3.7"
webencodings==0.5.1; python_version >= "3.7" and python_version < "4.0" or python_version >= "3.7"
websocket-client==0.59.0; python_version >= "3.7"
wheel==0.37.1; python_version >= "3.7"
wrapt==1.14.1; python_version >= "3.7"
yarg==0.1.9; python_version >= "3.7"
zipp==3.8.1; python_version >= "3.7" and python_version < "3.8"