Compare commits
29 Commits
test-upgra
...
test-remov
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5e62180231 | ||
|
|
5a9d5c4772 | ||
|
|
dd0e590de3 | ||
|
|
d3d9a05826 | ||
|
|
2cf1775864 | ||
|
|
f339d23e54 | ||
|
|
ac3edc2c1d | ||
|
|
ba912018f8 | ||
|
|
c06e40dbef | ||
|
|
32247b3c89 | ||
|
|
e4f5aced1c | ||
|
|
9292666b28 | ||
|
|
fb967fda15 | ||
|
|
4a404e2a4a | ||
|
|
0dbe17bbd4 | ||
|
|
e33090f282 | ||
|
|
06bece36de | ||
|
|
7f9857a81b | ||
|
|
459a254aea | ||
|
|
c21f277248 | ||
|
|
04a85742c1 | ||
|
|
21be290e24 | ||
|
|
bf40b81b5a | ||
|
|
1b6e4028dc | ||
|
|
f15d10abc8 | ||
|
|
a12d91aef6 | ||
|
|
c438a397a0 | ||
|
|
0f9f902b6e | ||
|
|
33f177b361 |
@@ -85,12 +85,6 @@ jobs:
|
||||
IMAGE_NAME: macOS-10.15
|
||||
PYTHON_VERSION: 3.8
|
||||
TOXENV: test-farm-apache2
|
||||
farmtest-leauto-upgrades:
|
||||
PYTHON_VERSION: 3.7
|
||||
TOXENV: test-farm-leauto-upgrades
|
||||
farmtest-certonly-standalone:
|
||||
PYTHON_VERSION: 3.7
|
||||
TOXENV: test-farm-certonly-standalone
|
||||
farmtest-sdists:
|
||||
PYTHON_VERSION: 3.7
|
||||
TOXENV: test-farm-sdists
|
||||
|
||||
@@ -1,127 +1,4 @@
|
||||
jobs:
|
||||
- job: docker_build
|
||||
pool:
|
||||
vmImage: ubuntu-18.04
|
||||
strategy:
|
||||
matrix:
|
||||
amd64:
|
||||
DOCKER_ARCH: amd64
|
||||
# Do not run the heavy non-amd64 builds for test branches
|
||||
${{ if not(startsWith(variables['Build.SourceBranchName'], 'test-')) }}:
|
||||
arm32v6:
|
||||
DOCKER_ARCH: arm32v6
|
||||
arm64v8:
|
||||
DOCKER_ARCH: arm64v8
|
||||
# The default timeout of 60 minutes is a little low for compiling
|
||||
# cryptography on ARM architectures.
|
||||
timeoutInMinutes: 180
|
||||
steps:
|
||||
- bash: set -e && tools/docker/build.sh $(dockerTag) $DOCKER_ARCH
|
||||
displayName: Build the Docker images
|
||||
# We don't filter for the Docker Hub organization to continue to allow
|
||||
# easy testing of these scripts on forks.
|
||||
- bash: |
|
||||
set -e
|
||||
DOCKER_IMAGES=$(docker images --filter reference='*/certbot' --filter reference='*/dns-*' --format '{{.Repository}}')
|
||||
docker save --output images.tar $DOCKER_IMAGES
|
||||
displayName: Save the Docker images
|
||||
# If the name of the tar file or artifact changes, the deploy stage will
|
||||
# also need to be updated.
|
||||
- bash: set -e && mv images.tar $(Build.ArtifactStagingDirectory)
|
||||
displayName: Prepare Docker artifact
|
||||
- task: PublishPipelineArtifact@1
|
||||
inputs:
|
||||
path: $(Build.ArtifactStagingDirectory)
|
||||
artifact: docker_$(DOCKER_ARCH)
|
||||
displayName: Store Docker artifact
|
||||
- job: docker_run
|
||||
dependsOn: docker_build
|
||||
pool:
|
||||
vmImage: ubuntu-18.04
|
||||
steps:
|
||||
- task: DownloadPipelineArtifact@2
|
||||
inputs:
|
||||
artifact: docker_amd64
|
||||
path: $(Build.SourcesDirectory)
|
||||
displayName: Retrieve Docker images
|
||||
- bash: set -e && docker load --input $(Build.SourcesDirectory)/images.tar
|
||||
displayName: Load Docker images
|
||||
- bash: |
|
||||
set -ex
|
||||
DOCKER_IMAGES=$(docker images --filter reference='*/certbot' --filter reference='*/dns-*' --format '{{.Repository}}:{{.Tag}}')
|
||||
for DOCKER_IMAGE in ${DOCKER_IMAGES}
|
||||
do docker run --rm "${DOCKER_IMAGE}" plugins --prepare
|
||||
done
|
||||
displayName: Run integration tests for Docker images
|
||||
- job: installer_build
|
||||
pool:
|
||||
vmImage: vs2017-win2016
|
||||
steps:
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: 3.8
|
||||
architecture: x86
|
||||
addToPath: true
|
||||
- script: |
|
||||
python -m venv venv
|
||||
venv\Scripts\python tools\pipstrap.py
|
||||
venv\Scripts\python tools\pip_install.py -e windows-installer
|
||||
displayName: Prepare Windows installer build environment
|
||||
- script: |
|
||||
venv\Scripts\construct-windows-installer
|
||||
displayName: Build Certbot installer
|
||||
- task: CopyFiles@2
|
||||
inputs:
|
||||
sourceFolder: $(System.DefaultWorkingDirectory)/windows-installer/build/nsis
|
||||
contents: '*.exe'
|
||||
targetFolder: $(Build.ArtifactStagingDirectory)
|
||||
- task: PublishPipelineArtifact@1
|
||||
inputs:
|
||||
path: $(Build.ArtifactStagingDirectory)
|
||||
# If we change the artifact's name, it should also be changed in tools/create_github_release.py
|
||||
artifact: windows-installer
|
||||
displayName: Publish Windows installer
|
||||
- job: installer_run
|
||||
dependsOn: installer_build
|
||||
strategy:
|
||||
matrix:
|
||||
win2019:
|
||||
imageName: windows-2019
|
||||
win2016:
|
||||
imageName: vs2017-win2016
|
||||
pool:
|
||||
vmImage: $(imageName)
|
||||
steps:
|
||||
- powershell: |
|
||||
if ($PSVersionTable.PSVersion.Major -ne 5) {
|
||||
throw "Powershell version is not 5.x"
|
||||
}
|
||||
condition: eq(variables['imageName'], 'vs2017-win2016')
|
||||
displayName: Check Powershell 5.x is used in vs2017-win2016
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: 3.8
|
||||
addToPath: true
|
||||
- task: DownloadPipelineArtifact@2
|
||||
inputs:
|
||||
artifact: windows-installer
|
||||
path: $(Build.SourcesDirectory)/bin
|
||||
displayName: Retrieve Windows installer
|
||||
- script: |
|
||||
python -m venv venv
|
||||
venv\Scripts\python tools\pipstrap.py
|
||||
venv\Scripts\python tools\pip_install.py -e certbot-ci
|
||||
env:
|
||||
PIP_NO_BUILD_ISOLATION: no
|
||||
displayName: Prepare Certbot-CI
|
||||
- script: |
|
||||
set PATH=%ProgramFiles(x86)%\Certbot\bin;%PATH%
|
||||
venv\Scripts\python -m pytest certbot-ci\windows_installer_integration_tests --allow-persistent-changes --installer-path $(Build.SourcesDirectory)\bin\certbot-beta-installer-win32.exe
|
||||
displayName: Run windows installer integration tests
|
||||
- script: |
|
||||
set PATH=%ProgramFiles(x86)%\Certbot\bin;%PATH%
|
||||
venv\Scripts\python -m pytest certbot-ci\certbot_integration_tests\certbot_tests -n 4
|
||||
displayName: Run certbot integration tests
|
||||
- job: snaps_build
|
||||
pool:
|
||||
vmImage: ubuntu-18.04
|
||||
@@ -169,36 +46,6 @@ jobs:
|
||||
path: $(Build.ArtifactStagingDirectory)
|
||||
artifact: snaps_$(SNAP_ARCH)
|
||||
displayName: Store snaps artifacts
|
||||
- job: snap_run
|
||||
dependsOn: snaps_build
|
||||
pool:
|
||||
vmImage: ubuntu-18.04
|
||||
steps:
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: 3.8
|
||||
addToPath: true
|
||||
- script: |
|
||||
set -e
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends nginx-light snapd
|
||||
python3 -m venv venv
|
||||
venv/bin/python tools/pipstrap.py
|
||||
venv/bin/python tools/pip_install.py -U tox
|
||||
displayName: Install dependencies
|
||||
- task: DownloadPipelineArtifact@2
|
||||
inputs:
|
||||
artifact: snaps_amd64
|
||||
path: $(Build.SourcesDirectory)/snap
|
||||
displayName: Retrieve Certbot snaps
|
||||
- script: |
|
||||
set -e
|
||||
sudo snap install --dangerous --classic snap/certbot_*.snap
|
||||
displayName: Install Certbot snap
|
||||
- script: |
|
||||
set -e
|
||||
venv/bin/python -m tox -e integration-external,apacheconftest-external-with-pebble
|
||||
displayName: Run tox
|
||||
- job: snap_dns_run
|
||||
dependsOn: snaps_build
|
||||
pool:
|
||||
|
||||
@@ -56,6 +56,8 @@ jobs:
|
||||
apache-compat:
|
||||
IMAGE_NAME: ubuntu-18.04
|
||||
TOXENV: apache_compat
|
||||
# le-modification can be moved to the extended test suite once
|
||||
# https://github.com/certbot/certbot/issues/8742 is resolved.
|
||||
le-modification:
|
||||
IMAGE_NAME: ubuntu-18.04
|
||||
TOXENV: modification
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
stages:
|
||||
- stage: TestAndPackage
|
||||
jobs:
|
||||
- template: ../jobs/standard-tests-jobs.yml
|
||||
- template: ../jobs/extended-tests-jobs.yml
|
||||
- template: ../jobs/packaging-jobs.yml
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
steps:
|
||||
# We run brew update because we've seen attempts to install an older version
|
||||
# of a package fail. See
|
||||
# https://github.com/actions/virtual-environments/issues/3165.
|
||||
- bash: |
|
||||
set -e
|
||||
brew update
|
||||
brew install augeas
|
||||
condition: startswith(variables['IMAGE_NAME'], 'macOS')
|
||||
displayName: Install MacOS dependencies
|
||||
|
||||
8
.gitignore
vendored
8
.gitignore
vendored
@@ -4,13 +4,11 @@
|
||||
build/
|
||||
dist*/
|
||||
/venv*/
|
||||
/kgs/
|
||||
/.tox/
|
||||
/releases*/
|
||||
/log*
|
||||
letsencrypt.log
|
||||
certbot.log
|
||||
letsencrypt-auto-source/letsencrypt-auto.sig.lzma.base64
|
||||
poetry.lock
|
||||
|
||||
# coverage
|
||||
@@ -32,12 +30,6 @@ tags
|
||||
# auth --cert-path --chain-path
|
||||
/*.pem
|
||||
|
||||
# letstest
|
||||
tests/letstest/letest-*/
|
||||
tests/letstest/*.pem
|
||||
tests/letstest/venv/
|
||||
tests/letstest/venv3/
|
||||
|
||||
.venv
|
||||
|
||||
# pytest cache
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
[settings]
|
||||
skip_glob=venv*
|
||||
skip=letsencrypt-auto-source
|
||||
force_sort_within_sections=True
|
||||
force_single_line=True
|
||||
order_by_type=False
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# This Dockerfile builds an image for development.
|
||||
FROM debian:buster
|
||||
FROM ubuntu:focal
|
||||
|
||||
# Note: this only exposes the port to other docker containers.
|
||||
EXPOSE 80 443
|
||||
@@ -8,8 +8,9 @@ WORKDIR /opt/certbot/src
|
||||
|
||||
COPY . .
|
||||
RUN apt-get update && \
|
||||
apt-get install apache2 git python3-dev python3-venv gcc libaugeas0 \
|
||||
libssl-dev libffi-dev ca-certificates openssl nginx-light -y && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install apache2 git python3-dev \
|
||||
python3-venv gcc libaugeas0 libssl-dev libffi-dev ca-certificates \
|
||||
openssl nginx-light -y --no-install-recommends && \
|
||||
apt-get clean && \
|
||||
rm -rf /var/lib/apt/lists/* \
|
||||
/tmp/* \
|
||||
|
||||
@@ -30,7 +30,7 @@ class Challenge(jose.TypedJSONObjectWithFields):
|
||||
@classmethod
|
||||
def from_json(cls, jobj):
|
||||
try:
|
||||
return super(Challenge, cls).from_json(jobj)
|
||||
return super().from_json(jobj)
|
||||
except jose.UnrecognizedTypeError as error:
|
||||
logger.debug(error)
|
||||
return UnrecognizedChallenge.from_json(jobj)
|
||||
@@ -58,7 +58,7 @@ class UnrecognizedChallenge(Challenge):
|
||||
"""
|
||||
|
||||
def __init__(self, jobj):
|
||||
super(UnrecognizedChallenge, self).__init__()
|
||||
super().__init__()
|
||||
object.__setattr__(self, "jobj", jobj)
|
||||
|
||||
def to_partial_json(self):
|
||||
@@ -141,7 +141,7 @@ class KeyAuthorizationChallengeResponse(ChallengeResponse):
|
||||
return True
|
||||
|
||||
def to_partial_json(self):
|
||||
jobj = super(KeyAuthorizationChallengeResponse, self).to_partial_json()
|
||||
jobj = super().to_partial_json()
|
||||
jobj.pop('keyAuthorization', None)
|
||||
return jobj
|
||||
|
||||
|
||||
@@ -253,7 +253,7 @@ class Client(ClientBase):
|
||||
if isinstance(directory, str):
|
||||
directory = messages.Directory.from_json(
|
||||
net.get(directory).json())
|
||||
super(Client, self).__init__(directory=directory,
|
||||
super().__init__(directory=directory,
|
||||
net=net, acme_version=1)
|
||||
|
||||
def register(self, new_reg=None):
|
||||
@@ -577,7 +577,7 @@ class ClientV2(ClientBase):
|
||||
:param .messages.Directory directory: Directory Resource
|
||||
:param .ClientNetwork net: Client network.
|
||||
"""
|
||||
super(ClientV2, self).__init__(directory=directory,
|
||||
super().__init__(directory=directory,
|
||||
net=net, acme_version=2)
|
||||
|
||||
def new_account(self, new_account):
|
||||
@@ -627,7 +627,7 @@ class ClientV2(ClientBase):
|
||||
"""
|
||||
# https://github.com/certbot/certbot/issues/6155
|
||||
new_regr = self._get_v2_account(regr)
|
||||
return super(ClientV2, self).update_registration(new_regr, update)
|
||||
return super().update_registration(new_regr, update)
|
||||
|
||||
def _get_v2_account(self, regr):
|
||||
self.net.account = None
|
||||
|
||||
@@ -29,7 +29,7 @@ class NonceError(ClientError):
|
||||
class BadNonce(NonceError):
|
||||
"""Bad nonce error."""
|
||||
def __init__(self, nonce, error, *args):
|
||||
super(BadNonce, self).__init__(*args)
|
||||
super().__init__(*args)
|
||||
self.nonce = nonce
|
||||
self.error = error
|
||||
|
||||
@@ -48,7 +48,7 @@ class MissingNonce(NonceError):
|
||||
|
||||
"""
|
||||
def __init__(self, response, *args):
|
||||
super(MissingNonce, self).__init__(*args)
|
||||
super().__init__(*args)
|
||||
self.response = response
|
||||
|
||||
def __str__(self):
|
||||
@@ -72,7 +72,7 @@ class PollError(ClientError):
|
||||
def __init__(self, exhausted, updated):
|
||||
self.exhausted = exhausted
|
||||
self.updated = updated
|
||||
super(PollError, self).__init__()
|
||||
super().__init__()
|
||||
|
||||
@property
|
||||
def timeout(self):
|
||||
@@ -90,7 +90,7 @@ class ValidationError(Error):
|
||||
"""
|
||||
def __init__(self, failed_authzrs):
|
||||
self.failed_authzrs = failed_authzrs
|
||||
super(ValidationError, self).__init__()
|
||||
super().__init__()
|
||||
|
||||
|
||||
class TimeoutError(Error): # pylint: disable=redefined-builtin
|
||||
@@ -106,7 +106,7 @@ class IssuanceError(Error):
|
||||
:param messages.Error error: The error provided by the server.
|
||||
"""
|
||||
self.error = error
|
||||
super(IssuanceError, self).__init__()
|
||||
super().__init__()
|
||||
|
||||
|
||||
class ConflictError(ClientError):
|
||||
@@ -119,7 +119,7 @@ class ConflictError(ClientError):
|
||||
"""
|
||||
def __init__(self, location):
|
||||
self.location = location
|
||||
super(ConflictError, self).__init__()
|
||||
super().__init__()
|
||||
|
||||
|
||||
class WildcardUnsupportedError(Error):
|
||||
|
||||
@@ -12,7 +12,7 @@ class Fixed(jose.Field):
|
||||
|
||||
def __init__(self, json_name, value):
|
||||
self.value = value
|
||||
super(Fixed, self).__init__(
|
||||
super().__init__(
|
||||
json_name=json_name, default=value, omitempty=False)
|
||||
|
||||
def decode(self, value):
|
||||
@@ -53,7 +53,7 @@ class Resource(jose.Field):
|
||||
|
||||
def __init__(self, resource_type, *args, **kwargs):
|
||||
self.resource_type = resource_type
|
||||
super(Resource, self).__init__(
|
||||
super().__init__(
|
||||
'resource', default=resource_type, *args, **kwargs)
|
||||
|
||||
def decode(self, value):
|
||||
|
||||
@@ -50,7 +50,7 @@ class JWS(jose.JWS):
|
||||
# Per ACME spec, jwk and kid are mutually exclusive, so only include a
|
||||
# jwk field if kid is not provided.
|
||||
include_jwk = kid is None
|
||||
return super(JWS, cls).sign(payload, key=key, alg=alg,
|
||||
return super().sign(payload, key=key, alg=alg,
|
||||
protect=frozenset(['nonce', 'url', 'kid', 'jwk', 'alg']),
|
||||
nonce=nonce, url=url, kid=kid,
|
||||
include_jwk=include_jwk)
|
||||
|
||||
@@ -132,7 +132,7 @@ class _Constant(jose.JSONDeSerializable, Hashable): # type: ignore
|
||||
POSSIBLE_NAMES: Dict[str, '_Constant'] = NotImplemented
|
||||
|
||||
def __init__(self, name):
|
||||
super(_Constant, self).__init__()
|
||||
super().__init__()
|
||||
self.POSSIBLE_NAMES[name] = self # pylint: disable=unsupported-assignment-operation
|
||||
self.name = name
|
||||
|
||||
@@ -201,7 +201,7 @@ class Directory(jose.JSONDeSerializable):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
kwargs = {self._internal_name(k): v for k, v in kwargs.items()}
|
||||
super(Directory.Meta, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
@property
|
||||
def terms_of_service(self):
|
||||
@@ -211,7 +211,7 @@ class Directory(jose.JSONDeSerializable):
|
||||
def __iter__(self):
|
||||
# When iterating over fields, use the external name 'terms_of_service' instead of
|
||||
# the internal '_terms_of_service'.
|
||||
for name in super(Directory.Meta, self).__iter__():
|
||||
for name in super().__iter__():
|
||||
yield name[1:] if name == '_terms_of_service' else name
|
||||
|
||||
def _internal_name(self, name):
|
||||
@@ -357,7 +357,7 @@ class Registration(ResourceBody):
|
||||
if 'contact' in kwargs:
|
||||
# Avoid the __setattr__ used by jose.TypedJSONObjectWithFields
|
||||
object.__setattr__(self, '_add_contact', True)
|
||||
super(Registration, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
def _filter_contact(self, prefix):
|
||||
return tuple(
|
||||
@@ -383,12 +383,12 @@ class Registration(ResourceBody):
|
||||
|
||||
def to_partial_json(self):
|
||||
"""Modify josepy.JSONDeserializable.to_partial_json()"""
|
||||
jobj = super(Registration, self).to_partial_json()
|
||||
jobj = super().to_partial_json()
|
||||
return self._add_contact_if_appropriate(jobj)
|
||||
|
||||
def fields_to_partial_json(self):
|
||||
"""Modify josepy.JSONObjectWithFields.fields_to_partial_json()"""
|
||||
jobj = super(Registration, self).fields_to_partial_json()
|
||||
jobj = super().fields_to_partial_json()
|
||||
return self._add_contact_if_appropriate(jobj)
|
||||
|
||||
@property
|
||||
@@ -460,19 +460,19 @@ class ChallengeBody(ResourceBody):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
kwargs = {self._internal_name(k): v for k, v in kwargs.items()}
|
||||
super(ChallengeBody, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
def encode(self, name):
|
||||
return super(ChallengeBody, self).encode(self._internal_name(name))
|
||||
return super().encode(self._internal_name(name))
|
||||
|
||||
def to_partial_json(self):
|
||||
jobj = super(ChallengeBody, self).to_partial_json()
|
||||
jobj = super().to_partial_json()
|
||||
jobj.update(self.chall.to_partial_json())
|
||||
return jobj
|
||||
|
||||
@classmethod
|
||||
def fields_from_json(cls, jobj):
|
||||
jobj_fields = super(ChallengeBody, cls).fields_from_json(jobj)
|
||||
jobj_fields = super().fields_from_json(jobj)
|
||||
jobj_fields['chall'] = challenges.Challenge.from_json(jobj)
|
||||
return jobj_fields
|
||||
|
||||
@@ -487,7 +487,7 @@ class ChallengeBody(ResourceBody):
|
||||
def __iter__(self):
|
||||
# When iterating over fields, use the external name 'uri' instead of
|
||||
# the internal '_uri'.
|
||||
for name in super(ChallengeBody, self).__iter__():
|
||||
for name in super().__iter__():
|
||||
yield name[1:] if name == '_uri' else name
|
||||
|
||||
def _internal_name(self, name):
|
||||
|
||||
@@ -20,7 +20,7 @@ class VersionedLEACMEMixin:
|
||||
# Required for @property to operate properly. See comment above.
|
||||
object.__setattr__(self, key, value)
|
||||
else:
|
||||
super(VersionedLEACMEMixin, self).__setattr__(key, value) # pragma: no cover
|
||||
super().__setattr__(key, value) # pragma: no cover
|
||||
|
||||
|
||||
class ResourceMixin(VersionedLEACMEMixin):
|
||||
@@ -30,12 +30,12 @@ class ResourceMixin(VersionedLEACMEMixin):
|
||||
"""
|
||||
def to_partial_json(self):
|
||||
"""See josepy.JSONDeserializable.to_partial_json()"""
|
||||
return _safe_jobj_compliance(super(ResourceMixin, self),
|
||||
return _safe_jobj_compliance(super(),
|
||||
'to_partial_json', 'resource')
|
||||
|
||||
def fields_to_partial_json(self):
|
||||
"""See josepy.JSONObjectWithFields.fields_to_partial_json()"""
|
||||
return _safe_jobj_compliance(super(ResourceMixin, self),
|
||||
return _safe_jobj_compliance(super(),
|
||||
'fields_to_partial_json', 'resource')
|
||||
|
||||
|
||||
@@ -46,12 +46,12 @@ class TypeMixin(VersionedLEACMEMixin):
|
||||
"""
|
||||
def to_partial_json(self):
|
||||
"""See josepy.JSONDeserializable.to_partial_json()"""
|
||||
return _safe_jobj_compliance(super(TypeMixin, self),
|
||||
return _safe_jobj_compliance(super(),
|
||||
'to_partial_json', 'type')
|
||||
|
||||
def fields_to_partial_json(self):
|
||||
"""See josepy.JSONObjectWithFields.fields_to_partial_json()"""
|
||||
return _safe_jobj_compliance(super(TypeMixin, self),
|
||||
return _safe_jobj_compliance(super(),
|
||||
'fields_to_partial_json', 'type')
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import sys
|
||||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.14.0.dev0'
|
||||
version = '1.15.0.dev0'
|
||||
|
||||
# Please update tox.ini when modifying dependency version requirements
|
||||
install_requires = [
|
||||
@@ -37,7 +37,7 @@ setup(
|
||||
description='ACME protocol implementation in Python',
|
||||
url='https://github.com/letsencrypt/letsencrypt',
|
||||
author="Certbot Project",
|
||||
author_email='client-dev@letsencrypt.org',
|
||||
author_email='certbot-dev@eff.org',
|
||||
license='Apache License 2.0',
|
||||
python_requires='>=3.6',
|
||||
classifiers=[
|
||||
|
||||
@@ -292,7 +292,7 @@ class TLSALPN01ResponseTest(unittest.TestCase):
|
||||
|
||||
def test_gen_verify_cert_gen_key(self):
|
||||
cert, key = self.response.gen_cert(self.domain)
|
||||
self.assertTrue(isinstance(key, OpenSSL.crypto.PKey))
|
||||
self.assertIsInstance(key, OpenSSL.crypto.PKey)
|
||||
self.assertTrue(self.response.verify_cert(self.domain, cert))
|
||||
|
||||
def test_verify_bad_cert(self):
|
||||
@@ -431,7 +431,7 @@ class DNSTest(unittest.TestCase):
|
||||
mock_gen.return_value = mock.sentinel.validation
|
||||
response = self.msg.gen_response(KEY)
|
||||
from acme.challenges import DNSResponse
|
||||
self.assertTrue(isinstance(response, DNSResponse))
|
||||
self.assertIsInstance(response, DNSResponse)
|
||||
self.assertEqual(response.validation, mock.sentinel.validation)
|
||||
|
||||
def test_validation_domain_name(self):
|
||||
|
||||
@@ -90,7 +90,7 @@ class BackwardsCompatibleClientV2Test(ClientTestBase):
|
||||
"""Tests for acme.client.BackwardsCompatibleClientV2."""
|
||||
|
||||
def setUp(self):
|
||||
super(BackwardsCompatibleClientV2Test, self).setUp()
|
||||
super().setUp()
|
||||
# contains a loaded cert
|
||||
self.certr = messages.CertificateResource(
|
||||
body=messages_test.CERT)
|
||||
@@ -319,7 +319,7 @@ class ClientTest(ClientTestBase):
|
||||
"""Tests for acme.client.Client."""
|
||||
|
||||
def setUp(self):
|
||||
super(ClientTest, self).setUp()
|
||||
super().setUp()
|
||||
|
||||
self.directory = DIRECTORY_V1
|
||||
|
||||
@@ -604,8 +604,8 @@ class ClientTest(ClientTestBase):
|
||||
# make sure that max_attempts is per-authorization, rather
|
||||
# than global
|
||||
max_attempts=max(len(authzrs[0].retries), len(authzrs[1].retries)))
|
||||
self.assertTrue(cert[0] is csr)
|
||||
self.assertTrue(cert[1] is updated_authzrs)
|
||||
self.assertIs(cert[0], csr)
|
||||
self.assertIs(cert[1], updated_authzrs)
|
||||
self.assertEqual(updated_authzrs[0].uri, 'a...')
|
||||
self.assertEqual(updated_authzrs[1].uri, 'b.')
|
||||
self.assertEqual(updated_authzrs[0].times, [
|
||||
@@ -641,7 +641,7 @@ class ClientTest(ClientTestBase):
|
||||
authzr = self.client.deactivate_authorization(self.authzr)
|
||||
self.assertEqual(authzb, authzr.body)
|
||||
self.assertEqual(self.client.net.post.call_count, 1)
|
||||
self.assertTrue(self.authzr.uri in self.net.post.call_args_list[0][0])
|
||||
self.assertIn(self.authzr.uri, self.net.post.call_args_list[0][0])
|
||||
|
||||
def test_check_cert(self):
|
||||
self.response.headers['Location'] = self.certr.uri
|
||||
@@ -700,7 +700,7 @@ class ClientTest(ClientTestBase):
|
||||
|
||||
def test_revocation_payload(self):
|
||||
obj = messages.Revocation(certificate=self.certr.body, reason=self.rsn)
|
||||
self.assertTrue('reason' in obj.to_partial_json().keys())
|
||||
self.assertIn('reason', obj.to_partial_json().keys())
|
||||
self.assertEqual(self.rsn, obj.to_partial_json()['reason'])
|
||||
|
||||
def test_revoke_bad_status_raises_error(self):
|
||||
@@ -716,7 +716,7 @@ class ClientV2Test(ClientTestBase):
|
||||
"""Tests for acme.client.ClientV2."""
|
||||
|
||||
def setUp(self):
|
||||
super(ClientV2Test, self).setUp()
|
||||
super().setUp()
|
||||
|
||||
self.directory = DIRECTORY_V2
|
||||
|
||||
@@ -877,9 +877,9 @@ class ClientV2Test(ClientTestBase):
|
||||
self.response.headers['Location'] = self.regr.uri
|
||||
self.response.json.return_value = self.regr.body.to_json()
|
||||
self.assertEqual(self.regr, self.client.update_registration(self.regr))
|
||||
self.assertNotEqual(self.client.net.account, None)
|
||||
self.assertIsNotNone(self.client.net.account)
|
||||
self.assertEqual(self.client.net.post.call_count, 2)
|
||||
self.assertTrue(DIRECTORY_V2.newAccount in self.net.post.call_args_list[0][0])
|
||||
self.assertIn(DIRECTORY_V2.newAccount, self.net.post.call_args_list[0][0])
|
||||
|
||||
self.response.json.return_value = self.regr.body.update(
|
||||
contact=()).to_json()
|
||||
@@ -943,7 +943,7 @@ class ClientNetworkTest(unittest.TestCase):
|
||||
self.response.links = {}
|
||||
|
||||
def test_init(self):
|
||||
self.assertTrue(self.net.verify_ssl is self.verify_ssl)
|
||||
self.assertIs(self.net.verify_ssl, self.verify_ssl)
|
||||
|
||||
def test_wrap_in_jws(self):
|
||||
# pylint: disable=protected-access
|
||||
@@ -1185,7 +1185,7 @@ class ClientNetworkWithMockedResponseTest(unittest.TestCase):
|
||||
|
||||
def send_request(*args, **kwargs):
|
||||
# pylint: disable=unused-argument,missing-docstring
|
||||
self.assertFalse("new_nonce_url" in kwargs)
|
||||
self.assertNotIn("new_nonce_url", kwargs)
|
||||
method = args[0]
|
||||
uri = args[1]
|
||||
if method == 'HEAD' and uri != "new_nonce_uri":
|
||||
@@ -1330,7 +1330,7 @@ class ClientNetworkSourceAddressBindingTest(unittest.TestCase):
|
||||
from acme.client import ClientNetwork
|
||||
net = ClientNetwork(key=None, alg=None, source_address=self.source_address)
|
||||
for adapter in net.session.adapters.values():
|
||||
self.assertTrue(self.source_address in adapter.source_address)
|
||||
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
|
||||
|
||||
@@ -191,7 +191,7 @@ class RandomSnTest(unittest.TestCase):
|
||||
for _ in range(self.cert_count):
|
||||
cert = gen_ss_cert(self.key, ['dummy'], force_san=True)
|
||||
self.serial_num.append(cert.get_serial_number())
|
||||
self.assertTrue(len(set(self.serial_num)) > 1)
|
||||
self.assertGreater(len(set(self.serial_num)), 1)
|
||||
|
||||
class MakeCSRTest(unittest.TestCase):
|
||||
"""Test for standalone functions."""
|
||||
@@ -206,8 +206,8 @@ class MakeCSRTest(unittest.TestCase):
|
||||
|
||||
def test_make_csr(self):
|
||||
csr_pem = self._call_with_key(["a.example", "b.example"])
|
||||
self.assertTrue(b'--BEGIN CERTIFICATE REQUEST--' in csr_pem)
|
||||
self.assertTrue(b'--END CERTIFICATE REQUEST--' in csr_pem)
|
||||
self.assertIn(b'--BEGIN CERTIFICATE REQUEST--', csr_pem)
|
||||
self.assertIn(b'--END CERTIFICATE REQUEST--', csr_pem)
|
||||
csr = OpenSSL.crypto.load_certificate_request(
|
||||
OpenSSL.crypto.FILETYPE_PEM, csr_pem)
|
||||
# In pyopenssl 0.13 (used with TOXENV=py27-oldest), csr objects don't
|
||||
|
||||
@@ -24,8 +24,8 @@ class MissingNonceTest(unittest.TestCase):
|
||||
self.error = MissingNonce(self.response)
|
||||
|
||||
def test_str(self):
|
||||
self.assertTrue("FOO" in str(self.error))
|
||||
self.assertTrue("{}" in str(self.error))
|
||||
self.assertIn("FOO", str(self.error))
|
||||
self.assertIn("{}", str(self.error))
|
||||
|
||||
|
||||
class PollErrorTest(unittest.TestCase):
|
||||
|
||||
@@ -48,7 +48,7 @@ class JWSTest(unittest.TestCase):
|
||||
self.assertEqual(jws.signature.combined.nonce, self.nonce)
|
||||
self.assertEqual(jws.signature.combined.url, self.url)
|
||||
self.assertEqual(jws.signature.combined.kid, self.kid)
|
||||
self.assertEqual(jws.signature.combined.jwk, None)
|
||||
self.assertIsNone(jws.signature.combined.jwk)
|
||||
# TODO: check that nonce is in protected header
|
||||
|
||||
self.assertEqual(jws, JWS.from_json(jws.to_json()))
|
||||
@@ -58,7 +58,7 @@ class JWSTest(unittest.TestCase):
|
||||
jws = JWS.sign(payload=b'foo', key=self.privkey,
|
||||
alg=jose.RS256, nonce=self.nonce,
|
||||
url=self.url)
|
||||
self.assertEqual(jws.signature.combined.kid, None)
|
||||
self.assertIsNone(jws.signature.combined.kid)
|
||||
self.assertEqual(jws.signature.combined.jwk, self.pubkey)
|
||||
|
||||
|
||||
|
||||
@@ -41,13 +41,13 @@ class ErrorTest(unittest.TestCase):
|
||||
|
||||
def test_description(self):
|
||||
self.assertEqual('The request message was malformed', self.error.description)
|
||||
self.assertTrue(self.error_custom.description is None)
|
||||
self.assertIsNone(self.error_custom.description)
|
||||
|
||||
def test_code(self):
|
||||
from acme.messages import Error
|
||||
self.assertEqual('malformed', self.error.code)
|
||||
self.assertEqual(None, self.error_custom.code)
|
||||
self.assertEqual(None, Error().code)
|
||||
self.assertIsNone(self.error_custom.code)
|
||||
self.assertIsNone(Error().code)
|
||||
|
||||
def test_is_acme_error(self):
|
||||
from acme.messages import is_acme_error, Error
|
||||
@@ -260,10 +260,10 @@ class RegistrationTest(unittest.TestCase):
|
||||
self.assertEqual(empty_new_reg.contact, ())
|
||||
self.assertEqual(new_reg_with_contact.contact, ())
|
||||
|
||||
self.assertTrue('contact' not in empty_new_reg.to_partial_json())
|
||||
self.assertTrue('contact' not in empty_new_reg.fields_to_partial_json())
|
||||
self.assertTrue('contact' in new_reg_with_contact.to_partial_json())
|
||||
self.assertTrue('contact' in new_reg_with_contact.fields_to_partial_json())
|
||||
self.assertNotIn('contact', empty_new_reg.to_partial_json())
|
||||
self.assertNotIn('contact', empty_new_reg.fields_to_partial_json())
|
||||
self.assertIn('contact', new_reg_with_contact.to_partial_json())
|
||||
self.assertIn('contact', new_reg_with_contact.fields_to_partial_json())
|
||||
|
||||
|
||||
class UpdateRegistrationTest(unittest.TestCase):
|
||||
@@ -406,7 +406,7 @@ class AuthorizationResourceTest(unittest.TestCase):
|
||||
authzr = AuthorizationResource(
|
||||
uri=mock.sentinel.uri,
|
||||
body=mock.sentinel.body)
|
||||
self.assertTrue(isinstance(authzr, jose.JSONDeSerializable))
|
||||
self.assertIsInstance(authzr, jose.JSONDeSerializable)
|
||||
|
||||
|
||||
class CertificateRequestTest(unittest.TestCase):
|
||||
@@ -417,7 +417,7 @@ class CertificateRequestTest(unittest.TestCase):
|
||||
self.req = CertificateRequest(csr=CSR)
|
||||
|
||||
def test_json_de_serializable(self):
|
||||
self.assertTrue(isinstance(self.req, jose.JSONDeSerializable))
|
||||
self.assertIsInstance(self.req, jose.JSONDeSerializable)
|
||||
from acme.messages import CertificateRequest
|
||||
self.assertEqual(
|
||||
self.req, CertificateRequest.from_json(self.req.to_json()))
|
||||
@@ -433,7 +433,7 @@ class CertificateResourceTest(unittest.TestCase):
|
||||
cert_chain_uri=mock.sentinel.cert_chain_uri)
|
||||
|
||||
def test_json_de_serializable(self):
|
||||
self.assertTrue(isinstance(self.certr, jose.JSONDeSerializable))
|
||||
self.assertIsInstance(self.certr, jose.JSONDeSerializable)
|
||||
from acme.messages import CertificateResource
|
||||
self.assertEqual(
|
||||
self.certr, CertificateResource.from_json(self.certr.to_json()))
|
||||
|
||||
@@ -15,7 +15,7 @@ class ApacheParserNode(interfaces.ParserNode):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
ancestor, dirty, filepath, metadata = util.parsernode_kwargs(kwargs) # pylint: disable=unused-variable
|
||||
super(ApacheParserNode, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
self.ancestor = ancestor
|
||||
self.filepath = filepath
|
||||
self.dirty = dirty
|
||||
@@ -39,7 +39,7 @@ class ApacheCommentNode(ApacheParserNode):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
comment, kwargs = util.commentnode_kwargs(kwargs) # pylint: disable=unused-variable
|
||||
super(ApacheCommentNode, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
self.comment = comment
|
||||
|
||||
def __eq__(self, other): # pragma: no cover
|
||||
@@ -57,7 +57,7 @@ class ApacheDirectiveNode(ApacheParserNode):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
name, parameters, enabled, kwargs = util.directivenode_kwargs(kwargs)
|
||||
super(ApacheDirectiveNode, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
self.name = name
|
||||
self.parameters = parameters
|
||||
self.enabled = enabled
|
||||
@@ -83,7 +83,7 @@ class ApacheBlockNode(ApacheDirectiveNode):
|
||||
""" apacheconfig implementation of BlockNode interface """
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(ApacheBlockNode, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
self.children: Tuple[ApacheParserNode, ...] = ()
|
||||
|
||||
def __eq__(self, other): # pragma: no cover
|
||||
|
||||
@@ -80,7 +80,7 @@ class AugeasParserNode(interfaces.ParserNode):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
ancestor, dirty, filepath, metadata = util.parsernode_kwargs(kwargs) # pylint: disable=unused-variable
|
||||
super(AugeasParserNode, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
self.ancestor = ancestor
|
||||
self.filepath = filepath
|
||||
self.dirty = dirty
|
||||
@@ -169,7 +169,7 @@ class AugeasCommentNode(AugeasParserNode):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
comment, kwargs = util.commentnode_kwargs(kwargs) # pylint: disable=unused-variable
|
||||
super(AugeasCommentNode, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
# self.comment = comment
|
||||
self.comment = comment
|
||||
|
||||
@@ -188,7 +188,7 @@ class AugeasDirectiveNode(AugeasParserNode):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
name, parameters, enabled, kwargs = util.directivenode_kwargs(kwargs)
|
||||
super(AugeasDirectiveNode, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
self.name = name
|
||||
self.enabled = enabled
|
||||
if parameters:
|
||||
@@ -245,7 +245,7 @@ class AugeasBlockNode(AugeasDirectiveNode):
|
||||
""" Augeas implementation of BlockNode interface """
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(AugeasBlockNode, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
self.children = ()
|
||||
|
||||
def __eq__(self, other):
|
||||
|
||||
@@ -8,10 +8,10 @@ import logging
|
||||
import re
|
||||
import socket
|
||||
import time
|
||||
from typing import cast
|
||||
from typing import DefaultDict
|
||||
from typing import Dict
|
||||
from typing import List
|
||||
from typing import Optional
|
||||
from typing import Set
|
||||
from typing import Union
|
||||
|
||||
@@ -36,6 +36,9 @@ from certbot_apache._internal import dualparser
|
||||
from certbot_apache._internal import http_01
|
||||
from certbot_apache._internal import obj
|
||||
from certbot_apache._internal import parser
|
||||
from certbot_apache._internal.dualparser import DualBlockNode
|
||||
from certbot_apache._internal.obj import VirtualHost
|
||||
from certbot_apache._internal.parser import ApacheParser
|
||||
|
||||
try:
|
||||
import apacheconfig
|
||||
@@ -47,6 +50,47 @@ except ImportError: # pragma: no cover
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class OsOptions:
|
||||
"""
|
||||
Dedicated class to describe the OS specificities (eg. paths, binary names)
|
||||
that the Apache configurator needs to be aware to operate properly.
|
||||
"""
|
||||
def __init__(self,
|
||||
server_root="/etc/apache2",
|
||||
vhost_root="/etc/apache2/sites-available",
|
||||
vhost_files="*",
|
||||
logs_root="/var/log/apache2",
|
||||
ctl="apache2ctl",
|
||||
version_cmd: Optional[List[str]] = None,
|
||||
restart_cmd: Optional[List[str]] = None,
|
||||
restart_cmd_alt: Optional[List[str]] = None,
|
||||
conftest_cmd: Optional[List[str]] = None,
|
||||
enmod: Optional[str] = None,
|
||||
dismod: Optional[str] = None,
|
||||
le_vhost_ext="-le-ssl.conf",
|
||||
handle_modules=False,
|
||||
handle_sites=False,
|
||||
challenge_location="/etc/apache2",
|
||||
apache_bin: Optional[str] = None,
|
||||
):
|
||||
self.server_root = server_root
|
||||
self.vhost_root = vhost_root
|
||||
self.vhost_files = vhost_files
|
||||
self.logs_root = logs_root
|
||||
self.ctl = ctl
|
||||
self.version_cmd = ['apache2ctl', '-v'] if not version_cmd else version_cmd
|
||||
self.restart_cmd = ['apache2ctl', 'graceful'] if not restart_cmd else restart_cmd
|
||||
self.restart_cmd_alt = restart_cmd_alt
|
||||
self.conftest_cmd = ['apache2ctl', 'configtest'] if not conftest_cmd else conftest_cmd
|
||||
self.enmod = enmod
|
||||
self.dismod = dismod
|
||||
self.le_vhost_ext = le_vhost_ext
|
||||
self.handle_modules = handle_modules
|
||||
self.handle_sites = handle_sites
|
||||
self.challenge_location = challenge_location
|
||||
self.bin = apache_bin
|
||||
|
||||
|
||||
# TODO: Augeas sections ie. <VirtualHost>, <IfModule> beginning and closing
|
||||
# tags need to be the same case, otherwise Augeas doesn't recognize them.
|
||||
# This is not able to be completely remedied by regular expressions because
|
||||
@@ -102,27 +146,7 @@ class ApacheConfigurator(common.Installer):
|
||||
" change depending on the operating system Certbot is run on.)"
|
||||
)
|
||||
|
||||
OS_DEFAULTS = dict(
|
||||
server_root="/etc/apache2",
|
||||
vhost_root="/etc/apache2/sites-available",
|
||||
vhost_files="*",
|
||||
logs_root="/var/log/apache2",
|
||||
ctl="apache2ctl",
|
||||
version_cmd=['apache2ctl', '-v'],
|
||||
restart_cmd=['apache2ctl', 'graceful'],
|
||||
conftest_cmd=['apache2ctl', 'configtest'],
|
||||
enmod=None,
|
||||
dismod=None,
|
||||
le_vhost_ext="-le-ssl.conf",
|
||||
handle_modules=False,
|
||||
handle_sites=False,
|
||||
challenge_location="/etc/apache2",
|
||||
bin=None
|
||||
)
|
||||
|
||||
def option(self, key):
|
||||
"""Get a value from options"""
|
||||
return self.options.get(key)
|
||||
OS_DEFAULTS = OsOptions()
|
||||
|
||||
def pick_apache_config(self, warn_on_no_mod_ssl=True):
|
||||
"""
|
||||
@@ -152,14 +176,14 @@ class ApacheConfigurator(common.Installer):
|
||||
for o in opts:
|
||||
# Config options use dashes instead of underscores
|
||||
if self.conf(o.replace("_", "-")) is not None:
|
||||
self.options[o] = self.conf(o.replace("_", "-"))
|
||||
setattr(self.options, o, self.conf(o.replace("_", "-")))
|
||||
else:
|
||||
self.options[o] = self.OS_DEFAULTS[o]
|
||||
setattr(self.options, o, getattr(self.OS_DEFAULTS, o))
|
||||
|
||||
# Special cases
|
||||
cast(List[str], self.options["version_cmd"])[0] = self.option("ctl")
|
||||
cast(List[str], self.options["restart_cmd"])[0] = self.option("ctl")
|
||||
cast(List[str], self.options["conftest_cmd"])[0] = self.option("ctl")
|
||||
self.options.version_cmd[0] = self.options.ctl
|
||||
self.options.restart_cmd[0] = self.options.ctl
|
||||
self.options.conftest_cmd[0] = self.options.ctl
|
||||
|
||||
@classmethod
|
||||
def add_parser_arguments(cls, add):
|
||||
@@ -174,30 +198,30 @@ class ApacheConfigurator(common.Installer):
|
||||
else:
|
||||
# cls.OS_DEFAULTS can be distribution specific, see override classes
|
||||
DEFAULTS = cls.OS_DEFAULTS
|
||||
add("enmod", default=DEFAULTS["enmod"],
|
||||
add("enmod", default=DEFAULTS.enmod,
|
||||
help="Path to the Apache 'a2enmod' binary")
|
||||
add("dismod", default=DEFAULTS["dismod"],
|
||||
add("dismod", default=DEFAULTS.dismod,
|
||||
help="Path to the Apache 'a2dismod' binary")
|
||||
add("le-vhost-ext", default=DEFAULTS["le_vhost_ext"],
|
||||
add("le-vhost-ext", default=DEFAULTS.le_vhost_ext,
|
||||
help="SSL vhost configuration extension")
|
||||
add("server-root", default=DEFAULTS["server_root"],
|
||||
add("server-root", default=DEFAULTS.server_root,
|
||||
help="Apache server root directory")
|
||||
add("vhost-root", default=None,
|
||||
help="Apache server VirtualHost configuration root")
|
||||
add("logs-root", default=DEFAULTS["logs_root"],
|
||||
add("logs-root", default=DEFAULTS.logs_root,
|
||||
help="Apache server logs directory")
|
||||
add("challenge-location",
|
||||
default=DEFAULTS["challenge_location"],
|
||||
default=DEFAULTS.challenge_location,
|
||||
help="Directory path for challenge configuration")
|
||||
add("handle-modules", default=DEFAULTS["handle_modules"],
|
||||
add("handle-modules", default=DEFAULTS.handle_modules,
|
||||
help="Let installer handle enabling required modules for you " +
|
||||
"(Only Ubuntu/Debian currently)")
|
||||
add("handle-sites", default=DEFAULTS["handle_sites"],
|
||||
add("handle-sites", default=DEFAULTS.handle_sites,
|
||||
help="Let installer handle enabling sites for you " +
|
||||
"(Only Ubuntu/Debian currently)")
|
||||
add("ctl", default=DEFAULTS["ctl"],
|
||||
add("ctl", default=DEFAULTS.ctl,
|
||||
help="Full path to Apache control script")
|
||||
add("bin", default=DEFAULTS["bin"],
|
||||
add("bin", default=DEFAULTS.bin,
|
||||
help="Full path to apache2/httpd binary")
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -210,7 +234,7 @@ class ApacheConfigurator(common.Installer):
|
||||
version = kwargs.pop("version", None)
|
||||
use_parsernode = kwargs.pop("use_parsernode", False)
|
||||
openssl_version = kwargs.pop("openssl_version", None)
|
||||
super(ApacheConfigurator, self).__init__(*args, **kwargs)
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
# Add name_server association dict
|
||||
self.assoc: Dict[str, obj.VirtualHost] = {}
|
||||
@@ -232,11 +256,11 @@ class ApacheConfigurator(common.Installer):
|
||||
self.parsed_paths: List[str] = []
|
||||
# These will be set in the prepare function
|
||||
self._prepared = False
|
||||
self.parser = None
|
||||
self.parser_root = None
|
||||
self.parser: ApacheParser
|
||||
self.parser_root: Optional[DualBlockNode] = None
|
||||
self.version = version
|
||||
self._openssl_version = openssl_version
|
||||
self.vhosts = None
|
||||
self.vhosts: List[VirtualHost]
|
||||
self.options = copy.deepcopy(self.OS_DEFAULTS)
|
||||
self._enhance_func = {"redirect": self._enable_redirect,
|
||||
"ensure-http-header": self._set_http_header,
|
||||
@@ -286,8 +310,8 @@ class ApacheConfigurator(common.Installer):
|
||||
ssl_module_location = self.parser.standard_path_from_server_root(ssl_module_location)
|
||||
else:
|
||||
# Possibility B: ssl_module is statically linked into Apache
|
||||
if self.option("bin"):
|
||||
ssl_module_location = self.option("bin")
|
||||
if self.options.bin:
|
||||
ssl_module_location = self.options.bin
|
||||
else:
|
||||
logger.warning("ssl_module is statically linked but --apache-bin is "
|
||||
"missing; not disabling session tickets.")
|
||||
@@ -317,7 +341,7 @@ class ApacheConfigurator(common.Installer):
|
||||
self._prepare_options()
|
||||
|
||||
# Verify Apache is installed
|
||||
self._verify_exe_availability(self.option("ctl"))
|
||||
self._verify_exe_availability(self.options.ctl)
|
||||
|
||||
# Make sure configuration is valid
|
||||
self.config_test()
|
||||
@@ -345,8 +369,9 @@ class ApacheConfigurator(common.Installer):
|
||||
"augeaspath": self.parser.get_root_augpath(),
|
||||
"ac_ast": None}
|
||||
if self.USE_PARSERNODE:
|
||||
self.parser_root = self.get_parsernode_root(pn_meta)
|
||||
self.parsed_paths = self.parser_root.parsed_paths()
|
||||
parser_root = self.get_parsernode_root(pn_meta)
|
||||
self.parser_root = parser_root
|
||||
self.parsed_paths = parser_root.parsed_paths()
|
||||
|
||||
# Check for errors in parsing files with Augeas
|
||||
self.parser.check_parsing_errors("httpd.aug")
|
||||
@@ -356,20 +381,20 @@ class ApacheConfigurator(common.Installer):
|
||||
|
||||
# We may try to enable mod_ssl later. If so, we shouldn't warn if we can't find it now.
|
||||
# This is currently only true for debian/ubuntu.
|
||||
warn_on_no_mod_ssl = not self.option("handle_modules")
|
||||
warn_on_no_mod_ssl = not self.options.handle_modules
|
||||
self.install_ssl_options_conf(self.mod_ssl_conf,
|
||||
self.updated_mod_ssl_conf_digest,
|
||||
warn_on_no_mod_ssl)
|
||||
|
||||
# Prevent two Apache plugins from modifying a config at once
|
||||
try:
|
||||
util.lock_dir_until_exit(self.option("server_root"))
|
||||
util.lock_dir_until_exit(self.options.server_root)
|
||||
except (OSError, errors.LockError):
|
||||
logger.debug("Encountered error:", exc_info=True)
|
||||
raise errors.PluginError(
|
||||
"Unable to create a lock file in {0}. Are you running"
|
||||
" Certbot with sufficient privileges to modify your"
|
||||
" Apache configuration?".format(self.option("server_root")))
|
||||
" Apache configuration?".format(self.options.server_root))
|
||||
self._prepared = True
|
||||
|
||||
def save(self, title=None, temporary=False):
|
||||
@@ -405,10 +430,10 @@ class ApacheConfigurator(common.Installer):
|
||||
:raises .errors.PluginError: If unable to recover the configuration
|
||||
|
||||
"""
|
||||
super(ApacheConfigurator, self).recovery_routine()
|
||||
super().recovery_routine()
|
||||
# Reload configuration after these changes take effect if needed
|
||||
# ie. ApacheParser has been initialized.
|
||||
if self.parser:
|
||||
if hasattr(self, "parser"):
|
||||
# TODO: wrap into non-implementation specific parser interface
|
||||
self.parser.aug.load()
|
||||
|
||||
@@ -430,7 +455,7 @@ class ApacheConfigurator(common.Installer):
|
||||
the function is unable to correctly revert the configuration
|
||||
|
||||
"""
|
||||
super(ApacheConfigurator, self).rollback_checkpoints(rollback)
|
||||
super().rollback_checkpoints(rollback)
|
||||
self.parser.aug.load()
|
||||
|
||||
def _verify_exe_availability(self, exe):
|
||||
@@ -444,7 +469,7 @@ class ApacheConfigurator(common.Installer):
|
||||
"""Initializes the ApacheParser"""
|
||||
# If user provided vhost_root value in command line, use it
|
||||
return parser.ApacheParser(
|
||||
self.option("server_root"), self.conf("vhost-root"),
|
||||
self.options.server_root, self.conf("vhost-root"),
|
||||
self.version, configurator=self)
|
||||
|
||||
def get_parsernode_root(self, metadata):
|
||||
@@ -452,9 +477,9 @@ class ApacheConfigurator(common.Installer):
|
||||
|
||||
if HAS_APACHECONFIG:
|
||||
apache_vars = {}
|
||||
apache_vars["defines"] = apache_util.parse_defines(self.option("ctl"))
|
||||
apache_vars["includes"] = apache_util.parse_includes(self.option("ctl"))
|
||||
apache_vars["modules"] = apache_util.parse_modules(self.option("ctl"))
|
||||
apache_vars["defines"] = apache_util.parse_defines(self.options.ctl)
|
||||
apache_vars["includes"] = apache_util.parse_includes(self.options.ctl)
|
||||
apache_vars["modules"] = apache_util.parse_modules(self.options.ctl)
|
||||
metadata["apache_vars"] = apache_vars
|
||||
|
||||
with open(self.parser.loc["root"]) as f:
|
||||
@@ -1051,6 +1076,9 @@ class ApacheConfigurator(common.Installer):
|
||||
:rtype: list
|
||||
"""
|
||||
|
||||
if not self.parser_root:
|
||||
raise errors.Error("This ApacheConfigurator instance is not" # pragma: no cover
|
||||
" configured to use a node parser.")
|
||||
vhs = []
|
||||
vhosts = self.parser_root.find_blocks("VirtualHost", exclude=False)
|
||||
for vhblock in vhosts:
|
||||
@@ -1303,7 +1331,7 @@ class ApacheConfigurator(common.Installer):
|
||||
:param boolean temp: If the change is temporary
|
||||
"""
|
||||
|
||||
if self.option("handle_modules"):
|
||||
if self.options.handle_modules:
|
||||
if self.version >= (2, 4) and ("socache_shmcb_module" not in
|
||||
self.parser.modules):
|
||||
self.enable_mod("socache_shmcb", temp=temp)
|
||||
@@ -1323,7 +1351,7 @@ class ApacheConfigurator(common.Installer):
|
||||
|
||||
Duplicates vhost and adds default ssl options
|
||||
New vhost will reside as (nonssl_vhost.path) +
|
||||
``self.option("le_vhost_ext")``
|
||||
``self.options.le_vhost_ext``
|
||||
|
||||
.. note:: This function saves the configuration
|
||||
|
||||
@@ -1422,15 +1450,15 @@ class ApacheConfigurator(common.Installer):
|
||||
"""
|
||||
|
||||
if self.conf("vhost-root") and os.path.exists(self.conf("vhost-root")):
|
||||
fp = os.path.join(filesystem.realpath(self.option("vhost_root")),
|
||||
fp = os.path.join(filesystem.realpath(self.options.vhost_root),
|
||||
os.path.basename(non_ssl_vh_fp))
|
||||
else:
|
||||
# Use non-ssl filepath
|
||||
fp = filesystem.realpath(non_ssl_vh_fp)
|
||||
|
||||
if fp.endswith(".conf"):
|
||||
return fp[:-(len(".conf"))] + self.option("le_vhost_ext")
|
||||
return fp + self.option("le_vhost_ext")
|
||||
return fp[:-(len(".conf"))] + self.options.le_vhost_ext
|
||||
return fp + self.options.le_vhost_ext
|
||||
|
||||
def _sift_rewrite_rule(self, line):
|
||||
"""Decides whether a line should be copied to a SSL vhost.
|
||||
@@ -2274,7 +2302,7 @@ class ApacheConfigurator(common.Installer):
|
||||
addr in self._get_proposed_addrs(ssl_vhost)),
|
||||
servername, serveralias,
|
||||
" ".join(rewrite_rule_args),
|
||||
self.option("logs_root")))
|
||||
self.options.logs_root))
|
||||
|
||||
def _write_out_redirect(self, ssl_vhost, text):
|
||||
# This is the default name
|
||||
@@ -2286,7 +2314,7 @@ class ApacheConfigurator(common.Installer):
|
||||
if len(ssl_vhost.name) < (255 - (len(redirect_filename) + 1)):
|
||||
redirect_filename = "le-redirect-%s.conf" % ssl_vhost.name
|
||||
|
||||
redirect_filepath = os.path.join(self.option("vhost_root"),
|
||||
redirect_filepath = os.path.join(self.options.vhost_root,
|
||||
redirect_filename)
|
||||
|
||||
# Register the new file that will be created
|
||||
@@ -2406,19 +2434,18 @@ class ApacheConfigurator(common.Installer):
|
||||
|
||||
"""
|
||||
try:
|
||||
util.run_script(self.option("restart_cmd"))
|
||||
util.run_script(self.options.restart_cmd)
|
||||
except errors.SubprocessError as err:
|
||||
logger.info("Unable to restart apache using %s",
|
||||
self.option("restart_cmd"))
|
||||
alt_restart = self.option("restart_cmd_alt")
|
||||
self.options.restart_cmd)
|
||||
alt_restart = self.options.restart_cmd_alt
|
||||
if alt_restart:
|
||||
logger.debug("Trying alternative restart command: %s",
|
||||
alt_restart)
|
||||
# There is an alternative restart command available
|
||||
# This usually is "restart" verb while original is "graceful"
|
||||
try:
|
||||
util.run_script(self.option(
|
||||
"restart_cmd_alt"))
|
||||
util.run_script(self.options.restart_cmd_alt)
|
||||
return
|
||||
except errors.SubprocessError as secerr:
|
||||
error = str(secerr)
|
||||
@@ -2433,7 +2460,7 @@ class ApacheConfigurator(common.Installer):
|
||||
|
||||
"""
|
||||
try:
|
||||
util.run_script(self.option("conftest_cmd"))
|
||||
util.run_script(self.options.conftest_cmd)
|
||||
except errors.SubprocessError as err:
|
||||
raise errors.MisconfigurationError(str(err))
|
||||
|
||||
@@ -2449,11 +2476,11 @@ class ApacheConfigurator(common.Installer):
|
||||
|
||||
"""
|
||||
try:
|
||||
stdout, _ = util.run_script(self.option("version_cmd"))
|
||||
stdout, _ = util.run_script(self.options.version_cmd)
|
||||
except errors.SubprocessError:
|
||||
raise errors.PluginError(
|
||||
"Unable to run %s -v" %
|
||||
self.option("version_cmd"))
|
||||
self.options.version_cmd)
|
||||
|
||||
regex = re.compile(r"Apache/([0-9\.]*)", re.IGNORECASE)
|
||||
matches = regex.findall(stdout)
|
||||
|
||||
@@ -47,7 +47,7 @@ class ApacheHttp01(common.ChallengePerformer):
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ApacheHttp01, self).__init__(*args, **kwargs)
|
||||
super().__init__(*args, **kwargs)
|
||||
self.challenge_conf_pre = os.path.join(
|
||||
self.configurator.conf("challenge-location"),
|
||||
"le_http_01_challenge_pre.conf")
|
||||
|
||||
@@ -238,7 +238,7 @@ class CommentNode(ParserNode, metaclass=abc.ABCMeta):
|
||||
created or changed after the last save. Default: False.
|
||||
:type dirty: bool
|
||||
"""
|
||||
super(CommentNode, self).__init__(ancestor=kwargs['ancestor'],
|
||||
super().__init__(ancestor=kwargs['ancestor'],
|
||||
dirty=kwargs.get('dirty', False),
|
||||
filepath=kwargs['filepath'],
|
||||
metadata=kwargs.get('metadata', {})) # pragma: no cover
|
||||
@@ -302,7 +302,7 @@ class DirectiveNode(ParserNode, metaclass=abc.ABCMeta):
|
||||
:type enabled: bool
|
||||
|
||||
"""
|
||||
super(DirectiveNode, self).__init__(ancestor=kwargs['ancestor'],
|
||||
super().__init__(ancestor=kwargs['ancestor'],
|
||||
dirty=kwargs.get('dirty', False),
|
||||
filepath=kwargs['filepath'],
|
||||
metadata=kwargs.get('metadata', {})) # pragma: no cover
|
||||
|
||||
@@ -26,7 +26,7 @@ class Addr(common.Addr):
|
||||
def __hash__(self): # pylint: disable=useless-super-delegation
|
||||
# Python 3 requires explicit overridden for __hash__ if __eq__ or
|
||||
# __cmp__ is overridden. See https://bugs.python.org/issue2235
|
||||
return super(Addr, self).__hash__()
|
||||
return super().__hash__()
|
||||
|
||||
def _addr_less_specific(self, addr):
|
||||
"""Returns if addr.get_addr() is more specific than self.get_addr()."""
|
||||
|
||||
@@ -3,13 +3,14 @@ import zope.interface
|
||||
|
||||
from certbot import interfaces
|
||||
from certbot_apache._internal import configurator
|
||||
from certbot_apache._internal.configurator import OsOptions
|
||||
|
||||
|
||||
@zope.interface.provider(interfaces.IPluginFactory)
|
||||
class ArchConfigurator(configurator.ApacheConfigurator):
|
||||
"""Arch Linux specific ApacheConfigurator override class"""
|
||||
|
||||
OS_DEFAULTS = dict(
|
||||
OS_DEFAULTS = OsOptions(
|
||||
server_root="/etc/httpd",
|
||||
vhost_root="/etc/httpd/conf",
|
||||
vhost_files="*.conf",
|
||||
@@ -18,11 +19,5 @@ class ArchConfigurator(configurator.ApacheConfigurator):
|
||||
version_cmd=['apachectl', '-v'],
|
||||
restart_cmd=['apachectl', 'graceful'],
|
||||
conftest_cmd=['apachectl', 'configtest'],
|
||||
enmod=None,
|
||||
dismod=None,
|
||||
le_vhost_ext="-le-ssl.conf",
|
||||
handle_modules=False,
|
||||
handle_sites=False,
|
||||
challenge_location="/etc/httpd/conf",
|
||||
bin=None,
|
||||
)
|
||||
|
||||
@@ -12,6 +12,7 @@ from certbot.errors import MisconfigurationError
|
||||
from certbot_apache._internal import apache_util
|
||||
from certbot_apache._internal import configurator
|
||||
from certbot_apache._internal import parser
|
||||
from certbot_apache._internal.configurator import OsOptions
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -20,7 +21,7 @@ logger = logging.getLogger(__name__)
|
||||
class CentOSConfigurator(configurator.ApacheConfigurator):
|
||||
"""CentOS specific ApacheConfigurator override class"""
|
||||
|
||||
OS_DEFAULTS = dict(
|
||||
OS_DEFAULTS = OsOptions(
|
||||
server_root="/etc/httpd",
|
||||
vhost_root="/etc/httpd/conf.d",
|
||||
vhost_files="*.conf",
|
||||
@@ -30,13 +31,7 @@ class CentOSConfigurator(configurator.ApacheConfigurator):
|
||||
restart_cmd=['apachectl', 'graceful'],
|
||||
restart_cmd_alt=['apachectl', 'restart'],
|
||||
conftest_cmd=['apachectl', 'configtest'],
|
||||
enmod=None,
|
||||
dismod=None,
|
||||
le_vhost_ext="-le-ssl.conf",
|
||||
handle_modules=False,
|
||||
handle_sites=False,
|
||||
challenge_location="/etc/httpd/conf.d",
|
||||
bin=None,
|
||||
)
|
||||
|
||||
def config_test(self):
|
||||
@@ -51,7 +46,7 @@ class CentOSConfigurator(configurator.ApacheConfigurator):
|
||||
fedora = os_info[0].lower() == "fedora"
|
||||
|
||||
try:
|
||||
super(CentOSConfigurator, self).config_test()
|
||||
super().config_test()
|
||||
except errors.MisconfigurationError:
|
||||
if fedora:
|
||||
self._try_restart_fedora()
|
||||
@@ -69,20 +64,22 @@ class CentOSConfigurator(configurator.ApacheConfigurator):
|
||||
raise errors.MisconfigurationError(str(err))
|
||||
|
||||
# Finish with actual config check to see if systemctl restart helped
|
||||
super(CentOSConfigurator, self).config_test()
|
||||
super().config_test()
|
||||
|
||||
def _prepare_options(self):
|
||||
"""
|
||||
Override the options dictionary initialization in order to support
|
||||
alternative restart cmd used in CentOS.
|
||||
"""
|
||||
super(CentOSConfigurator, self)._prepare_options()
|
||||
cast(List[str], self.options["restart_cmd_alt"])[0] = self.option("ctl")
|
||||
super()._prepare_options()
|
||||
if not self.options.restart_cmd_alt: # pragma: no cover
|
||||
raise ValueError("OS option restart_cmd_alt must be set for CentOS.")
|
||||
self.options.restart_cmd_alt[0] = self.options.ctl
|
||||
|
||||
def get_parser(self):
|
||||
"""Initializes the ApacheParser"""
|
||||
return CentOSParser(
|
||||
self.option("server_root"), self.option("vhost_root"),
|
||||
self.options.server_root, self.options.vhost_root,
|
||||
self.version, configurator=self)
|
||||
|
||||
def _deploy_cert(self, *args, **kwargs): # pylint: disable=arguments-differ
|
||||
@@ -91,7 +88,7 @@ class CentOSConfigurator(configurator.ApacheConfigurator):
|
||||
has "LoadModule ssl_module..." before parsing the VirtualHost configuration
|
||||
that was created by Certbot
|
||||
"""
|
||||
super(CentOSConfigurator, self)._deploy_cert(*args, **kwargs)
|
||||
super()._deploy_cert(*args, **kwargs)
|
||||
if self.version < (2, 4, 0):
|
||||
self._deploy_loadmodule_ssl_if_needed()
|
||||
|
||||
@@ -119,8 +116,9 @@ class CentOSConfigurator(configurator.ApacheConfigurator):
|
||||
else:
|
||||
loadmod_args = path_args
|
||||
|
||||
if self.parser.not_modssl_ifmodule(noarg_path): # pylint: disable=no-member
|
||||
if self.parser.loc["default"] in noarg_path:
|
||||
centos_parser: CentOSParser = cast(CentOSParser, self.parser)
|
||||
if centos_parser.not_modssl_ifmodule(noarg_path):
|
||||
if centos_parser.loc["default"] in noarg_path:
|
||||
# LoadModule already in the main configuration file
|
||||
if ("ifmodule/" in noarg_path.lower() or
|
||||
"ifmodule[1]" in noarg_path.lower()):
|
||||
@@ -168,12 +166,12 @@ class CentOSParser(parser.ApacheParser):
|
||||
def __init__(self, *args, **kwargs):
|
||||
# CentOS specific configuration file for Apache
|
||||
self.sysconfig_filep = "/etc/sysconfig/httpd"
|
||||
super(CentOSParser, self).__init__(*args, **kwargs)
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def update_runtime_variables(self):
|
||||
""" Override for update_runtime_variables for custom parsing """
|
||||
# Opportunistic, works if SELinux not enforced
|
||||
super(CentOSParser, self).update_runtime_variables()
|
||||
super().update_runtime_variables()
|
||||
self.parse_sysconfig_var()
|
||||
|
||||
def parse_sysconfig_var(self):
|
||||
|
||||
@@ -3,26 +3,19 @@ import zope.interface
|
||||
|
||||
from certbot import interfaces
|
||||
from certbot_apache._internal import configurator
|
||||
from certbot_apache._internal.configurator import OsOptions
|
||||
|
||||
|
||||
@zope.interface.provider(interfaces.IPluginFactory)
|
||||
class DarwinConfigurator(configurator.ApacheConfigurator):
|
||||
"""macOS specific ApacheConfigurator override class"""
|
||||
|
||||
OS_DEFAULTS = dict(
|
||||
server_root="/etc/apache2",
|
||||
OS_DEFAULTS = OsOptions(
|
||||
vhost_root="/etc/apache2/other",
|
||||
vhost_files="*.conf",
|
||||
logs_root="/var/log/apache2",
|
||||
ctl="apachectl",
|
||||
version_cmd=['apachectl', '-v'],
|
||||
restart_cmd=['apachectl', 'graceful'],
|
||||
conftest_cmd=['apachectl', 'configtest'],
|
||||
enmod=None,
|
||||
dismod=None,
|
||||
le_vhost_ext="-le-ssl.conf",
|
||||
handle_modules=False,
|
||||
handle_sites=False,
|
||||
challenge_location="/etc/apache2/other",
|
||||
bin=None,
|
||||
)
|
||||
|
||||
@@ -10,6 +10,7 @@ from certbot.compat import filesystem
|
||||
from certbot.compat import os
|
||||
from certbot_apache._internal import apache_util
|
||||
from certbot_apache._internal import configurator
|
||||
from certbot_apache._internal.configurator import OsOptions
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -18,22 +19,11 @@ logger = logging.getLogger(__name__)
|
||||
class DebianConfigurator(configurator.ApacheConfigurator):
|
||||
"""Debian specific ApacheConfigurator override class"""
|
||||
|
||||
OS_DEFAULTS = dict(
|
||||
server_root="/etc/apache2",
|
||||
vhost_root="/etc/apache2/sites-available",
|
||||
vhost_files="*",
|
||||
logs_root="/var/log/apache2",
|
||||
ctl="apache2ctl",
|
||||
version_cmd=['apache2ctl', '-v'],
|
||||
restart_cmd=['apache2ctl', 'graceful'],
|
||||
conftest_cmd=['apache2ctl', 'configtest'],
|
||||
OS_DEFAULTS = OsOptions(
|
||||
enmod="a2enmod",
|
||||
dismod="a2dismod",
|
||||
le_vhost_ext="-le-ssl.conf",
|
||||
handle_modules=True,
|
||||
handle_sites=True,
|
||||
challenge_location="/etc/apache2",
|
||||
bin=None,
|
||||
)
|
||||
|
||||
def enable_site(self, vhost):
|
||||
@@ -58,7 +48,7 @@ class DebianConfigurator(configurator.ApacheConfigurator):
|
||||
if not os.path.isdir(os.path.dirname(enabled_path)):
|
||||
# For some reason, sites-enabled / sites-available do not exist
|
||||
# Call the parent method
|
||||
return super(DebianConfigurator, self).enable_site(vhost)
|
||||
return super().enable_site(vhost)
|
||||
self.reverter.register_file_creation(False, enabled_path)
|
||||
try:
|
||||
os.symlink(vhost.filep, enabled_path)
|
||||
@@ -132,11 +122,11 @@ class DebianConfigurator(configurator.ApacheConfigurator):
|
||||
# Generate reversal command.
|
||||
# Try to be safe here... check that we can probably reverse before
|
||||
# applying enmod command
|
||||
if not util.exe_exists(self.option("dismod")):
|
||||
if not util.exe_exists(self.options.dismod):
|
||||
raise errors.MisconfigurationError(
|
||||
"Unable to find a2dismod, please make sure a2enmod and "
|
||||
"a2dismod are configured correctly for certbot.")
|
||||
|
||||
self.reverter.register_undo_command(
|
||||
temp, [self.option("dismod"), "-f", mod_name])
|
||||
util.run_script([self.option("enmod"), mod_name])
|
||||
temp, [self.options.dismod, "-f", mod_name])
|
||||
util.run_script([self.options.enmod, mod_name])
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
""" Distribution specific override class for Fedora 29+ """
|
||||
from typing import cast
|
||||
from typing import List
|
||||
|
||||
import zope.interface
|
||||
|
||||
from certbot import errors
|
||||
@@ -10,13 +7,14 @@ from certbot import util
|
||||
from certbot_apache._internal import apache_util
|
||||
from certbot_apache._internal import configurator
|
||||
from certbot_apache._internal import parser
|
||||
from certbot_apache._internal.configurator import OsOptions
|
||||
|
||||
|
||||
@zope.interface.provider(interfaces.IPluginFactory)
|
||||
class FedoraConfigurator(configurator.ApacheConfigurator):
|
||||
"""Fedora 29+ specific ApacheConfigurator override class"""
|
||||
|
||||
OS_DEFAULTS = dict(
|
||||
OS_DEFAULTS = OsOptions(
|
||||
server_root="/etc/httpd",
|
||||
vhost_root="/etc/httpd/conf.d",
|
||||
vhost_files="*.conf",
|
||||
@@ -26,13 +24,7 @@ class FedoraConfigurator(configurator.ApacheConfigurator):
|
||||
restart_cmd=['apachectl', 'graceful'],
|
||||
restart_cmd_alt=['apachectl', 'restart'],
|
||||
conftest_cmd=['apachectl', 'configtest'],
|
||||
enmod=None,
|
||||
dismod=None,
|
||||
le_vhost_ext="-le-ssl.conf",
|
||||
handle_modules=False,
|
||||
handle_sites=False,
|
||||
challenge_location="/etc/httpd/conf.d",
|
||||
bin=None,
|
||||
)
|
||||
|
||||
def config_test(self):
|
||||
@@ -43,14 +35,14 @@ class FedoraConfigurator(configurator.ApacheConfigurator):
|
||||
during the first (re)start of httpd.
|
||||
"""
|
||||
try:
|
||||
super(FedoraConfigurator, self).config_test()
|
||||
super().config_test()
|
||||
except errors.MisconfigurationError:
|
||||
self._try_restart_fedora()
|
||||
|
||||
def get_parser(self):
|
||||
"""Initializes the ApacheParser"""
|
||||
return FedoraParser(
|
||||
self.option("server_root"), self.option("vhost_root"),
|
||||
self.options.server_root, self.options.vhost_root,
|
||||
self.version, configurator=self)
|
||||
|
||||
def _try_restart_fedora(self):
|
||||
@@ -63,7 +55,7 @@ class FedoraConfigurator(configurator.ApacheConfigurator):
|
||||
raise errors.MisconfigurationError(str(err))
|
||||
|
||||
# Finish with actual config check to see if systemctl restart helped
|
||||
super(FedoraConfigurator, self).config_test()
|
||||
super().config_test()
|
||||
|
||||
def _prepare_options(self):
|
||||
"""
|
||||
@@ -71,10 +63,12 @@ class FedoraConfigurator(configurator.ApacheConfigurator):
|
||||
instead of httpd and so take advantages of this new bash script in newer versions
|
||||
of Fedora to restart httpd.
|
||||
"""
|
||||
super(FedoraConfigurator, self)._prepare_options()
|
||||
cast(List[str], self.options["restart_cmd"])[0] = 'apachectl'
|
||||
cast(List[str], self.options["restart_cmd_alt"])[0] = 'apachectl'
|
||||
cast(List[str], self.options["conftest_cmd"])[0] = 'apachectl'
|
||||
super()._prepare_options()
|
||||
self.options.restart_cmd[0] = 'apachectl'
|
||||
if not self.options.restart_cmd_alt: # pragma: no cover
|
||||
raise ValueError("OS option restart_cmd_alt must be set for Fedora.")
|
||||
self.options.restart_cmd_alt[0] = 'apachectl'
|
||||
self.options.conftest_cmd[0] = 'apachectl'
|
||||
|
||||
|
||||
class FedoraParser(parser.ApacheParser):
|
||||
@@ -82,12 +76,12 @@ class FedoraParser(parser.ApacheParser):
|
||||
def __init__(self, *args, **kwargs):
|
||||
# Fedora 29+ specific configuration file for Apache
|
||||
self.sysconfig_filep = "/etc/sysconfig/httpd"
|
||||
super(FedoraParser, self).__init__(*args, **kwargs)
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def update_runtime_variables(self):
|
||||
""" Override for update_runtime_variables for custom parsing """
|
||||
# Opportunistic, works if SELinux not enforced
|
||||
super(FedoraParser, self).update_runtime_variables()
|
||||
super().update_runtime_variables()
|
||||
self._parse_sysconfig_var()
|
||||
|
||||
def _parse_sysconfig_var(self):
|
||||
|
||||
@@ -1,36 +1,23 @@
|
||||
""" Distribution specific override class for Gentoo Linux """
|
||||
from typing import cast
|
||||
from typing import List
|
||||
|
||||
import zope.interface
|
||||
|
||||
from certbot import interfaces
|
||||
from certbot_apache._internal import apache_util
|
||||
from certbot_apache._internal import configurator
|
||||
from certbot_apache._internal import parser
|
||||
from certbot_apache._internal.configurator import OsOptions
|
||||
|
||||
|
||||
@zope.interface.provider(interfaces.IPluginFactory)
|
||||
class GentooConfigurator(configurator.ApacheConfigurator):
|
||||
"""Gentoo specific ApacheConfigurator override class"""
|
||||
|
||||
OS_DEFAULTS = dict(
|
||||
OS_DEFAULTS = OsOptions(
|
||||
server_root="/etc/apache2",
|
||||
vhost_root="/etc/apache2/vhosts.d",
|
||||
vhost_files="*.conf",
|
||||
logs_root="/var/log/apache2",
|
||||
ctl="apache2ctl",
|
||||
version_cmd=['apache2ctl', '-v'],
|
||||
restart_cmd=['apache2ctl', 'graceful'],
|
||||
restart_cmd_alt=['apache2ctl', 'restart'],
|
||||
conftest_cmd=['apache2ctl', 'configtest'],
|
||||
enmod=None,
|
||||
dismod=None,
|
||||
le_vhost_ext="-le-ssl.conf",
|
||||
handle_modules=False,
|
||||
handle_sites=False,
|
||||
challenge_location="/etc/apache2/vhosts.d",
|
||||
bin=None,
|
||||
)
|
||||
|
||||
def _prepare_options(self):
|
||||
@@ -38,13 +25,15 @@ class GentooConfigurator(configurator.ApacheConfigurator):
|
||||
Override the options dictionary initialization in order to support
|
||||
alternative restart cmd used in Gentoo.
|
||||
"""
|
||||
super(GentooConfigurator, self)._prepare_options()
|
||||
cast(List[str], self.options["restart_cmd_alt"])[0] = self.option("ctl")
|
||||
super()._prepare_options()
|
||||
if not self.options.restart_cmd_alt: # pragma: no cover
|
||||
raise ValueError("OS option restart_cmd_alt must be set for Gentoo.")
|
||||
self.options.restart_cmd_alt[0] = self.options.ctl
|
||||
|
||||
def get_parser(self):
|
||||
"""Initializes the ApacheParser"""
|
||||
return GentooParser(
|
||||
self.option("server_root"), self.option("vhost_root"),
|
||||
self.options.server_root, self.options.vhost_root,
|
||||
self.version, configurator=self)
|
||||
|
||||
|
||||
@@ -53,7 +42,7 @@ class GentooParser(parser.ApacheParser):
|
||||
def __init__(self, *args, **kwargs):
|
||||
# Gentoo specific configuration file for Apache2
|
||||
self.apacheconfig_filep = "/etc/conf.d/apache2"
|
||||
super(GentooParser, self).__init__(*args, **kwargs)
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def update_runtime_variables(self):
|
||||
""" Override for update_runtime_variables for custom parsing """
|
||||
@@ -69,7 +58,7 @@ class GentooParser(parser.ApacheParser):
|
||||
|
||||
def update_modules(self):
|
||||
"""Get loaded modules from httpd process, and add them to DOM"""
|
||||
mod_cmd = [self.configurator.option("ctl"), "modules"]
|
||||
mod_cmd = [self.configurator.options.ctl, "modules"]
|
||||
matches = apache_util.parse_from_subprocess(mod_cmd, r"(.*)_module")
|
||||
for mod in matches:
|
||||
self.add_mod(mod.strip())
|
||||
|
||||
@@ -3,26 +3,21 @@ import zope.interface
|
||||
|
||||
from certbot import interfaces
|
||||
from certbot_apache._internal import configurator
|
||||
from certbot_apache._internal.configurator import OsOptions
|
||||
|
||||
|
||||
@zope.interface.provider(interfaces.IPluginFactory)
|
||||
class OpenSUSEConfigurator(configurator.ApacheConfigurator):
|
||||
"""OpenSUSE specific ApacheConfigurator override class"""
|
||||
|
||||
OS_DEFAULTS = dict(
|
||||
server_root="/etc/apache2",
|
||||
OS_DEFAULTS = OsOptions(
|
||||
vhost_root="/etc/apache2/vhosts.d",
|
||||
vhost_files="*.conf",
|
||||
logs_root="/var/log/apache2",
|
||||
ctl="apachectl",
|
||||
version_cmd=['apachectl', '-v'],
|
||||
restart_cmd=['apachectl', 'graceful'],
|
||||
conftest_cmd=['apachectl', 'configtest'],
|
||||
enmod="a2enmod",
|
||||
dismod="a2dismod",
|
||||
le_vhost_ext="-le-ssl.conf",
|
||||
handle_modules=False,
|
||||
handle_sites=False,
|
||||
challenge_location="/etc/apache2/vhosts.d",
|
||||
bin=None,
|
||||
)
|
||||
|
||||
@@ -5,12 +5,18 @@ import logging
|
||||
import re
|
||||
from typing import Dict
|
||||
from typing import List
|
||||
from typing import Optional
|
||||
|
||||
from certbot import errors
|
||||
from certbot.compat import os
|
||||
from certbot_apache._internal import apache_util
|
||||
from certbot_apache._internal import constants
|
||||
|
||||
try:
|
||||
from augeas import Augeas
|
||||
except ImportError: # pragma: no cover
|
||||
Augeas = None # type: ignore
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -39,8 +45,7 @@ class ApacheParser:
|
||||
self.configurator = configurator
|
||||
|
||||
# Initialize augeas
|
||||
self.aug = None
|
||||
self.init_augeas()
|
||||
self.aug = init_augeas()
|
||||
|
||||
if not self.check_aug_version():
|
||||
raise errors.NotSupportedError(
|
||||
@@ -48,7 +53,7 @@ class ApacheParser:
|
||||
"version 1.2.0 or higher, please make sure you have you have "
|
||||
"those installed.")
|
||||
|
||||
self.modules: Dict[str, str] = {}
|
||||
self.modules: Dict[str, Optional[str]] = {}
|
||||
self.parser_paths: Dict[str, List[str]] = {}
|
||||
self.variables: Dict[str, str] = {}
|
||||
|
||||
@@ -76,30 +81,13 @@ class ApacheParser:
|
||||
# Must also attempt to parse additional virtual host root
|
||||
if vhostroot:
|
||||
self.parse_file(os.path.abspath(vhostroot) + "/" +
|
||||
self.configurator.option("vhost_files"))
|
||||
self.configurator.options.vhost_files)
|
||||
|
||||
# check to see if there were unparsed define statements
|
||||
if version < (2, 4):
|
||||
if self.find_dir("Define", exclude=False):
|
||||
raise errors.PluginError("Error parsing runtime variables")
|
||||
|
||||
def init_augeas(self):
|
||||
""" Initialize the actual Augeas instance """
|
||||
|
||||
try:
|
||||
import augeas
|
||||
except ImportError: # pragma: no cover
|
||||
raise errors.NoInstallationError("Problem in Augeas installation")
|
||||
|
||||
self.aug = augeas.Augeas(
|
||||
# specify a directory to load our preferred lens from
|
||||
loadpath=constants.AUGEAS_LENS_DIR,
|
||||
# Do not save backup (we do it ourselves), do not load
|
||||
# anything by default
|
||||
flags=(augeas.Augeas.NONE |
|
||||
augeas.Augeas.NO_MODL_AUTOLOAD |
|
||||
augeas.Augeas.ENABLE_SPAN))
|
||||
|
||||
def check_parsing_errors(self, lens):
|
||||
"""Verify Augeas can parse all of the lens files.
|
||||
|
||||
@@ -294,7 +282,7 @@ class ApacheParser:
|
||||
def update_defines(self):
|
||||
"""Updates the dictionary of known variables in the configuration"""
|
||||
|
||||
self.variables = apache_util.parse_defines(self.configurator.option("ctl"))
|
||||
self.variables = apache_util.parse_defines(self.configurator.options.ctl)
|
||||
|
||||
def update_includes(self):
|
||||
"""Get includes from httpd process, and add them to DOM if needed"""
|
||||
@@ -304,7 +292,7 @@ class ApacheParser:
|
||||
# configuration files
|
||||
_ = self.find_dir("Include")
|
||||
|
||||
matches = apache_util.parse_includes(self.configurator.option("ctl"))
|
||||
matches = apache_util.parse_includes(self.configurator.options.ctl)
|
||||
if matches:
|
||||
for i in matches:
|
||||
if not self.parsed_in_current(i):
|
||||
@@ -313,7 +301,7 @@ class ApacheParser:
|
||||
def update_modules(self):
|
||||
"""Get loaded modules from httpd process, and add them to DOM"""
|
||||
|
||||
matches = apache_util.parse_modules(self.configurator.option("ctl"))
|
||||
matches = apache_util.parse_modules(self.configurator.options.ctl)
|
||||
for mod in matches:
|
||||
self.add_mod(mod.strip())
|
||||
|
||||
@@ -949,3 +937,19 @@ def get_aug_path(file_path):
|
||||
|
||||
"""
|
||||
return "/files%s" % file_path
|
||||
|
||||
|
||||
def init_augeas() -> Augeas:
|
||||
""" Initialize the actual Augeas instance """
|
||||
|
||||
if not Augeas: # pragma: no cover
|
||||
raise errors.NoInstallationError("Problem in Augeas installation")
|
||||
|
||||
return Augeas(
|
||||
# specify a directory to load our preferred lens from
|
||||
loadpath=constants.AUGEAS_LENS_DIR,
|
||||
# Do not save backup (we do it ourselves), do not load
|
||||
# anything by default
|
||||
flags=(Augeas.NONE |
|
||||
Augeas.NO_MODL_AUTOLOAD |
|
||||
Augeas.ENABLE_SPAN))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.14.0.dev0'
|
||||
version = '1.15.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
@@ -24,7 +24,7 @@ setup(
|
||||
description="Apache plugin for Certbot",
|
||||
url='https://github.com/letsencrypt/letsencrypt',
|
||||
author="Certbot Project",
|
||||
author_email='client-dev@letsencrypt.org',
|
||||
author_email='certbot-dev@eff.org',
|
||||
license='Apache License 2.0',
|
||||
python_requires='>=3.6',
|
||||
classifiers=[
|
||||
|
||||
@@ -29,7 +29,7 @@ class AugeasParserNodeTest(util.ApacheTest): # pylint: disable=too-many-public-
|
||||
"""Test AugeasParserNode using available test configurations"""
|
||||
|
||||
def setUp(self): # pylint: disable=arguments-differ
|
||||
super(AugeasParserNodeTest, self).setUp()
|
||||
super().setUp()
|
||||
|
||||
with mock.patch("certbot_apache._internal.configurator.ApacheConfigurator.get_parsernode_root") as mock_parsernode:
|
||||
mock_parsernode.side_effect = _get_augeasnode_mock(
|
||||
|
||||
@@ -18,7 +18,7 @@ class AutoHSTSTest(util.ApacheTest):
|
||||
# pylint: disable=protected-access
|
||||
|
||||
def setUp(self): # pylint: disable=arguments-differ
|
||||
super(AutoHSTSTest, self).setUp()
|
||||
super().setUp()
|
||||
|
||||
self.config = util.get_apache_configurator(
|
||||
self.config_path, self.vhost_path, self.config_dir, self.work_dir)
|
||||
|
||||
@@ -36,9 +36,9 @@ class CentOS6Tests(util.ApacheTest):
|
||||
test_dir = "centos6_apache/apache"
|
||||
config_root = "centos6_apache/apache/httpd"
|
||||
vhost_root = "centos6_apache/apache/httpd/conf.d"
|
||||
super(CentOS6Tests, self).setUp(test_dir=test_dir,
|
||||
config_root=config_root,
|
||||
vhost_root=vhost_root)
|
||||
super().setUp(test_dir=test_dir,
|
||||
config_root=config_root,
|
||||
vhost_root=vhost_root)
|
||||
|
||||
self.config = util.get_apache_configurator(
|
||||
self.config_path, self.vhost_path, self.config_dir, self.work_dir,
|
||||
|
||||
@@ -41,9 +41,9 @@ class FedoraRestartTest(util.ApacheTest):
|
||||
test_dir = "centos7_apache/apache"
|
||||
config_root = "centos7_apache/apache/httpd"
|
||||
vhost_root = "centos7_apache/apache/httpd/conf.d"
|
||||
super(FedoraRestartTest, self).setUp(test_dir=test_dir,
|
||||
config_root=config_root,
|
||||
vhost_root=vhost_root)
|
||||
super().setUp(test_dir=test_dir,
|
||||
config_root=config_root,
|
||||
vhost_root=vhost_root)
|
||||
self.config = util.get_apache_configurator(
|
||||
self.config_path, self.vhost_path, self.config_dir, self.work_dir,
|
||||
os_info="fedora_old")
|
||||
@@ -96,9 +96,9 @@ class MultipleVhostsTestCentOS(util.ApacheTest):
|
||||
test_dir = "centos7_apache/apache"
|
||||
config_root = "centos7_apache/apache/httpd"
|
||||
vhost_root = "centos7_apache/apache/httpd/conf.d"
|
||||
super(MultipleVhostsTestCentOS, self).setUp(test_dir=test_dir,
|
||||
config_root=config_root,
|
||||
vhost_root=vhost_root)
|
||||
super().setUp(test_dir=test_dir,
|
||||
config_root=config_root,
|
||||
vhost_root=vhost_root)
|
||||
|
||||
self.config = util.get_apache_configurator(
|
||||
self.config_path, self.vhost_path, self.config_dir, self.work_dir,
|
||||
|
||||
@@ -11,7 +11,7 @@ class ComplexParserTest(util.ParserTest):
|
||||
"""Apache Parser Test."""
|
||||
|
||||
def setUp(self): # pylint: disable=arguments-differ
|
||||
super(ComplexParserTest, self).setUp(
|
||||
super().setUp(
|
||||
"complex_parsing", "complex_parsing")
|
||||
|
||||
self.setup_variables()
|
||||
|
||||
@@ -16,7 +16,7 @@ class ConfiguratorReverterTest(util.ApacheTest):
|
||||
|
||||
|
||||
def setUp(self): # pylint: disable=arguments-differ
|
||||
super(ConfiguratorReverterTest, self).setUp()
|
||||
super().setUp()
|
||||
|
||||
self.config = util.get_apache_configurator(
|
||||
self.config_path, self.vhost_path, self.config_dir, self.work_dir)
|
||||
|
||||
@@ -30,7 +30,7 @@ class MultipleVhostsTest(util.ApacheTest):
|
||||
"""Test two standard well-configured HTTP vhosts."""
|
||||
|
||||
def setUp(self): # pylint: disable=arguments-differ
|
||||
super(MultipleVhostsTest, self).setUp()
|
||||
super().setUp()
|
||||
|
||||
self.config = util.get_apache_configurator(
|
||||
self.config_path, self.vhost_path, self.config_dir, self.work_dir)
|
||||
@@ -103,9 +103,9 @@ class MultipleVhostsTest(util.ApacheTest):
|
||||
"handle_modules", "handle_sites", "ctl"]
|
||||
exp = {}
|
||||
|
||||
for k in ApacheConfigurator.OS_DEFAULTS:
|
||||
for k in ApacheConfigurator.OS_DEFAULTS.__dict__.keys():
|
||||
if k in parserargs:
|
||||
exp[k.replace("_", "-")] = ApacheConfigurator.OS_DEFAULTS[k]
|
||||
exp[k.replace("_", "-")] = getattr(ApacheConfigurator.OS_DEFAULTS, k)
|
||||
# Special cases
|
||||
exp["vhost-root"] = None
|
||||
|
||||
@@ -128,14 +128,13 @@ class MultipleVhostsTest(util.ApacheTest):
|
||||
def test_all_configurators_defaults_defined(self):
|
||||
from certbot_apache._internal.entrypoint import OVERRIDE_CLASSES
|
||||
from certbot_apache._internal.configurator import ApacheConfigurator
|
||||
parameters = set(ApacheConfigurator.OS_DEFAULTS.keys())
|
||||
parameters = set(ApacheConfigurator.OS_DEFAULTS.__dict__.keys())
|
||||
for cls in OVERRIDE_CLASSES.values():
|
||||
self.assertTrue(parameters.issubset(set(cls.OS_DEFAULTS.keys())))
|
||||
self.assertTrue(parameters.issubset(set(cls.OS_DEFAULTS.__dict__.keys())))
|
||||
|
||||
def test_constant(self):
|
||||
self.assertTrue("debian_apache_2_4/multiple_vhosts/apache" in
|
||||
self.config.option("server_root"))
|
||||
self.assertEqual(self.config.option("nonexistent"), None)
|
||||
self.config.options.server_root)
|
||||
|
||||
@certbot_util.patch_get_utility()
|
||||
def test_get_all_names(self, mock_getutility):
|
||||
@@ -1477,9 +1476,9 @@ class AugeasVhostsTest(util.ApacheTest):
|
||||
td = "debian_apache_2_4/augeas_vhosts"
|
||||
cr = "debian_apache_2_4/augeas_vhosts/apache2"
|
||||
vr = "debian_apache_2_4/augeas_vhosts/apache2/sites-available"
|
||||
super(AugeasVhostsTest, self).setUp(test_dir=td,
|
||||
config_root=cr,
|
||||
vhost_root=vr)
|
||||
super().setUp(test_dir=td,
|
||||
config_root=cr,
|
||||
vhost_root=vr)
|
||||
|
||||
self.config = util.get_apache_configurator(
|
||||
self.config_path, self.vhost_path, self.config_dir,
|
||||
@@ -1556,9 +1555,9 @@ class MultiVhostsTest(util.ApacheTest):
|
||||
td = "debian_apache_2_4/multi_vhosts"
|
||||
cr = "debian_apache_2_4/multi_vhosts/apache2"
|
||||
vr = "debian_apache_2_4/multi_vhosts/apache2/sites-available"
|
||||
super(MultiVhostsTest, self).setUp(test_dir=td,
|
||||
config_root=cr,
|
||||
vhost_root=vr)
|
||||
super().setUp(test_dir=td,
|
||||
config_root=cr,
|
||||
vhost_root=vr)
|
||||
|
||||
self.config = util.get_apache_configurator(
|
||||
self.config_path, self.vhost_path,
|
||||
@@ -1661,7 +1660,7 @@ class InstallSslOptionsConfTest(util.ApacheTest):
|
||||
"""Test that the options-ssl-nginx.conf file is installed and updated properly."""
|
||||
|
||||
def setUp(self): # pylint: disable=arguments-differ
|
||||
super(InstallSslOptionsConfTest, self).setUp()
|
||||
super().setUp()
|
||||
|
||||
self.config = util.get_apache_configurator(
|
||||
self.config_path, self.vhost_path, self.config_dir, self.work_dir)
|
||||
@@ -1774,7 +1773,7 @@ class InstallSslOptionsConfTest(util.ApacheTest):
|
||||
# ssl_module statically linked
|
||||
self.config._openssl_version = None
|
||||
self.config.parser.modules['ssl_module'] = None
|
||||
self.config.options['bin'] = '/fake/path/to/httpd'
|
||||
self.config.options.bin = '/fake/path/to/httpd'
|
||||
with mock.patch("certbot_apache._internal.configurator."
|
||||
"ApacheConfigurator._open_module_file") as mock_omf:
|
||||
mock_omf.return_value = some_string_contents
|
||||
@@ -1810,7 +1809,7 @@ class InstallSslOptionsConfTest(util.ApacheTest):
|
||||
|
||||
# When ssl_module is statically linked but --apache-bin not provided
|
||||
self.config._openssl_version = None
|
||||
self.config.options['bin'] = None
|
||||
self.config.options.bin = None
|
||||
self.config.parser.modules['ssl_module'] = None
|
||||
with mock.patch("certbot_apache._internal.configurator.logger.warning") as mock_log:
|
||||
self.assertEqual(self.config.openssl_version(), None)
|
||||
|
||||
@@ -20,7 +20,7 @@ class MultipleVhostsTestDebian(util.ApacheTest):
|
||||
_multiprocess_can_split_ = True
|
||||
|
||||
def setUp(self): # pylint: disable=arguments-differ
|
||||
super(MultipleVhostsTestDebian, self).setUp()
|
||||
super().setUp()
|
||||
self.config = util.get_apache_configurator(
|
||||
self.config_path, self.vhost_path, self.config_dir, self.work_dir,
|
||||
os_info="debian")
|
||||
|
||||
@@ -46,9 +46,9 @@ class FedoraRestartTest(util.ApacheTest):
|
||||
test_dir = "centos7_apache/apache"
|
||||
config_root = "centos7_apache/apache/httpd"
|
||||
vhost_root = "centos7_apache/apache/httpd/conf.d"
|
||||
super(FedoraRestartTest, self).setUp(test_dir=test_dir,
|
||||
config_root=config_root,
|
||||
vhost_root=vhost_root)
|
||||
super().setUp(test_dir=test_dir,
|
||||
config_root=config_root,
|
||||
vhost_root=vhost_root)
|
||||
self.config = util.get_apache_configurator(
|
||||
self.config_path, self.vhost_path, self.config_dir, self.work_dir,
|
||||
os_info="fedora")
|
||||
@@ -90,9 +90,9 @@ class MultipleVhostsTestFedora(util.ApacheTest):
|
||||
test_dir = "centos7_apache/apache"
|
||||
config_root = "centos7_apache/apache/httpd"
|
||||
vhost_root = "centos7_apache/apache/httpd/conf.d"
|
||||
super(MultipleVhostsTestFedora, self).setUp(test_dir=test_dir,
|
||||
config_root=config_root,
|
||||
vhost_root=vhost_root)
|
||||
super().setUp(test_dir=test_dir,
|
||||
config_root=config_root,
|
||||
vhost_root=vhost_root)
|
||||
|
||||
self.config = util.get_apache_configurator(
|
||||
self.config_path, self.vhost_path, self.config_dir, self.work_dir,
|
||||
|
||||
@@ -50,9 +50,9 @@ class MultipleVhostsTestGentoo(util.ApacheTest):
|
||||
test_dir = "gentoo_apache/apache"
|
||||
config_root = "gentoo_apache/apache/apache2"
|
||||
vhost_root = "gentoo_apache/apache/apache2/vhosts.d"
|
||||
super(MultipleVhostsTestGentoo, self).setUp(test_dir=test_dir,
|
||||
config_root=config_root,
|
||||
vhost_root=vhost_root)
|
||||
super().setUp(test_dir=test_dir,
|
||||
config_root=config_root,
|
||||
vhost_root=vhost_root)
|
||||
|
||||
# pylint: disable=line-too-long
|
||||
with mock.patch("certbot_apache._internal.override_gentoo.GentooParser.update_runtime_variables"):
|
||||
|
||||
@@ -24,7 +24,7 @@ class ApacheHttp01Test(util.ApacheTest):
|
||||
"""Test for certbot_apache._internal.http_01.ApacheHttp01."""
|
||||
|
||||
def setUp(self, *args, **kwargs): # pylint: disable=arguments-differ
|
||||
super(ApacheHttp01Test, self).setUp(*args, **kwargs)
|
||||
super().setUp(*args, **kwargs)
|
||||
|
||||
self.account_key = self.rsa512jwk
|
||||
self.achalls: List[achallenges.KeyAuthorizationAnnotatedChallenge] = []
|
||||
|
||||
@@ -16,7 +16,7 @@ class BasicParserTest(util.ParserTest):
|
||||
"""Apache Parser Test."""
|
||||
|
||||
def setUp(self): # pylint: disable=arguments-differ
|
||||
super(BasicParserTest, self).setUp()
|
||||
super().setUp()
|
||||
|
||||
def tearDown(self):
|
||||
shutil.rmtree(self.temp_dir)
|
||||
@@ -305,11 +305,9 @@ class BasicParserTest(util.ParserTest):
|
||||
self.assertRaises(
|
||||
errors.PluginError, self.parser.update_runtime_variables)
|
||||
|
||||
@mock.patch("certbot_apache._internal.configurator.ApacheConfigurator.option")
|
||||
@mock.patch("certbot_apache._internal.apache_util.subprocess.Popen")
|
||||
def test_update_runtime_vars_bad_ctl(self, mock_popen, mock_opt):
|
||||
def test_update_runtime_vars_bad_ctl(self, mock_popen):
|
||||
mock_popen.side_effect = OSError
|
||||
mock_opt.return_value = "nonexistent"
|
||||
self.assertRaises(
|
||||
errors.MisconfigurationError,
|
||||
self.parser.update_runtime_variables)
|
||||
@@ -332,14 +330,14 @@ class BasicParserTest(util.ParserTest):
|
||||
|
||||
class ParserInitTest(util.ApacheTest):
|
||||
def setUp(self): # pylint: disable=arguments-differ
|
||||
super(ParserInitTest, self).setUp()
|
||||
super().setUp()
|
||||
|
||||
def tearDown(self):
|
||||
shutil.rmtree(self.temp_dir)
|
||||
shutil.rmtree(self.config_dir)
|
||||
shutil.rmtree(self.work_dir)
|
||||
|
||||
@mock.patch("certbot_apache._internal.parser.ApacheParser.init_augeas")
|
||||
@mock.patch("certbot_apache._internal.parser.init_augeas")
|
||||
def test_prepare_no_augeas(self, mock_init_augeas):
|
||||
from certbot_apache._internal.parser import ApacheParser
|
||||
mock_init_augeas.side_effect = errors.NoInstallationError
|
||||
|
||||
@@ -20,7 +20,7 @@ class ConfiguratorParserNodeTest(util.ApacheTest): # pylint: disable=too-many-p
|
||||
"""Test AugeasParserNode using available test configurations"""
|
||||
|
||||
def setUp(self): # pylint: disable=arguments-differ
|
||||
super(ConfiguratorParserNodeTest, self).setUp()
|
||||
super().setUp()
|
||||
|
||||
self.config = util.get_apache_configurator(
|
||||
self.config_path, self.vhost_path, self.config_dir,
|
||||
|
||||
@@ -18,7 +18,7 @@ class DummyParserNode(interfaces.ParserNode):
|
||||
self.dirty = dirty
|
||||
self.filepath = filepath
|
||||
self.metadata = metadata
|
||||
super(DummyParserNode, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
def save(self, msg): # pragma: no cover
|
||||
"""Save"""
|
||||
@@ -38,7 +38,7 @@ class DummyCommentNode(DummyParserNode):
|
||||
"""
|
||||
comment, kwargs = util.commentnode_kwargs(kwargs)
|
||||
self.comment = comment
|
||||
super(DummyCommentNode, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
|
||||
class DummyDirectiveNode(DummyParserNode):
|
||||
@@ -54,7 +54,7 @@ class DummyDirectiveNode(DummyParserNode):
|
||||
self.parameters = parameters
|
||||
self.enabled = enabled
|
||||
|
||||
super(DummyDirectiveNode, self).__init__(**kwargs)
|
||||
super().__init__(**kwargs)
|
||||
|
||||
def set_parameters(self, parameters): # pragma: no cover
|
||||
"""Set parameters"""
|
||||
|
||||
@@ -67,7 +67,7 @@ class ParserTest(ApacheTest):
|
||||
def setUp(self, test_dir="debian_apache_2_4/multiple_vhosts",
|
||||
config_root="debian_apache_2_4/multiple_vhosts/apache2",
|
||||
vhost_root="debian_apache_2_4/multiple_vhosts/apache2/sites-available"):
|
||||
super(ParserTest, self).setUp(test_dir, config_root, vhost_root)
|
||||
super().setUp(test_dir, config_root, vhost_root)
|
||||
|
||||
zope.component.provideUtility(display_util.FileDisplay(sys.stdout,
|
||||
False))
|
||||
@@ -123,11 +123,11 @@ def get_apache_configurator(
|
||||
version=version, use_parsernode=use_parsernode,
|
||||
openssl_version=openssl_version)
|
||||
if not conf_vhost_path:
|
||||
config_class.OS_DEFAULTS["vhost_root"] = vhost_path
|
||||
config_class.OS_DEFAULTS.vhost_root = vhost_path
|
||||
else:
|
||||
# Custom virtualhost path was requested
|
||||
config.config.apache_vhost_root = conf_vhost_path
|
||||
config.config.apache_ctl = config_class.OS_DEFAULTS["ctl"]
|
||||
config.config.apache_ctl = config_class.OS_DEFAULTS.ctl
|
||||
config.prepare()
|
||||
return config
|
||||
|
||||
|
||||
27
certbot-auto
27
certbot-auto
@@ -31,7 +31,7 @@ if [ -z "$VENV_PATH" ]; then
|
||||
fi
|
||||
VENV_BIN="$VENV_PATH/bin"
|
||||
BOOTSTRAP_VERSION_PATH="$VENV_PATH/certbot-auto-bootstrap-version.txt"
|
||||
LE_AUTO_VERSION="1.13.0"
|
||||
LE_AUTO_VERSION="1.14.0"
|
||||
BASENAME=$(basename $0)
|
||||
USAGE="Usage: $BASENAME [OPTIONS]
|
||||
A self-updating wrapper script for the Certbot ACME client. When run, updates
|
||||
@@ -800,6 +800,7 @@ BootstrapMageiaCommon() {
|
||||
# packages BOOTSTRAP_VERSION is not set.
|
||||
if [ -f /etc/debian_version ]; then
|
||||
DEPRECATED_OS=1
|
||||
NO_SELF_UPGRADE=1
|
||||
elif [ -f /etc/mageia-release ]; then
|
||||
# Mageia has both /etc/mageia-release and /etc/redhat-release
|
||||
DEPRECATED_OS=1
|
||||
@@ -1488,18 +1489,18 @@ letsencrypt==0.7.0 \
|
||||
--hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \
|
||||
--hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9
|
||||
|
||||
certbot==1.13.0 \
|
||||
--hash=sha256:082eb732e1318bb9605afa7aea8db2c2f4c5029d523c73f24c6aa98f03caff76 \
|
||||
--hash=sha256:64cf41b57df7667d9d849fcaa9031a4f151788246733d1f4c3f37a5aa5e2f458
|
||||
acme==1.13.0 \
|
||||
--hash=sha256:93b6365c9425de03497a6b8aee1107814501d2974499b42e9bcc9a7378771143 \
|
||||
--hash=sha256:6b4257dfd6a6d5f01e8cd4f0b10422c17836bed7c67e9c5b0a0ad6c7d651c088
|
||||
certbot-apache==1.13.0 \
|
||||
--hash=sha256:36ed02ac7d2d91febee8dd3181ae9095b3f06434c9ed8959fbc6db24ab4da2e8 \
|
||||
--hash=sha256:4b5a16e80c1418e2edc05fc2578f522fb24974b2c13eb747cdfeef69e5bd5ae1
|
||||
certbot-nginx==1.13.0 \
|
||||
--hash=sha256:3ff271f65321b25c77a868af21f76f58754a7d61529ad565a1d66e29c711120f \
|
||||
--hash=sha256:9e972cc19c0fa9e5b7863da0423b156fbfb5623fd30b558fd2fd6d21c24c0b08
|
||||
certbot==1.14.0 \
|
||||
--hash=sha256:67b4d26ceaea6c7f8325d0d45169e7a165a2cabc7122c84bc971ba068ca19cca \
|
||||
--hash=sha256:959ea90c6bb8dca38eab9772722cb940972ef6afcd5f15deef08b3c3636841eb
|
||||
acme==1.14.0 \
|
||||
--hash=sha256:4f48c41261202f1a389ec2986b2580b58f53e0d5a1ae2463b34318d78b87fc66 \
|
||||
--hash=sha256:61daccfb0343628cbbca551a7fc4c82482113952c21db3fe0c585b7c98fa1c35
|
||||
certbot-apache==1.14.0 \
|
||||
--hash=sha256:b757038db23db707c44630fecb46e99172bd791f0db5a8e623c0842613c4d3d9 \
|
||||
--hash=sha256:887fe4a21af2de1e5c2c9428bacba6eb7c1219257bc70f1a1d8447c8a321adb0
|
||||
certbot-nginx==1.14.0 \
|
||||
--hash=sha256:8916a815437988d6c192df9f035bb7a176eab20eee0956677b335d0698d243fb \
|
||||
--hash=sha256:cc2a8a0de56d9bb6b2efbda6c80c647dad8db2bb90675cac03ade94bd5fc8597
|
||||
|
||||
UNLIKELY_EOF
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
@@ -11,7 +11,7 @@ from certbot_integration_tests.utils import misc
|
||||
class IntegrationTestsContext(certbot_context.IntegrationTestsContext):
|
||||
"""General fixture describing a certbot-nginx integration tests context"""
|
||||
def __init__(self, request):
|
||||
super(IntegrationTestsContext, self).__init__(request)
|
||||
super().__init__(request)
|
||||
|
||||
self.nginx_root = os.path.join(self.workspace, 'nginx')
|
||||
os.mkdir(self.nginx_root)
|
||||
@@ -29,7 +29,7 @@ class IntegrationTestsContext(certbot_context.IntegrationTestsContext):
|
||||
|
||||
def cleanup(self):
|
||||
self._stop_nginx()
|
||||
super(IntegrationTestsContext, self).cleanup()
|
||||
super().cleanup()
|
||||
|
||||
def certbot_test_nginx(self, args):
|
||||
"""
|
||||
|
||||
@@ -13,11 +13,10 @@ from certbot_integration_tests.utils import certbot_call
|
||||
class IntegrationTestsContext(certbot_context.IntegrationTestsContext):
|
||||
"""Integration test context for certbot-dns-rfc2136"""
|
||||
def __init__(self, request):
|
||||
super(IntegrationTestsContext, self).__init__(request)
|
||||
super().__init__(request)
|
||||
|
||||
self.request = request
|
||||
|
||||
self._dns_xdist = None
|
||||
if hasattr(request.config, 'workerinput'): # Worker node
|
||||
self._dns_xdist = request.config.workerinput['dns_xdist']
|
||||
else: # Primary node
|
||||
@@ -45,7 +44,6 @@ class IntegrationTestsContext(certbot_context.IntegrationTestsContext):
|
||||
src_file = resource_filename('certbot_integration_tests',
|
||||
'assets/bind-config/rfc2136-credentials-{}.ini.tpl'
|
||||
.format(label))
|
||||
contents = None
|
||||
|
||||
with open(src_file, 'r') as f:
|
||||
contents = f.read().format(
|
||||
|
||||
@@ -8,6 +8,7 @@ import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import time
|
||||
from typing import Optional
|
||||
|
||||
from pkg_resources import resource_filename
|
||||
|
||||
@@ -38,7 +39,7 @@ class DNSServer:
|
||||
|
||||
self.bind_root = tempfile.mkdtemp()
|
||||
|
||||
self.process: subprocess.Popen = None
|
||||
self.process: Optional[subprocess.Popen] = None
|
||||
|
||||
self.dns_xdist = {"address": BIND_BIND_ADDRESS[0], "port": BIND_BIND_ADDRESS[1]}
|
||||
|
||||
@@ -119,6 +120,9 @@ class DNSServer:
|
||||
but otherwise the contents are ignored.
|
||||
:param int attempts: The number of attempts to make.
|
||||
"""
|
||||
if not self.process:
|
||||
raise ValueError("DNS server has not been started. Please run start() first.")
|
||||
|
||||
for _ in range(attempts):
|
||||
if self.process.poll():
|
||||
raise ValueError("BIND9 server stopped unexpectedly")
|
||||
|
||||
@@ -38,7 +38,7 @@ setup(
|
||||
description="Certbot continuous integration framework",
|
||||
url='https://github.com/certbot/certbot',
|
||||
author="Certbot Project",
|
||||
author_email='client-dev@letsencrypt.org',
|
||||
author_email='certbot-dev@eff.org',
|
||||
license='Apache License 2.0',
|
||||
python_requires='>=3.6',
|
||||
classifiers=[
|
||||
|
||||
@@ -44,4 +44,4 @@ def test_dns_plugin_install(dns_snap_path):
|
||||
'certbot:certbot-metadata'])
|
||||
subprocess.check_call(['snap', 'install', '--dangerous', dns_snap_path])
|
||||
finally:
|
||||
subprocess.call(['snap', 'remove', 'plugin_name'])
|
||||
subprocess.call(['snap', 'remove', plugin_name])
|
||||
|
||||
@@ -22,7 +22,7 @@ class Proxy(configurators_common.Proxy):
|
||||
|
||||
def __init__(self, args):
|
||||
"""Initializes the plugin with the given command line args"""
|
||||
super(Proxy, self).__init__(args)
|
||||
super().__init__(args)
|
||||
self.le_config.apache_le_vhost_ext = "-le-ssl.conf"
|
||||
|
||||
self.modules = self.server_root = self.test_conf = self.version = None
|
||||
@@ -34,7 +34,7 @@ class Proxy(configurators_common.Proxy):
|
||||
|
||||
def load_config(self):
|
||||
"""Loads the next configuration for the plugin to test"""
|
||||
config = super(Proxy, self).load_config()
|
||||
config = super().load_config()
|
||||
self._all_names, self._test_names = _get_names(config)
|
||||
|
||||
server_root = _get_server_root(config)
|
||||
@@ -54,9 +54,9 @@ class Proxy(configurators_common.Proxy):
|
||||
|
||||
def _prepare_configurator(self):
|
||||
"""Prepares the Apache plugin for testing"""
|
||||
for k in entrypoint.ENTRYPOINT.OS_DEFAULTS:
|
||||
for k in entrypoint.ENTRYPOINT.OS_DEFAULTS.__dict__.keys():
|
||||
setattr(self.le_config, "apache_" + k,
|
||||
entrypoint.ENTRYPOINT.OS_DEFAULTS[k])
|
||||
getattr(entrypoint.ENTRYPOINT.OS_DEFAULTS, k))
|
||||
|
||||
self._configurator = entrypoint.ENTRYPOINT(
|
||||
config=configuration.NamespaceConfig(self.le_config),
|
||||
@@ -65,7 +65,7 @@ class Proxy(configurators_common.Proxy):
|
||||
|
||||
def cleanup_from_tests(self):
|
||||
"""Performs any necessary cleanup from running plugin tests"""
|
||||
super(Proxy, self).cleanup_from_tests()
|
||||
super().cleanup_from_tests()
|
||||
mock.patch.stopall()
|
||||
|
||||
|
||||
|
||||
@@ -33,7 +33,9 @@ class Proxy:
|
||||
self.args = args
|
||||
self.http_port = 80
|
||||
self.https_port = 443
|
||||
self._configurator = self._all_names = self._test_names = None
|
||||
self._configurator = None
|
||||
self._all_names = None
|
||||
self._test_names = None
|
||||
|
||||
def __getattr__(self, name):
|
||||
"""Wraps the configurator methods"""
|
||||
@@ -93,5 +95,7 @@ class Proxy:
|
||||
"""Installs cert"""
|
||||
cert_path, key_path, chain_path = self.copy_certs_and_keys(
|
||||
cert_path, key_path, chain_path)
|
||||
if not self._configurator:
|
||||
raise ValueError("Configurator plugin is not set.")
|
||||
self._configurator.deploy_cert(
|
||||
domain, cert_path, key_path, chain_path, fullchain_path)
|
||||
|
||||
@@ -21,7 +21,7 @@ class Proxy(configurators_common.Proxy):
|
||||
|
||||
def load_config(self):
|
||||
"""Loads the next configuration for the plugin to test"""
|
||||
config = super(Proxy, self).load_config()
|
||||
config = super().load_config()
|
||||
self._all_names, self._test_names = _get_names(config)
|
||||
|
||||
server_root = _get_server_root(config)
|
||||
|
||||
@@ -3,7 +3,7 @@ import sys
|
||||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.14.0.dev0'
|
||||
version = '1.15.0.dev0'
|
||||
|
||||
install_requires = [
|
||||
'certbot',
|
||||
@@ -24,7 +24,7 @@ setup(
|
||||
description="Compatibility tests for Certbot",
|
||||
url='https://github.com/letsencrypt/letsencrypt',
|
||||
author="Certbot Project",
|
||||
author_email='client-dev@letsencrypt.org',
|
||||
author_email='certbot-dev@eff.org',
|
||||
license='Apache License 2.0',
|
||||
python_requires='>=3.6',
|
||||
classifiers=[
|
||||
|
||||
@@ -3,6 +3,7 @@ import logging
|
||||
from typing import Any
|
||||
from typing import Dict
|
||||
from typing import List
|
||||
from typing import Optional
|
||||
|
||||
import CloudFlare
|
||||
import zope.interface
|
||||
@@ -10,6 +11,7 @@ import zope.interface
|
||||
from certbot import errors
|
||||
from certbot import interfaces
|
||||
from certbot.plugins import dns_common
|
||||
from certbot.plugins.dns_common import CredentialsConfiguration
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -29,12 +31,12 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
ttl = 120
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Authenticator, self).__init__(*args, **kwargs)
|
||||
self.credentials = None
|
||||
super().__init__(*args, **kwargs)
|
||||
self.credentials: Optional[CredentialsConfiguration] = None
|
||||
|
||||
@classmethod
|
||||
def add_parser_arguments(cls, add): # pylint: disable=arguments-differ
|
||||
super(Authenticator, cls).add_parser_arguments(add)
|
||||
super().add_parser_arguments(add)
|
||||
add('credentials', help='Cloudflare credentials INI file.')
|
||||
|
||||
def more_info(self): # pylint: disable=missing-function-docstring
|
||||
@@ -79,6 +81,8 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
self._get_cloudflare_client().del_txt_record(domain, validation_name, validation)
|
||||
|
||||
def _get_cloudflare_client(self):
|
||||
if not self.credentials: # pragma: no cover
|
||||
raise errors.Error("Plugin has not been prepared.")
|
||||
if self.credentials.conf('api-token'):
|
||||
return _CloudflareClient(None, self.credentials.conf('api-token'))
|
||||
return _CloudflareClient(self.credentials.conf('email'), self.credentials.conf('api-key'))
|
||||
|
||||
@@ -4,7 +4,7 @@ import sys
|
||||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.14.0.dev0'
|
||||
version = '1.15.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
@@ -36,7 +36,7 @@ setup(
|
||||
description="Cloudflare DNS Authenticator plugin for Certbot",
|
||||
url='https://github.com/certbot/certbot',
|
||||
author="Certbot Project",
|
||||
author_email='client-dev@letsencrypt.org',
|
||||
author_email='certbot-dev@eff.org',
|
||||
license='Apache License 2.0',
|
||||
python_requires='>=3.6',
|
||||
classifiers=[
|
||||
|
||||
@@ -27,7 +27,7 @@ class AuthenticatorTest(test_util.TempDirTestCase, dns_test_common.BaseAuthentic
|
||||
def setUp(self):
|
||||
from certbot_dns_cloudflare._internal.dns_cloudflare import Authenticator
|
||||
|
||||
super(AuthenticatorTest, self).setUp()
|
||||
super().setUp()
|
||||
|
||||
path = os.path.join(self.tempdir, 'file.ini')
|
||||
dns_test_common.write({"cloudflare_email": EMAIL, "cloudflare_api_key": API_KEY}, path)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"""DNS Authenticator for CloudXNS DNS."""
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from lexicon.providers import cloudxns
|
||||
import zope.interface
|
||||
@@ -8,6 +9,7 @@ from certbot import errors
|
||||
from certbot import interfaces
|
||||
from certbot.plugins import dns_common
|
||||
from certbot.plugins import dns_common_lexicon
|
||||
from certbot.plugins.dns_common import CredentialsConfiguration
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -26,12 +28,12 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
ttl = 60
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Authenticator, self).__init__(*args, **kwargs)
|
||||
self.credentials = None
|
||||
super().__init__(*args, **kwargs)
|
||||
self.credentials: Optional[CredentialsConfiguration] = None
|
||||
|
||||
@classmethod
|
||||
def add_parser_arguments(cls, add): # pylint: disable=arguments-differ
|
||||
super(Authenticator, cls).add_parser_arguments(add, default_propagation_seconds=30)
|
||||
super().add_parser_arguments(add, default_propagation_seconds=30)
|
||||
add('credentials', help='CloudXNS credentials INI file.')
|
||||
|
||||
def more_info(self): # pylint: disable=missing-function-docstring
|
||||
@@ -56,6 +58,8 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
self._get_cloudxns_client().del_txt_record(domain, validation_name, validation)
|
||||
|
||||
def _get_cloudxns_client(self):
|
||||
if not self.credentials: # pragma: no cover
|
||||
raise errors.Error("Plugin has not been prepared.")
|
||||
return _CloudXNSLexiconClient(self.credentials.conf('api-key'),
|
||||
self.credentials.conf('secret-key'),
|
||||
self.ttl)
|
||||
@@ -67,7 +71,7 @@ class _CloudXNSLexiconClient(dns_common_lexicon.LexiconClient):
|
||||
"""
|
||||
|
||||
def __init__(self, api_key, secret_key, ttl):
|
||||
super(_CloudXNSLexiconClient, self).__init__()
|
||||
super().__init__()
|
||||
|
||||
config = dns_common_lexicon.build_lexicon_config('cloudxns', {
|
||||
'ttl': ttl,
|
||||
|
||||
@@ -4,7 +4,7 @@ import sys
|
||||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.14.0.dev0'
|
||||
version = '1.15.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
@@ -36,7 +36,7 @@ setup(
|
||||
description="CloudXNS DNS Authenticator plugin for Certbot",
|
||||
url='https://github.com/certbot/certbot',
|
||||
author="Certbot Project",
|
||||
author_email='client-dev@letsencrypt.org',
|
||||
author_email='certbot-dev@eff.org',
|
||||
license='Apache License 2.0',
|
||||
python_requires='>=3.6',
|
||||
classifiers=[
|
||||
|
||||
@@ -26,7 +26,7 @@ class AuthenticatorTest(test_util.TempDirTestCase,
|
||||
dns_test_common_lexicon.BaseLexiconAuthenticatorTest):
|
||||
|
||||
def setUp(self):
|
||||
super(AuthenticatorTest, self).setUp()
|
||||
super().setUp()
|
||||
|
||||
from certbot_dns_cloudxns._internal.dns_cloudxns import Authenticator
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"""DNS Authenticator for DigitalOcean."""
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
import digitalocean
|
||||
import zope.interface
|
||||
@@ -7,6 +8,7 @@ import zope.interface
|
||||
from certbot import errors
|
||||
from certbot import interfaces
|
||||
from certbot.plugins import dns_common
|
||||
from certbot.plugins.dns_common import CredentialsConfiguration
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -24,12 +26,12 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
ttl = 30
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Authenticator, self).__init__(*args, **kwargs)
|
||||
self.credentials = None
|
||||
super().__init__(*args, **kwargs)
|
||||
self.credentials: Optional[CredentialsConfiguration] = None
|
||||
|
||||
@classmethod
|
||||
def add_parser_arguments(cls, add): # pylint: disable=arguments-differ
|
||||
super(Authenticator, cls).add_parser_arguments(add)
|
||||
super().add_parser_arguments(add)
|
||||
add('credentials', help='DigitalOcean credentials INI file.')
|
||||
|
||||
def more_info(self): # pylint: disable=missing-function-docstring
|
||||
@@ -53,6 +55,8 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
self._get_digitalocean_client().del_txt_record(domain, validation_name, validation)
|
||||
|
||||
def _get_digitalocean_client(self):
|
||||
if not self.credentials: # pragma: no cover
|
||||
raise errors.Error("Plugin has not been prepared.")
|
||||
return _DigitalOceanClient(self.credentials.conf('token'))
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import sys
|
||||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.14.0.dev0'
|
||||
version = '1.15.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
@@ -36,7 +36,7 @@ setup(
|
||||
description="DigitalOcean DNS Authenticator plugin for Certbot",
|
||||
url='https://github.com/certbot/certbot',
|
||||
author="Certbot Project",
|
||||
author_email='client-dev@letsencrypt.org',
|
||||
author_email='certbot-dev@eff.org',
|
||||
license='Apache License 2.0',
|
||||
python_requires='>=3.6',
|
||||
classifiers=[
|
||||
|
||||
@@ -23,7 +23,7 @@ class AuthenticatorTest(test_util.TempDirTestCase, dns_test_common.BaseAuthentic
|
||||
def setUp(self):
|
||||
from certbot_dns_digitalocean._internal.dns_digitalocean import Authenticator
|
||||
|
||||
super(AuthenticatorTest, self).setUp()
|
||||
super().setUp()
|
||||
|
||||
path = os.path.join(self.tempdir, 'file.ini')
|
||||
dns_test_common.write({"digitalocean_token": TOKEN}, path)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"""DNS Authenticator for DNSimple DNS."""
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from lexicon.providers import dnsimple
|
||||
import zope.interface
|
||||
@@ -8,6 +9,7 @@ from certbot import errors
|
||||
from certbot import interfaces
|
||||
from certbot.plugins import dns_common
|
||||
from certbot.plugins import dns_common_lexicon
|
||||
from certbot.plugins.dns_common import CredentialsConfiguration
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -26,12 +28,12 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
ttl = 60
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Authenticator, self).__init__(*args, **kwargs)
|
||||
self.credentials = None
|
||||
super().__init__(*args, **kwargs)
|
||||
self.credentials: Optional[CredentialsConfiguration] = None
|
||||
|
||||
@classmethod
|
||||
def add_parser_arguments(cls, add): # pylint: disable=arguments-differ
|
||||
super(Authenticator, cls).add_parser_arguments(add, default_propagation_seconds=30)
|
||||
super().add_parser_arguments(add, default_propagation_seconds=30)
|
||||
add('credentials', help='DNSimple credentials INI file.')
|
||||
|
||||
def more_info(self): # pylint: disable=missing-function-docstring
|
||||
@@ -54,6 +56,8 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
self._get_dnsimple_client().del_txt_record(domain, validation_name, validation)
|
||||
|
||||
def _get_dnsimple_client(self):
|
||||
if not self.credentials: # pragma: no cover
|
||||
raise errors.Error("Plugin has not been prepared.")
|
||||
return _DNSimpleLexiconClient(self.credentials.conf('token'), self.ttl)
|
||||
|
||||
|
||||
@@ -63,7 +67,7 @@ class _DNSimpleLexiconClient(dns_common_lexicon.LexiconClient):
|
||||
"""
|
||||
|
||||
def __init__(self, token, ttl):
|
||||
super(_DNSimpleLexiconClient, self).__init__()
|
||||
super().__init__()
|
||||
|
||||
config = dns_common_lexicon.build_lexicon_config('dnssimple', {
|
||||
'ttl': ttl,
|
||||
|
||||
@@ -4,7 +4,7 @@ import sys
|
||||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.14.0.dev0'
|
||||
version = '1.15.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
@@ -47,7 +47,7 @@ setup(
|
||||
description="DNSimple DNS Authenticator plugin for Certbot",
|
||||
url='https://github.com/certbot/certbot',
|
||||
author="Certbot Project",
|
||||
author_email='client-dev@letsencrypt.org',
|
||||
author_email='certbot-dev@eff.org',
|
||||
license='Apache License 2.0',
|
||||
python_requires='>=3.6',
|
||||
classifiers=[
|
||||
|
||||
@@ -20,7 +20,7 @@ class AuthenticatorTest(test_util.TempDirTestCase,
|
||||
dns_test_common_lexicon.BaseLexiconAuthenticatorTest):
|
||||
|
||||
def setUp(self):
|
||||
super(AuthenticatorTest, self).setUp()
|
||||
super().setUp()
|
||||
|
||||
from certbot_dns_dnsimple._internal.dns_dnsimple import Authenticator
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"""DNS Authenticator for DNS Made Easy DNS."""
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from lexicon.providers import dnsmadeeasy
|
||||
import zope.interface
|
||||
@@ -8,6 +9,7 @@ from certbot import errors
|
||||
from certbot import interfaces
|
||||
from certbot.plugins import dns_common
|
||||
from certbot.plugins import dns_common_lexicon
|
||||
from certbot.plugins.dns_common import CredentialsConfiguration
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -27,12 +29,12 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
ttl = 60
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Authenticator, self).__init__(*args, **kwargs)
|
||||
self.credentials = None
|
||||
super().__init__(*args, **kwargs)
|
||||
self.credentials: Optional[CredentialsConfiguration] = None
|
||||
|
||||
@classmethod
|
||||
def add_parser_arguments(cls, add): # pylint: disable=arguments-differ
|
||||
super(Authenticator, cls).add_parser_arguments(add, default_propagation_seconds=60)
|
||||
super().add_parser_arguments(add, default_propagation_seconds=60)
|
||||
add('credentials', help='DNS Made Easy credentials INI file.')
|
||||
|
||||
def more_info(self): # pylint: disable=missing-function-docstring
|
||||
@@ -58,6 +60,8 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
self._get_dnsmadeeasy_client().del_txt_record(domain, validation_name, validation)
|
||||
|
||||
def _get_dnsmadeeasy_client(self):
|
||||
if not self.credentials: # pragma: no cover
|
||||
raise errors.Error("Plugin has not been prepared.")
|
||||
return _DNSMadeEasyLexiconClient(self.credentials.conf('api-key'),
|
||||
self.credentials.conf('secret-key'),
|
||||
self.ttl)
|
||||
@@ -69,7 +73,7 @@ class _DNSMadeEasyLexiconClient(dns_common_lexicon.LexiconClient):
|
||||
"""
|
||||
|
||||
def __init__(self, api_key, secret_key, ttl):
|
||||
super(_DNSMadeEasyLexiconClient, self).__init__()
|
||||
super().__init__()
|
||||
|
||||
config = dns_common_lexicon.build_lexicon_config('dnsmadeeasy', {
|
||||
'ttl': ttl,
|
||||
|
||||
@@ -4,7 +4,7 @@ import sys
|
||||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.14.0.dev0'
|
||||
version = '1.15.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
@@ -36,7 +36,7 @@ setup(
|
||||
description="DNS Made Easy DNS Authenticator plugin for Certbot",
|
||||
url='https://github.com/certbot/certbot',
|
||||
author="Certbot Project",
|
||||
author_email='client-dev@letsencrypt.org',
|
||||
author_email='certbot-dev@eff.org',
|
||||
license='Apache License 2.0',
|
||||
python_requires='>=3.6',
|
||||
classifiers=[
|
||||
|
||||
@@ -22,7 +22,7 @@ class AuthenticatorTest(test_util.TempDirTestCase,
|
||||
dns_test_common_lexicon.BaseLexiconAuthenticatorTest):
|
||||
|
||||
def setUp(self):
|
||||
super(AuthenticatorTest, self).setUp()
|
||||
super().setUp()
|
||||
|
||||
from certbot_dns_dnsmadeeasy._internal.dns_dnsmadeeasy import Authenticator
|
||||
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
"""DNS Authenticator for Gehirn Infrastructure Service DNS."""
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from lexicon.providers import gehirn
|
||||
import zope.interface
|
||||
|
||||
from certbot import errors
|
||||
from certbot import interfaces
|
||||
from certbot.plugins import dns_common
|
||||
from certbot.plugins import dns_common_lexicon
|
||||
from certbot.plugins.dns_common import CredentialsConfiguration
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -26,12 +29,12 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
ttl = 60
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Authenticator, self).__init__(*args, **kwargs)
|
||||
self.credentials = None
|
||||
super().__init__(*args, **kwargs)
|
||||
self.credentials: Optional[CredentialsConfiguration] = None
|
||||
|
||||
@classmethod
|
||||
def add_parser_arguments(cls, add): # pylint: disable=arguments-differ
|
||||
super(Authenticator, cls).add_parser_arguments(add, default_propagation_seconds=30)
|
||||
super().add_parser_arguments(add, default_propagation_seconds=30)
|
||||
add('credentials', help='Gehirn Infrastructure Service credentials file.')
|
||||
|
||||
def more_info(self): # pylint: disable=missing-function-docstring
|
||||
@@ -57,6 +60,8 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
self._get_gehirn_client().del_txt_record(domain, validation_name, validation)
|
||||
|
||||
def _get_gehirn_client(self):
|
||||
if not self.credentials: # pragma: no cover
|
||||
raise errors.Error("Plugin has not been prepared.")
|
||||
return _GehirnLexiconClient(
|
||||
self.credentials.conf('api-token'),
|
||||
self.credentials.conf('api-secret'),
|
||||
@@ -70,7 +75,7 @@ class _GehirnLexiconClient(dns_common_lexicon.LexiconClient):
|
||||
"""
|
||||
|
||||
def __init__(self, api_token, api_secret, ttl):
|
||||
super(_GehirnLexiconClient, self).__init__()
|
||||
super().__init__()
|
||||
|
||||
config = dns_common_lexicon.build_lexicon_config('gehirn', {
|
||||
'ttl': ttl,
|
||||
@@ -84,4 +89,4 @@ class _GehirnLexiconClient(dns_common_lexicon.LexiconClient):
|
||||
def _handle_http_error(self, e, domain_name):
|
||||
if domain_name in str(e) and (str(e).startswith('404 Client Error: Not Found for url:')):
|
||||
return None # Expected errors when zone name guess is wrong
|
||||
return super(_GehirnLexiconClient, self)._handle_http_error(e, domain_name)
|
||||
return super()._handle_http_error(e, domain_name)
|
||||
|
||||
@@ -4,7 +4,7 @@ import sys
|
||||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.14.0.dev0'
|
||||
version = '1.15.0.dev0'
|
||||
|
||||
# Please update tox.ini when modifying dependency version requirements
|
||||
install_requires = [
|
||||
@@ -35,7 +35,7 @@ setup(
|
||||
description="Gehirn Infrastructure Service DNS Authenticator plugin for Certbot",
|
||||
url='https://github.com/certbot/certbot',
|
||||
author="Certbot Project",
|
||||
author_email='client-dev@letsencrypt.org',
|
||||
author_email='certbot-dev@eff.org',
|
||||
license='Apache License 2.0',
|
||||
python_requires='>=3.6',
|
||||
classifiers=[
|
||||
|
||||
@@ -21,7 +21,7 @@ class AuthenticatorTest(test_util.TempDirTestCase,
|
||||
dns_test_common_lexicon.BaseLexiconAuthenticatorTest):
|
||||
|
||||
def setUp(self):
|
||||
super(AuthenticatorTest, self).setUp()
|
||||
super().setUp()
|
||||
|
||||
from certbot_dns_gehirn._internal.dns_gehirn import Authenticator
|
||||
|
||||
|
||||
@@ -32,13 +32,9 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
'for DNS).')
|
||||
ttl = 60
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Authenticator, self).__init__(*args, **kwargs)
|
||||
self.credentials = None
|
||||
|
||||
@classmethod
|
||||
def add_parser_arguments(cls, add): # pylint: disable=arguments-differ
|
||||
super(Authenticator, cls).add_parser_arguments(add, default_propagation_seconds=60)
|
||||
super().add_parser_arguments(add, default_propagation_seconds=60)
|
||||
add('credentials',
|
||||
help=('Path to Google Cloud DNS service account JSON file. (See {0} for' +
|
||||
'information about creating a service account and {1} for information about the' +
|
||||
|
||||
@@ -4,7 +4,7 @@ import sys
|
||||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.14.0.dev0'
|
||||
version = '1.15.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
@@ -39,7 +39,7 @@ setup(
|
||||
description="Google Cloud DNS Authenticator plugin for Certbot",
|
||||
url='https://github.com/certbot/certbot',
|
||||
author="Certbot Project",
|
||||
author_email='client-dev@letsencrypt.org',
|
||||
author_email='certbot-dev@eff.org',
|
||||
license='Apache License 2.0',
|
||||
python_requires='>=3.6',
|
||||
classifiers=[
|
||||
|
||||
@@ -26,14 +26,14 @@ PROJECT_ID = "test-test-1"
|
||||
class AuthenticatorTest(test_util.TempDirTestCase, dns_test_common.BaseAuthenticatorTest):
|
||||
|
||||
def setUp(self):
|
||||
super(AuthenticatorTest, self).setUp()
|
||||
super().setUp()
|
||||
|
||||
from certbot_dns_google._internal.dns_google import Authenticator
|
||||
|
||||
path = os.path.join(self.tempdir, 'file.json')
|
||||
open(path, "wb").close()
|
||||
|
||||
super(AuthenticatorTest, self).setUp()
|
||||
super().setUp()
|
||||
self.config = mock.MagicMock(google_credentials=path,
|
||||
google_propagation_seconds=0) # don't wait during tests
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""DNS Authenticator for Linode."""
|
||||
import logging
|
||||
import re
|
||||
from typing import Optional
|
||||
|
||||
from lexicon.providers import linode
|
||||
from lexicon.providers import linode4
|
||||
@@ -10,6 +11,7 @@ from certbot import errors
|
||||
from certbot import interfaces
|
||||
from certbot.plugins import dns_common
|
||||
from certbot.plugins import dns_common_lexicon
|
||||
from certbot.plugins.dns_common import CredentialsConfiguration
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -27,12 +29,12 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
description = 'Obtain certificates using a DNS TXT record (if you are using Linode for DNS).'
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Authenticator, self).__init__(*args, **kwargs)
|
||||
self.credentials = None
|
||||
super().__init__(*args, **kwargs)
|
||||
self.credentials: Optional[CredentialsConfiguration] = None
|
||||
|
||||
@classmethod
|
||||
def add_parser_arguments(cls, add): # pylint: disable=arguments-differ
|
||||
super(Authenticator, cls).add_parser_arguments(add, default_propagation_seconds=120)
|
||||
super().add_parser_arguments(add, default_propagation_seconds=120)
|
||||
add('credentials', help='Linode credentials INI file.')
|
||||
|
||||
def more_info(self): # pylint: disable=missing-function-docstring
|
||||
@@ -56,6 +58,8 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
self._get_linode_client().del_txt_record(domain, validation_name, validation)
|
||||
|
||||
def _get_linode_client(self):
|
||||
if not self.credentials: # pragma: no cover
|
||||
raise errors.Error("Plugin has not been prepared.")
|
||||
api_key = self.credentials.conf('key')
|
||||
api_version = self.credentials.conf('version')
|
||||
if api_version == '':
|
||||
@@ -81,7 +85,7 @@ class _LinodeLexiconClient(dns_common_lexicon.LexiconClient):
|
||||
"""
|
||||
|
||||
def __init__(self, api_key, api_version):
|
||||
super(_LinodeLexiconClient, self).__init__()
|
||||
super().__init__()
|
||||
|
||||
self.api_version = api_version
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import sys
|
||||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.14.0.dev0'
|
||||
version = '1.15.0.dev0'
|
||||
|
||||
# Please update tox.ini when modifying dependency version requirements
|
||||
install_requires = [
|
||||
@@ -35,7 +35,7 @@ setup(
|
||||
description="Linode DNS Authenticator plugin for Certbot",
|
||||
url='https://github.com/certbot/certbot',
|
||||
author="Certbot Project",
|
||||
author_email='client-dev@letsencrypt.org',
|
||||
author_email='certbot-dev@eff.org',
|
||||
license='Apache License 2.0',
|
||||
python_requires='>=3.6',
|
||||
classifiers=[
|
||||
|
||||
@@ -22,7 +22,7 @@ class AuthenticatorTest(test_util.TempDirTestCase,
|
||||
dns_test_common_lexicon.BaseLexiconAuthenticatorTest):
|
||||
|
||||
def setUp(self):
|
||||
super(AuthenticatorTest, self).setUp()
|
||||
super().setUp()
|
||||
|
||||
path = os.path.join(self.tempdir, 'file.ini')
|
||||
dns_test_common.write({"linode_key": TOKEN}, path)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"""DNS Authenticator for LuaDNS DNS."""
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from lexicon.providers import luadns
|
||||
import zope.interface
|
||||
@@ -8,6 +9,7 @@ from certbot import errors
|
||||
from certbot import interfaces
|
||||
from certbot.plugins import dns_common
|
||||
from certbot.plugins import dns_common_lexicon
|
||||
from certbot.plugins.dns_common import CredentialsConfiguration
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -26,12 +28,12 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
ttl = 60
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Authenticator, self).__init__(*args, **kwargs)
|
||||
self.credentials = None
|
||||
super().__init__(*args, **kwargs)
|
||||
self.credentials: Optional[CredentialsConfiguration] = None
|
||||
|
||||
@classmethod
|
||||
def add_parser_arguments(cls, add): # pylint: disable=arguments-differ
|
||||
super(Authenticator, cls).add_parser_arguments(add, default_propagation_seconds=30)
|
||||
super().add_parser_arguments(add, default_propagation_seconds=30)
|
||||
add('credentials', help='LuaDNS credentials INI file.')
|
||||
|
||||
def more_info(self): # pylint: disable=missing-function-docstring
|
||||
@@ -55,6 +57,8 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
self._get_luadns_client().del_txt_record(domain, validation_name, validation)
|
||||
|
||||
def _get_luadns_client(self):
|
||||
if not self.credentials: # pragma: no cover
|
||||
raise errors.Error("Plugin has not been prepared.")
|
||||
return _LuaDNSLexiconClient(self.credentials.conf('email'),
|
||||
self.credentials.conf('token'),
|
||||
self.ttl)
|
||||
@@ -66,7 +70,7 @@ class _LuaDNSLexiconClient(dns_common_lexicon.LexiconClient):
|
||||
"""
|
||||
|
||||
def __init__(self, email, token, ttl):
|
||||
super(_LuaDNSLexiconClient, self).__init__()
|
||||
super().__init__()
|
||||
|
||||
config = dns_common_lexicon.build_lexicon_config('luadns', {
|
||||
'ttl': ttl,
|
||||
|
||||
@@ -4,7 +4,7 @@ import sys
|
||||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.14.0.dev0'
|
||||
version = '1.15.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
@@ -36,7 +36,7 @@ setup(
|
||||
description="LuaDNS Authenticator plugin for Certbot",
|
||||
url='https://github.com/certbot/certbot',
|
||||
author="Certbot Project",
|
||||
author_email='client-dev@letsencrypt.org',
|
||||
author_email='certbot-dev@eff.org',
|
||||
license='Apache License 2.0',
|
||||
python_requires='>=3.6',
|
||||
classifiers=[
|
||||
|
||||
@@ -21,7 +21,7 @@ class AuthenticatorTest(test_util.TempDirTestCase,
|
||||
dns_test_common_lexicon.BaseLexiconAuthenticatorTest):
|
||||
|
||||
def setUp(self):
|
||||
super(AuthenticatorTest, self).setUp()
|
||||
super().setUp()
|
||||
|
||||
from certbot_dns_luadns._internal.dns_luadns import Authenticator
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"""DNS Authenticator for NS1 DNS."""
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from lexicon.providers import nsone
|
||||
import zope.interface
|
||||
@@ -8,6 +9,7 @@ from certbot import errors
|
||||
from certbot import interfaces
|
||||
from certbot.plugins import dns_common
|
||||
from certbot.plugins import dns_common_lexicon
|
||||
from certbot.plugins.dns_common import CredentialsConfiguration
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -26,12 +28,12 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
ttl = 60
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Authenticator, self).__init__(*args, **kwargs)
|
||||
self.credentials = None
|
||||
super().__init__(*args, **kwargs)
|
||||
self.credentials: Optional[CredentialsConfiguration] = None
|
||||
|
||||
@classmethod
|
||||
def add_parser_arguments(cls, add): # pylint: disable=arguments-differ
|
||||
super(Authenticator, cls).add_parser_arguments(add, default_propagation_seconds=30)
|
||||
super().add_parser_arguments(add, default_propagation_seconds=30)
|
||||
add('credentials', help='NS1 credentials file.')
|
||||
|
||||
def more_info(self): # pylint: disable=missing-function-docstring
|
||||
@@ -54,6 +56,8 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
self._get_nsone_client().del_txt_record(domain, validation_name, validation)
|
||||
|
||||
def _get_nsone_client(self):
|
||||
if not self.credentials: # pragma: no cover
|
||||
raise errors.Error("Plugin has not been prepared.")
|
||||
return _NS1LexiconClient(self.credentials.conf('api-key'), self.ttl)
|
||||
|
||||
|
||||
@@ -63,7 +67,7 @@ class _NS1LexiconClient(dns_common_lexicon.LexiconClient):
|
||||
"""
|
||||
|
||||
def __init__(self, api_key, ttl):
|
||||
super(_NS1LexiconClient, self).__init__()
|
||||
super().__init__()
|
||||
|
||||
config = dns_common_lexicon.build_lexicon_config('nsone', {
|
||||
'ttl': ttl,
|
||||
|
||||
@@ -4,7 +4,7 @@ import sys
|
||||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.14.0.dev0'
|
||||
version = '1.15.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
@@ -36,7 +36,7 @@ setup(
|
||||
description="NS1 DNS Authenticator plugin for Certbot",
|
||||
url='https://github.com/certbot/certbot',
|
||||
author="Certbot Project",
|
||||
author_email='client-dev@letsencrypt.org',
|
||||
author_email='certbot-dev@eff.org',
|
||||
license='Apache License 2.0',
|
||||
python_requires='>=3.6',
|
||||
classifiers=[
|
||||
|
||||
@@ -21,7 +21,7 @@ class AuthenticatorTest(test_util.TempDirTestCase,
|
||||
dns_test_common_lexicon.BaseLexiconAuthenticatorTest):
|
||||
|
||||
def setUp(self):
|
||||
super(AuthenticatorTest, self).setUp()
|
||||
super().setUp()
|
||||
|
||||
from certbot_dns_nsone._internal.dns_nsone import Authenticator
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"""DNS Authenticator for OVH DNS."""
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from lexicon.providers import ovh
|
||||
import zope.interface
|
||||
@@ -8,6 +9,7 @@ from certbot import errors
|
||||
from certbot import interfaces
|
||||
from certbot.plugins import dns_common
|
||||
from certbot.plugins import dns_common_lexicon
|
||||
from certbot.plugins.dns_common import CredentialsConfiguration
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -26,12 +28,12 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
ttl = 60
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Authenticator, self).__init__(*args, **kwargs)
|
||||
self.credentials = None
|
||||
super().__init__(*args, **kwargs)
|
||||
self.credentials: Optional[CredentialsConfiguration] = None
|
||||
|
||||
@classmethod
|
||||
def add_parser_arguments(cls, add): # pylint: disable=arguments-differ
|
||||
super(Authenticator, cls).add_parser_arguments(add, default_propagation_seconds=30)
|
||||
super().add_parser_arguments(add, default_propagation_seconds=30)
|
||||
add('credentials', help='OVH credentials INI file.')
|
||||
|
||||
def more_info(self): # pylint: disable=missing-function-docstring
|
||||
@@ -60,6 +62,8 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
self._get_ovh_client().del_txt_record(domain, validation_name, validation)
|
||||
|
||||
def _get_ovh_client(self):
|
||||
if not self.credentials: # pragma: no cover
|
||||
raise errors.Error("Plugin has not been prepared.")
|
||||
return _OVHLexiconClient(
|
||||
self.credentials.conf('endpoint'),
|
||||
self.credentials.conf('application-key'),
|
||||
@@ -75,7 +79,7 @@ class _OVHLexiconClient(dns_common_lexicon.LexiconClient):
|
||||
"""
|
||||
|
||||
def __init__(self, endpoint, application_key, application_secret, consumer_key, ttl):
|
||||
super(_OVHLexiconClient, self).__init__()
|
||||
super().__init__()
|
||||
|
||||
config = dns_common_lexicon.build_lexicon_config('ovh', {
|
||||
'ttl': ttl,
|
||||
@@ -102,4 +106,4 @@ class _OVHLexiconClient(dns_common_lexicon.LexiconClient):
|
||||
if domain_name in str(e) and str(e).endswith('not found'):
|
||||
return
|
||||
|
||||
super(_OVHLexiconClient, self)._handle_general_error(e, domain_name)
|
||||
super()._handle_general_error(e, domain_name)
|
||||
|
||||
@@ -4,7 +4,7 @@ import sys
|
||||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.14.0.dev0'
|
||||
version = '1.15.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
@@ -36,7 +36,7 @@ setup(
|
||||
description="OVH DNS Authenticator plugin for Certbot",
|
||||
url='https://github.com/certbot/certbot',
|
||||
author="Certbot Project",
|
||||
author_email='client-dev@letsencrypt.org',
|
||||
author_email='certbot-dev@eff.org',
|
||||
license='Apache License 2.0',
|
||||
python_requires='>=3.6',
|
||||
classifiers=[
|
||||
|
||||
@@ -23,7 +23,7 @@ class AuthenticatorTest(test_util.TempDirTestCase,
|
||||
dns_test_common_lexicon.BaseLexiconAuthenticatorTest):
|
||||
|
||||
def setUp(self):
|
||||
super(AuthenticatorTest, self).setUp()
|
||||
super().setUp()
|
||||
|
||||
from certbot_dns_ovh._internal.dns_ovh import Authenticator
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"""DNS Authenticator using RFC 2136 Dynamic Updates."""
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
import dns.flags
|
||||
import dns.message
|
||||
@@ -15,6 +16,7 @@ import zope.interface
|
||||
from certbot import errors
|
||||
from certbot import interfaces
|
||||
from certbot.plugins import dns_common
|
||||
from certbot.plugins.dns_common import CredentialsConfiguration
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -43,12 +45,12 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
ttl = 120
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Authenticator, self).__init__(*args, **kwargs)
|
||||
self.credentials = None
|
||||
super().__init__(*args, **kwargs)
|
||||
self.credentials: Optional[CredentialsConfiguration] = None
|
||||
|
||||
@classmethod
|
||||
def add_parser_arguments(cls, add): # pylint: disable=arguments-differ
|
||||
super(Authenticator, cls).add_parser_arguments(add, default_propagation_seconds=60)
|
||||
super().add_parser_arguments(add, default_propagation_seconds=60)
|
||||
add('credentials', help='RFC 2136 credentials INI file.')
|
||||
|
||||
def more_info(self): # pylint: disable=missing-function-docstring
|
||||
@@ -80,6 +82,8 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
self._get_rfc2136_client().del_txt_record(validation_name, validation)
|
||||
|
||||
def _get_rfc2136_client(self):
|
||||
if not self.credentials: # pragma: no cover
|
||||
raise errors.Error("Plugin has not been prepared.")
|
||||
return _RFC2136Client(self.credentials.conf('server'),
|
||||
int(self.credentials.conf('port') or self.PORT),
|
||||
self.credentials.conf('name'),
|
||||
|
||||
@@ -4,7 +4,7 @@ import sys
|
||||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.14.0.dev0'
|
||||
version = '1.15.0.dev0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
@@ -36,7 +36,7 @@ setup(
|
||||
description="RFC 2136 DNS Authenticator plugin for Certbot",
|
||||
url='https://github.com/certbot/certbot',
|
||||
author="Certbot Project",
|
||||
author_email='client-dev@letsencrypt.org',
|
||||
author_email='certbot-dev@eff.org',
|
||||
license='Apache License 2.0',
|
||||
python_requires='>=3.6',
|
||||
classifiers=[
|
||||
|
||||
@@ -28,7 +28,7 @@ class AuthenticatorTest(test_util.TempDirTestCase, dns_test_common.BaseAuthentic
|
||||
def setUp(self):
|
||||
from certbot_dns_rfc2136._internal.dns_rfc2136 import Authenticator
|
||||
|
||||
super(AuthenticatorTest, self).setUp()
|
||||
super().setUp()
|
||||
|
||||
path = os.path.join(self.tempdir, 'file.ini')
|
||||
dns_test_common.write(VALID_CONFIG, path)
|
||||
|
||||
@@ -37,7 +37,7 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
ttl = 10
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Authenticator, self).__init__(*args, **kwargs)
|
||||
super().__init__(*args, **kwargs)
|
||||
self.r53 = boto3.client("route53")
|
||||
self._resource_records: DefaultDict[str, List[Dict[str, str]]] = collections.defaultdict(list)
|
||||
|
||||
|
||||
@@ -18,4 +18,4 @@ class Authenticator(dns_route53.Authenticator):
|
||||
def __init__(self, *args, **kwargs):
|
||||
warnings.warn("The 'authenticator' module was renamed 'dns_route53'",
|
||||
DeprecationWarning)
|
||||
super(Authenticator, self).__init__(*args, **kwargs)
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user