Compare commits
104 Commits
test-apach
...
1.3.x
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c4426c44e7 | ||
|
|
5f6df46dfe | ||
|
|
6edb4e1a39 | ||
|
|
b1fb3296e9 | ||
|
|
3147026211 | ||
|
|
9f8e4507ad | ||
|
|
50ea608553 | ||
|
|
fa67b7ba0f | ||
|
|
6309ded92f | ||
|
|
5a4f158c55 | ||
|
|
a2be8e1956 | ||
|
|
2f737ee292 | ||
|
|
8c75a9de9f | ||
|
|
24aa1e9127 | ||
|
|
f4c0a9fd63 | ||
|
|
f169c37153 | ||
|
|
4ea98d830b | ||
|
|
4fd04366aa | ||
|
|
2633c3ffb6 | ||
|
|
9819443440 | ||
|
|
84b57fac93 | ||
|
|
7d79c91e9b | ||
|
|
c883efde0f | ||
|
|
42dda355c5 | ||
|
|
99b1538d0a | ||
|
|
fd64c8c33b | ||
|
|
3f52695ec2 | ||
|
|
fc7e5e8e60 | ||
|
|
bcaee66b0a | ||
|
|
df584a3b90 | ||
|
|
7d540fc33a | ||
|
|
605ef40656 | ||
|
|
b8856ac810 | ||
|
|
02bf7d7dfc | ||
|
|
e6f050dbe9 | ||
|
|
5607025e9b | ||
|
|
7cc6cf2604 | ||
|
|
86a6cc53cf | ||
|
|
1859fb059d | ||
|
|
c5a2ba03da | ||
|
|
995e70542a | ||
|
|
4f80f8b910 | ||
|
|
0e03f82733 | ||
|
|
5035a510a2 | ||
|
|
ef388a309f | ||
|
|
c98183c998 | ||
|
|
2b051dd197 | ||
|
|
7da5196206 | ||
|
|
cc764b65c1 | ||
|
|
7b35abbcb4 | ||
|
|
6601d03ce8 | ||
|
|
d3a4b8fd8c | ||
|
|
f3ed133744 | ||
|
|
1a2189f4df | ||
|
|
6a4b610269 | ||
|
|
97ae63efa6 | ||
|
|
3907b53b4b | ||
|
|
6c5959d892 | ||
|
|
601a114d1b | ||
|
|
86926dff92 | ||
|
|
9b35dbf2be | ||
|
|
05e35ff2e0 | ||
|
|
7d0651c315 | ||
|
|
174fa0e05c | ||
|
|
8d9943cb08 | ||
|
|
715899d5a8 | ||
|
|
882335c7ec | ||
|
|
35fa4c0457 | ||
|
|
11e402893f | ||
|
|
2338ab36fd | ||
|
|
e3c996de10 | ||
|
|
b8a9dd75eb | ||
|
|
2072599bd7 | ||
|
|
b1a8e7175b | ||
|
|
1e2f70b17a | ||
|
|
896c1e0b66 | ||
|
|
2f24726d4c | ||
|
|
5f315b46e9 | ||
|
|
a342eb5546 | ||
|
|
90fd1afc38 | ||
|
|
4473fd25cb | ||
|
|
a6772043d6 | ||
|
|
7234d8922d | ||
|
|
07dc2400eb | ||
|
|
1702cb90fd | ||
|
|
fcdeaf48f2 | ||
|
|
702ad99090 | ||
|
|
5f0703cbf1 | ||
|
|
9a3186a67e | ||
|
|
91ce42ce9c | ||
|
|
097c76f512 | ||
|
|
6e07e8b5c0 | ||
|
|
fd91643a7f | ||
|
|
619b17753e | ||
|
|
60cd920bcb | ||
|
|
f512b5eaa2 | ||
|
|
9800e5d8fc | ||
|
|
e84ed49c56 | ||
|
|
ceea41c1e2 | ||
|
|
456122e342 | ||
|
|
84c1b912d9 | ||
|
|
2bc64183a8 | ||
|
|
b27e5804b9 | ||
|
|
4ca03aec8d |
@@ -69,12 +69,12 @@ Access can be defined for all or only selected repositories, which is nice.
|
||||
```
|
||||
|
||||
- Redirected to Azure DevOps, select the account created in _Having an Azure DevOps account_ section.
|
||||
- Select the organization, and click "Create a new project" (let's name it the same than the targetted github repo)
|
||||
- Select the organization, and click "Create a new project" (let's name it the same than the targeted github repo)
|
||||
- The Visibility is public, to profit from 10 parallel jobs
|
||||
|
||||
```
|
||||
!!! ACCESS !!!
|
||||
Azure Pipelines needs access to the GitHub account (in term of beeing able to check it is valid), and the Resources shared between the GitHub account and Azure Pipelines.
|
||||
Azure Pipelines needs access to the GitHub account (in term of being able to check it is valid), and the Resources shared between the GitHub account and Azure Pipelines.
|
||||
```
|
||||
|
||||
_Done. We can move to pipelines configuration._
|
||||
|
||||
13
.azure-pipelines/advanced-test.yml
Normal file
13
.azure-pipelines/advanced-test.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
# Advanced pipeline for running our full test suite on demand.
|
||||
trigger:
|
||||
# When changing these triggers, please ensure the documentation under
|
||||
# "Running tests in CI" is still correct.
|
||||
- azure-test-*
|
||||
- test-*
|
||||
pr: none
|
||||
|
||||
jobs:
|
||||
# Any addition here should be reflected in the advanced and release pipelines.
|
||||
# It is advised to declare all jobs here as templates to improve maintainability.
|
||||
- template: templates/tests-suite.yml
|
||||
- template: templates/installer-tests.yml
|
||||
@@ -1,9 +1,7 @@
|
||||
# Advanced pipeline for isolated checks and release purpose
|
||||
# Advanced pipeline for running our full test suite on protected branches.
|
||||
trigger:
|
||||
- test-*
|
||||
- '*.x'
|
||||
pr:
|
||||
- test-*
|
||||
pr: none
|
||||
# This pipeline is also nightly run on master
|
||||
schedules:
|
||||
- cron: "0 4 * * *"
|
||||
@@ -14,7 +12,7 @@ schedules:
|
||||
always: true
|
||||
|
||||
jobs:
|
||||
# Any addition here should be reflected in the release pipeline.
|
||||
# Any addition here should be reflected in the advanced-test and release pipelines.
|
||||
# It is advised to declare all jobs here as templates to improve maintainability.
|
||||
- template: templates/tests-suite.yml
|
||||
- template: templates/installer-tests.yml
|
||||
|
||||
@@ -6,7 +6,7 @@ trigger:
|
||||
pr: none
|
||||
|
||||
jobs:
|
||||
# Any addition here should be reflected in the advanced pipeline.
|
||||
# Any addition here should be reflected in the advanced and advanced-test pipelines.
|
||||
# It is advised to declare all jobs here as templates to improve maintainability.
|
||||
- template: templates/tests-suite.yml
|
||||
- template: templates/installer-tests.yml
|
||||
|
||||
@@ -28,27 +28,27 @@ jobs:
|
||||
imageName: windows-2019
|
||||
win2016:
|
||||
imageName: vs2017-win2016
|
||||
win2012r2:
|
||||
imageName: vs2015-win2012r2
|
||||
pool:
|
||||
vmImage: $(imageName)
|
||||
steps:
|
||||
- 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: $(Build.SourcesDirectory)\bin\certbot-beta-installer-win32.exe /S
|
||||
displayName: Install Certbot
|
||||
- powershell: Invoke-WebRequest https://www.python.org/ftp/python/3.8.0/python-3.8.0-amd64-webinstall.exe -OutFile C:\py3-setup.exe
|
||||
displayName: Get Python
|
||||
- script: C:\py3-setup.exe /quiet PrependPath=1 InstallAllUsers=1 Include_launcher=1 InstallLauncherAllUsers=1 Include_test=0 Include_doc=0 Include_dev=1 Include_debug=0 Include_tcltk=0 TargetDir=C:\py3
|
||||
displayName: Install Python
|
||||
- script: |
|
||||
py -3 -m venv venv
|
||||
venv\Scripts\python tools\pip_install.py -e certbot-ci
|
||||
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 integration tests
|
||||
displayName: Run certbot integration tests
|
||||
|
||||
@@ -1,22 +1,34 @@
|
||||
jobs:
|
||||
- job: test
|
||||
pool:
|
||||
vmImage: vs2017-win2016
|
||||
strategy:
|
||||
matrix:
|
||||
py35:
|
||||
macos-py27:
|
||||
IMAGE_NAME: macOS-10.14
|
||||
PYTHON_VERSION: 2.7
|
||||
TOXENV: py27
|
||||
macos-py38:
|
||||
IMAGE_NAME: macOS-10.14
|
||||
PYTHON_VERSION: 3.8
|
||||
TOXENV: py38
|
||||
windows-py35:
|
||||
IMAGE_NAME: vs2017-win2016
|
||||
PYTHON_VERSION: 3.5
|
||||
TOXENV: py35
|
||||
py37-cover:
|
||||
windows-py37-cover:
|
||||
IMAGE_NAME: vs2017-win2016
|
||||
PYTHON_VERSION: 3.7
|
||||
TOXENV: py37-cover
|
||||
integration-certbot:
|
||||
windows-integration-certbot:
|
||||
IMAGE_NAME: vs2017-win2016
|
||||
PYTHON_VERSION: 3.7
|
||||
TOXENV: integration-certbot
|
||||
PYTEST_ADDOPTS: --numprocesses 4
|
||||
variables:
|
||||
- group: certbot-common
|
||||
pool:
|
||||
vmImage: $(IMAGE_NAME)
|
||||
steps:
|
||||
- bash: brew install augeas
|
||||
condition: startswith(variables['IMAGE_NAME'], 'macOS')
|
||||
displayName: Install Augeas
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: $(PYTHON_VERSION)
|
||||
@@ -25,14 +37,3 @@ jobs:
|
||||
displayName: Install dependencies
|
||||
- script: python -m tox
|
||||
displayName: Run tox
|
||||
# We do not require codecov report upload to succeed. So to avoid to break the pipeline if
|
||||
# something goes wrong, each command is suffixed with a command that hides any non zero exit
|
||||
# codes and echoes an informative message instead.
|
||||
- bash: |
|
||||
curl -s https://codecov.io/bash -o codecov-bash || echo "Failed to download codecov-bash"
|
||||
chmod +x codecov-bash || echo "Failed to apply execute permissions on codecov-bash"
|
||||
./codecov-bash -F windows || echo "Codecov did not collect coverage reports"
|
||||
condition: in(variables['TOXENV'], 'py37-cover', 'integration-certbot')
|
||||
env:
|
||||
CODECOV_TOKEN: $(codecov_token)
|
||||
displayName: Publish coverage
|
||||
|
||||
18
.codecov.yml
18
.codecov.yml
@@ -1,18 +0,0 @@
|
||||
coverage:
|
||||
status:
|
||||
project:
|
||||
default: off
|
||||
linux:
|
||||
flags: linux
|
||||
# Fixed target instead of auto set by #7173, can
|
||||
# be removed when flags in Codecov are added back.
|
||||
target: 97.4
|
||||
threshold: 0.1
|
||||
base: auto
|
||||
windows:
|
||||
flags: windows
|
||||
# Fixed target instead of auto set by #7173, can
|
||||
# be removed when flags in Codecov are added back.
|
||||
target: 97.4
|
||||
threshold: 0.1
|
||||
base: auto
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -26,6 +26,7 @@ tags
|
||||
\#*#
|
||||
.idea
|
||||
.ropeproject
|
||||
.vscode
|
||||
|
||||
# auth --cert-path --chain-path
|
||||
/*.pem
|
||||
|
||||
74
.travis.yml
74
.travis.yml
@@ -6,7 +6,6 @@ cache:
|
||||
- $HOME/.cache/pip
|
||||
|
||||
before_script:
|
||||
- 'if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ulimit -n 1024 ; fi'
|
||||
# On Travis, the fastest parallelization for integration tests has proved to be 4.
|
||||
- 'if [[ "$TOXENV" == *"integration"* ]]; then export PYTEST_ADDOPTS="--numprocesses 4"; fi'
|
||||
# Use Travis retry feature for farm tests since they are flaky
|
||||
@@ -14,17 +13,19 @@ before_script:
|
||||
- export TOX_TESTENV_PASSENV=TRAVIS
|
||||
|
||||
# Only build pushes to the master branch, PRs, and branches beginning with
|
||||
# `test-` or of the form `digit(s).digit(s).x`. This reduces the number of
|
||||
# simultaneous Travis runs, which speeds turnaround time on review since there
|
||||
# is a cap of on the number of simultaneous runs.
|
||||
# `test-`, `travis-test-`, or of the form `digit(s).digit(s).x`. This reduces
|
||||
# the number of simultaneous Travis runs, which speeds turnaround time on
|
||||
# review since there is a cap of on the number of simultaneous runs.
|
||||
branches:
|
||||
# When changing these branches, please ensure the documentation under
|
||||
# "Running tests in CI" is still correct.
|
||||
only:
|
||||
# apache-parser-v2 is a temporary branch for doing work related to
|
||||
# rewriting the parser in the Apache plugin.
|
||||
- apache-parser-v2
|
||||
- master
|
||||
- /^\d+\.\d+\.x$/
|
||||
- /^test-.*$/
|
||||
- /^(travis-)?test-.*$/
|
||||
|
||||
# Jobs for the main test suite are always executed (including on PRs) except for pushes on master.
|
||||
not-on-master: ¬-on-master
|
||||
@@ -59,11 +60,8 @@ matrix:
|
||||
dist: trusty
|
||||
env: TOXENV='py27-{acme,apache,apache-v2,certbot,dns,nginx}-oldest'
|
||||
<<: *not-on-master
|
||||
- python: "3.4"
|
||||
env: TOXENV=py34
|
||||
<<: *not-on-master
|
||||
- python: "3.7"
|
||||
env: TOXENV=py37
|
||||
- python: "3.5"
|
||||
env: TOXENV=py35
|
||||
<<: *not-on-master
|
||||
- python: "3.8"
|
||||
env: TOXENV=py38
|
||||
@@ -163,31 +161,12 @@ matrix:
|
||||
sudo: required
|
||||
services: docker
|
||||
<<: *extended-test-suite
|
||||
- python: "3.4"
|
||||
env: TOXENV=py34
|
||||
<<: *extended-test-suite
|
||||
- python: "3.5"
|
||||
env: TOXENV=py35
|
||||
<<: *extended-test-suite
|
||||
- python: "3.6"
|
||||
env: TOXENV=py36
|
||||
<<: *extended-test-suite
|
||||
- python: "3.7"
|
||||
env: TOXENV=py37
|
||||
<<: *extended-test-suite
|
||||
- python: "3.8"
|
||||
env: TOXENV=py38
|
||||
<<: *extended-test-suite
|
||||
- python: "3.4"
|
||||
env: ACME_SERVER=boulder-v1 TOXENV=integration
|
||||
sudo: required
|
||||
services: docker
|
||||
<<: *extended-test-suite
|
||||
- python: "3.4"
|
||||
env: ACME_SERVER=boulder-v2 TOXENV=integration
|
||||
sudo: required
|
||||
services: docker
|
||||
<<: *extended-test-suite
|
||||
- python: "3.5"
|
||||
env: ACME_SERVER=boulder-v1 TOXENV=integration
|
||||
sudo: required
|
||||
@@ -232,6 +211,10 @@ matrix:
|
||||
env: TOXENV=le_auto_centos6
|
||||
services: docker
|
||||
<<: *extended-test-suite
|
||||
- sudo: required
|
||||
env: TOXENV=le_auto_oraclelinux6
|
||||
services: docker
|
||||
<<: *extended-test-suite
|
||||
- sudo: required
|
||||
env: TOXENV=docker_dev
|
||||
services: docker
|
||||
@@ -240,30 +223,6 @@ matrix:
|
||||
packages: # don't install nginx and apache
|
||||
- libaugeas0
|
||||
<<: *extended-test-suite
|
||||
- language: generic
|
||||
env: TOXENV=py27
|
||||
os: osx
|
||||
# Using this osx_image is a workaround for
|
||||
# https://travis-ci.community/t/xcode-8-3-homebrew-outdated-error/3798.
|
||||
osx_image: xcode10.2
|
||||
addons:
|
||||
homebrew:
|
||||
packages:
|
||||
- augeas
|
||||
- python2
|
||||
<<: *extended-test-suite
|
||||
- language: generic
|
||||
env: TOXENV=py3
|
||||
os: osx
|
||||
# Using this osx_image is a workaround for
|
||||
# https://travis-ci.community/t/xcode-8-3-homebrew-outdated-error/3798.
|
||||
osx_image: xcode10.2
|
||||
addons:
|
||||
homebrew:
|
||||
packages:
|
||||
- augeas
|
||||
- python3
|
||||
<<: *extended-test-suite
|
||||
|
||||
# container-based infrastructure
|
||||
sudo: false
|
||||
@@ -285,19 +244,20 @@ addons:
|
||||
# except in tests where the environment variable CERTBOT_NO_PIN is set.
|
||||
# virtualenv is listed here explicitly to make sure it is upgraded when
|
||||
# CERTBOT_NO_PIN is set to work around failures we've seen when using an older
|
||||
# version of virtualenv.
|
||||
install: 'tools/pip_install.py -U codecov tox virtualenv'
|
||||
# version of virtualenv. The option "-I" is set so when CERTBOT_NO_PIN is also
|
||||
# set, pip updates dependencies it thinks are already satisfied to avoid some
|
||||
# problems with its lack of real dependency resolution.
|
||||
install: 'tools/pip_install.py -I tox virtualenv'
|
||||
# Most of the time TRAVIS_RETRY is an empty string, and has no effect on the
|
||||
# script command. It is set only to `travis_retry` during farm tests, in
|
||||
# order to trigger the Travis retry feature, and compensate the inherent
|
||||
# flakiness of these specific tests.
|
||||
script: '$TRAVIS_RETRY tox'
|
||||
|
||||
after_success: '[ "$TOXENV" == "py27-cover" ] && codecov -F linux'
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
irc:
|
||||
if: NOT branch =~ ^(travis-)?test-.*$
|
||||
channels:
|
||||
# This is set to a secure variable to prevent forks from sending
|
||||
# notifications. This value was created by installing
|
||||
|
||||
@@ -36,6 +36,7 @@ Authors
|
||||
* [Brad Warren](https://github.com/bmw)
|
||||
* [Brandon Kraft](https://github.com/kraftbj)
|
||||
* [Brandon Kreisel](https://github.com/kraftbj)
|
||||
* [Cameron Steel](https://github.com/Tugzrida)
|
||||
* [Ceesjan Luiten](https://github.com/quinox)
|
||||
* [Chad Whitacre](https://github.com/whit537)
|
||||
* [Chhatoi Pritam Baral](https://github.com/pritambaral)
|
||||
@@ -100,6 +101,7 @@ Authors
|
||||
* [Harlan Lieberman-Berg](https://github.com/hlieberman)
|
||||
* [Henri Salo](https://github.com/fgeek)
|
||||
* [Henry Chen](https://github.com/henrychen95)
|
||||
* [Hugo van Kemenade](https://github.com/hugovk)
|
||||
* [Ingolf Becker](https://github.com/watercrossing)
|
||||
* [Jaap Eldering](https://github.com/eldering)
|
||||
* [Jacob Hoffman-Andrews](https://github.com/jsha)
|
||||
@@ -124,6 +126,7 @@ Authors
|
||||
* [Jonathan Herlin](https://github.com/Jonher937)
|
||||
* [Jon Walsh](https://github.com/code-tree)
|
||||
* [Joona Hoikkala](https://github.com/joohoi)
|
||||
* [Josh McCullough](https://github.com/JoshMcCullough)
|
||||
* [Josh Soref](https://github.com/jsoref)
|
||||
* [Joubin Jabbari](https://github.com/joubin)
|
||||
* [Juho Juopperi](https://github.com/jkjuopperi)
|
||||
|
||||
@@ -303,7 +303,7 @@ class HTTP01Response(KeyAuthorizationChallengeResponse):
|
||||
uri = chall.uri(domain)
|
||||
logger.debug("Verifying %s at %s...", chall.typ, uri)
|
||||
try:
|
||||
http_response = requests.get(uri)
|
||||
http_response = requests.get(uri, verify=False)
|
||||
except requests.exceptions.RequestException as error:
|
||||
logger.error("Unable to reach %s: %s", uri, error)
|
||||
return False
|
||||
|
||||
@@ -15,16 +15,16 @@ import requests
|
||||
from requests.adapters import HTTPAdapter
|
||||
from requests_toolbelt.adapters.source import SourceAddressAdapter
|
||||
import six
|
||||
from six.moves import http_client # pylint: disable=import-error
|
||||
from six.moves import http_client
|
||||
|
||||
from acme import crypto_util
|
||||
from acme import errors
|
||||
from acme import jws
|
||||
from acme import messages
|
||||
from acme.magic_typing import Dict # pylint: disable=unused-import, no-name-in-module
|
||||
from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module
|
||||
from acme.magic_typing import Set # pylint: disable=unused-import, no-name-in-module
|
||||
from acme.magic_typing import Text # pylint: disable=unused-import, no-name-in-module
|
||||
from acme.magic_typing import Dict
|
||||
from acme.magic_typing import List
|
||||
from acme.magic_typing import Set
|
||||
from acme.magic_typing import Text
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -36,7 +36,7 @@ if sys.version_info < (2, 7, 9): # pragma: no cover
|
||||
try:
|
||||
requests.packages.urllib3.contrib.pyopenssl.inject_into_urllib3() # type: ignore
|
||||
except AttributeError:
|
||||
import urllib3.contrib.pyopenssl # pylint: disable=import-error
|
||||
import urllib3.contrib.pyopenssl
|
||||
urllib3.contrib.pyopenssl.inject_into_urllib3()
|
||||
|
||||
DEFAULT_NETWORK_TIMEOUT = 45
|
||||
@@ -666,7 +666,7 @@ class ClientV2(ClientBase):
|
||||
response = self._post(self.directory['newOrder'], order)
|
||||
body = messages.Order.from_json(response.json())
|
||||
authorizations = []
|
||||
for url in body.authorizations: # pylint: disable=not-an-iterable
|
||||
for url in body.authorizations:
|
||||
authorizations.append(self._authzr_from_response(self._post_as_get(url), uri=url))
|
||||
return messages.OrderResource(
|
||||
body=body,
|
||||
@@ -942,7 +942,7 @@ class ClientNetwork(object):
|
||||
:param messages.RegistrationResource account: Account object. Required if you are
|
||||
planning to use .post() with acme_version=2 for anything other than
|
||||
creating a new account; may be set later after registering.
|
||||
:param josepy.JWASignature alg: Algoritm to use in signing JWS.
|
||||
:param josepy.JWASignature alg: Algorithm to use in signing JWS.
|
||||
:param bool verify_ssl: Whether to verify certificates on SSL connections.
|
||||
:param str user_agent: String to send as User-Agent header.
|
||||
:param float timeout: Timeout for requests.
|
||||
@@ -1022,6 +1022,9 @@ class ClientNetwork(object):
|
||||
|
||||
"""
|
||||
response_ct = response.headers.get('Content-Type')
|
||||
# Strip parameters from the media-type (rfc2616#section-3.7)
|
||||
if response_ct:
|
||||
response_ct = response_ct.split(';')[0].strip()
|
||||
try:
|
||||
# TODO: response.json() is called twice, once here, and
|
||||
# once in _get and _post clients
|
||||
|
||||
@@ -11,10 +11,9 @@ from OpenSSL import crypto
|
||||
from OpenSSL import SSL # type: ignore # https://github.com/python/typeshed/issues/2052
|
||||
|
||||
from acme import errors
|
||||
from acme.magic_typing import Callable # pylint: disable=unused-import, no-name-in-module
|
||||
from acme.magic_typing import Optional # pylint: disable=unused-import, no-name-in-module
|
||||
from acme.magic_typing import Tuple # pylint: disable=unused-import, no-name-in-module
|
||||
from acme.magic_typing import Union # pylint: disable=unused-import, no-name-in-module
|
||||
from acme.magic_typing import Callable
|
||||
from acme.magic_typing import Tuple
|
||||
from acme.magic_typing import Union
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -74,7 +73,7 @@ class SSLSocket(object):
|
||||
class FakeConnection(object):
|
||||
"""Fake OpenSSL.SSL.Connection."""
|
||||
|
||||
# pylint: disable=missing-docstring
|
||||
# pylint: disable=missing-function-docstring
|
||||
|
||||
def __init__(self, connection):
|
||||
self._wrapped = connection
|
||||
@@ -86,7 +85,7 @@ class SSLSocket(object):
|
||||
# OpenSSL.SSL.Connection.shutdown doesn't accept any args
|
||||
return self._wrapped.shutdown()
|
||||
|
||||
def accept(self): # pylint: disable=missing-docstring
|
||||
def accept(self): # pylint: disable=missing-function-docstring
|
||||
sock, addr = self.sock.accept()
|
||||
|
||||
context = SSL.Context(self.method)
|
||||
@@ -298,7 +297,6 @@ def dump_pyopenssl_chain(chain, filetype=crypto.FILETYPE_PEM):
|
||||
|
||||
def _dump_cert(cert):
|
||||
if isinstance(cert, jose.ComparableX509):
|
||||
# pylint: disable=protected-access
|
||||
cert = cert.wrapped
|
||||
return crypto.dump_certificate(filetype, cert)
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ class Header(jose.Header):
|
||||
url = jose.Field('url', omitempty=True)
|
||||
|
||||
@nonce.decoder
|
||||
def nonce(value): # pylint: disable=missing-docstring,no-self-argument
|
||||
def nonce(value): # pylint: disable=no-self-argument,missing-function-docstring
|
||||
try:
|
||||
return jose.decode_b64jose(value)
|
||||
except jose.DeserializationError as error:
|
||||
|
||||
@@ -10,7 +10,6 @@ class TypingClass(object):
|
||||
try:
|
||||
# mypy doesn't respect modifying sys.modules
|
||||
from typing import * # pylint: disable=wildcard-import, unused-wildcard-import
|
||||
# pylint: disable=unused-import
|
||||
from typing import Collection, IO # type: ignore
|
||||
# pylint: enable=unused-import
|
||||
except ImportError:
|
||||
|
||||
@@ -11,7 +11,7 @@ from acme import jws
|
||||
from acme import util
|
||||
|
||||
try:
|
||||
from collections.abc import Hashable # pylint: disable=no-name-in-module
|
||||
from collections.abc import Hashable
|
||||
except ImportError: # pragma: no cover
|
||||
from collections import Hashable
|
||||
|
||||
@@ -36,7 +36,7 @@ ERROR_CODES = {
|
||||
' domain'),
|
||||
'dns': 'There was a problem with a DNS query during identifier validation',
|
||||
'dnssec': 'The server could not validate a DNSSEC signed domain',
|
||||
'incorrectResponse': 'Response recieved didn\'t match the challenge\'s requirements',
|
||||
'incorrectResponse': 'Response received didn\'t match the challenge\'s requirements',
|
||||
# deprecate invalidEmail
|
||||
'invalidEmail': 'The provided email for a registration was invalid',
|
||||
'invalidContact': 'The provided contact URI was invalid',
|
||||
@@ -245,13 +245,13 @@ class Directory(jose.JSONDeSerializable):
|
||||
try:
|
||||
return self[name.replace('_', '-')]
|
||||
except KeyError as error:
|
||||
raise AttributeError(str(error) + ': ' + name)
|
||||
raise AttributeError(str(error))
|
||||
|
||||
def __getitem__(self, name):
|
||||
try:
|
||||
return self._jobj[self._canon_key(name)]
|
||||
except KeyError:
|
||||
raise KeyError('Directory field not found')
|
||||
raise KeyError('Directory field "' + self._canon_key(name) + '" not found')
|
||||
|
||||
def to_partial_json(self):
|
||||
return self._jobj
|
||||
@@ -460,7 +460,6 @@ class ChallengeResource(Resource):
|
||||
@property
|
||||
def uri(self):
|
||||
"""The URL of the challenge body."""
|
||||
# pylint: disable=function-redefined,no-member
|
||||
return self.body.uri
|
||||
|
||||
|
||||
@@ -488,7 +487,7 @@ class Authorization(ResourceBody):
|
||||
wildcard = jose.Field('wildcard', omitempty=True)
|
||||
|
||||
@challenges.decoder
|
||||
def challenges(value): # pylint: disable=missing-docstring,no-self-argument
|
||||
def challenges(value): # pylint: disable=no-self-argument,missing-function-docstring
|
||||
return tuple(ChallengeBody.from_json(chall) for chall in value)
|
||||
|
||||
@property
|
||||
@@ -585,7 +584,7 @@ class Order(ResourceBody):
|
||||
error = jose.Field('error', omitempty=True, decoder=Error.from_json)
|
||||
|
||||
@identifiers.decoder
|
||||
def identifiers(value): # pylint: disable=missing-docstring,no-self-argument
|
||||
def identifiers(value): # pylint: disable=no-self-argument,missing-function-docstring
|
||||
return tuple(Identifier.from_json(identifier) for identifier in value)
|
||||
|
||||
class OrderResource(ResourceWithURI):
|
||||
|
||||
@@ -5,19 +5,16 @@ import logging
|
||||
import socket
|
||||
import threading
|
||||
|
||||
from six.moves import BaseHTTPServer # type: ignore # pylint: disable=import-error
|
||||
from six.moves import http_client # pylint: disable=import-error
|
||||
from six.moves import socketserver # type: ignore # pylint: disable=import-error
|
||||
from six.moves import BaseHTTPServer # type: ignore
|
||||
from six.moves import http_client
|
||||
from six.moves import socketserver # type: ignore
|
||||
|
||||
from acme import challenges
|
||||
from acme import crypto_util
|
||||
from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module
|
||||
from acme.magic_typing import List
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# six.moves.* | pylint: disable=no-member,attribute-defined-outside-init
|
||||
# pylint: disable=no-init
|
||||
|
||||
|
||||
class TLSServer(socketserver.TCPServer):
|
||||
"""Generic TLS Server."""
|
||||
@@ -30,7 +27,6 @@ class TLSServer(socketserver.TCPServer):
|
||||
self.address_family = socket.AF_INET
|
||||
self.certs = kwargs.pop("certs", {})
|
||||
self.method = kwargs.pop(
|
||||
# pylint: disable=protected-access
|
||||
"method", crypto_util._DEFAULT_SSL_METHOD)
|
||||
self.allow_reuse_address = kwargs.pop("allow_reuse_address", True)
|
||||
socketserver.TCPServer.__init__(self, *args, **kwargs)
|
||||
@@ -39,7 +35,7 @@ class TLSServer(socketserver.TCPServer):
|
||||
self.socket = crypto_util.SSLSocket(
|
||||
self.socket, certs=self.certs, method=self.method)
|
||||
|
||||
def server_bind(self): # pylint: disable=missing-docstring
|
||||
def server_bind(self):
|
||||
self._wrap_sock()
|
||||
return socketserver.TCPServer.server_bind(self)
|
||||
|
||||
@@ -178,7 +174,7 @@ class HTTP01RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
|
||||
self.log_message("Incoming request")
|
||||
BaseHTTPServer.BaseHTTPRequestHandler.handle(self)
|
||||
|
||||
def do_GET(self): # pylint: disable=invalid-name,missing-docstring
|
||||
def do_GET(self): # pylint: disable=invalid-name,missing-function-docstring
|
||||
if self.path == "/":
|
||||
self.handle_index()
|
||||
elif self.path.startswith("/" + challenges.HTTP01.URI_ROOT_PATH):
|
||||
|
||||
@@ -41,7 +41,7 @@ extensions = [
|
||||
]
|
||||
|
||||
autodoc_member_order = 'bysource'
|
||||
autodoc_default_flags = ['show-inheritance', 'private-members']
|
||||
autodoc_default_flags = ['show-inheritance']
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
@@ -113,7 +113,7 @@ pygments_style = 'sphinx'
|
||||
#keep_warnings = False
|
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||
todo_include_todos = True
|
||||
todo_include_todos = False
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
@@ -4,7 +4,7 @@ from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
from setuptools.command.test import test as TestCommand
|
||||
|
||||
version = '1.1.0.dev0'
|
||||
version = '1.3.0'
|
||||
|
||||
# Please update tox.ini when modifying dependency version requirements
|
||||
install_requires = [
|
||||
@@ -61,7 +61,7 @@ setup(
|
||||
author="Certbot Project",
|
||||
author_email='client-dev@letsencrypt.org',
|
||||
license='Apache License 2.0',
|
||||
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*',
|
||||
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
|
||||
classifiers=[
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Intended Audience :: Developers',
|
||||
@@ -70,7 +70,6 @@ setup(
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
|
||||
@@ -181,7 +181,7 @@ class HTTP01ResponseTest(unittest.TestCase):
|
||||
mock_get.return_value = mock.MagicMock(text=validation)
|
||||
self.assertTrue(self.response.simple_verify(
|
||||
self.chall, "local", KEY.public_key()))
|
||||
mock_get.assert_called_once_with(self.chall.uri("local"))
|
||||
mock_get.assert_called_once_with(self.chall.uri("local"), verify=False)
|
||||
|
||||
@mock.patch("acme.challenges.requests.get")
|
||||
def test_simple_verify_bad_validation(self, mock_get):
|
||||
@@ -197,7 +197,7 @@ class HTTP01ResponseTest(unittest.TestCase):
|
||||
HTTP01Response.WHITESPACE_CUTSET))
|
||||
self.assertTrue(self.response.simple_verify(
|
||||
self.chall, "local", KEY.public_key()))
|
||||
mock_get.assert_called_once_with(self.chall.uri("local"))
|
||||
mock_get.assert_called_once_with(self.chall.uri("local"), verify=False)
|
||||
|
||||
@mock.patch("acme.challenges.requests.get")
|
||||
def test_simple_verify_connection_error(self, mock_get):
|
||||
|
||||
@@ -980,6 +980,35 @@ class ClientNetworkTest(unittest.TestCase):
|
||||
self.assertEqual(
|
||||
self.response, self.net._check_response(self.response))
|
||||
|
||||
@mock.patch('acme.client.logger')
|
||||
def test_check_response_ok_ct_with_charset(self, mock_logger):
|
||||
self.response.json.return_value = {}
|
||||
self.response.headers['Content-Type'] = 'application/json; charset=utf-8'
|
||||
# pylint: disable=protected-access
|
||||
self.assertEqual(self.response, self.net._check_response(
|
||||
self.response, content_type='application/json'))
|
||||
try:
|
||||
mock_logger.debug.assert_called_with(
|
||||
'Ignoring wrong Content-Type (%r) for JSON decodable response',
|
||||
'application/json; charset=utf-8'
|
||||
)
|
||||
except AssertionError:
|
||||
return
|
||||
raise AssertionError('Expected Content-Type warning ' #pragma: no cover
|
||||
'to not have been logged')
|
||||
|
||||
@mock.patch('acme.client.logger')
|
||||
def test_check_response_ok_bad_ct(self, mock_logger):
|
||||
self.response.json.return_value = {}
|
||||
self.response.headers['Content-Type'] = 'text/plain'
|
||||
# pylint: disable=protected-access
|
||||
self.assertEqual(self.response, self.net._check_response(
|
||||
self.response, content_type='application/json'))
|
||||
mock_logger.debug.assert_called_with(
|
||||
'Ignoring wrong Content-Type (%r) for JSON decodable response',
|
||||
'text/plain'
|
||||
)
|
||||
|
||||
def test_check_response_conflict(self):
|
||||
self.response.ok = False
|
||||
self.response.status_code = 409
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
include LICENSE.txt
|
||||
include README.rst
|
||||
recursive-include tests *
|
||||
include certbot_apache/_internal/centos-options-ssl-apache.conf
|
||||
include certbot_apache/_internal/options-ssl-apache.conf
|
||||
recursive-include certbot_apache/_internal/augeas_lens *.aug
|
||||
global-exclude __pycache__
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
# This file contains important security parameters. If you modify this file
|
||||
# manually, Certbot will be unable to automatically provide future security
|
||||
# updates. Instead, Certbot will print and log an error message with a path to
|
||||
# the up-to-date file that you will need to refer to when manually updating
|
||||
# this file.
|
||||
|
||||
SSLEngine on
|
||||
|
||||
# Intermediate configuration, tweak to your needs
|
||||
SSLProtocol all -SSLv2 -SSLv3
|
||||
SSLCipherSuite ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS
|
||||
SSLHonorCipherOrder on
|
||||
|
||||
SSLOptions +StrictRequire
|
||||
|
||||
# Add vhost name to log entries:
|
||||
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" vhost_combined
|
||||
LogFormat "%v %h %l %u %t \"%r\" %>s %b" vhost_common
|
||||
|
||||
#CustomLog /var/log/apache2/access.log vhost_combined
|
||||
#LogLevel warn
|
||||
#ErrorLog /var/log/apache2/error.log
|
||||
|
||||
# Always ensure Cookies have "Secure" set (JAH 2012/1)
|
||||
#Header edit Set-Cookie (?i)^(.*)(;\s*secure)??((\s*;)?(.*)) "$1; Secure$3$4"
|
||||
@@ -14,11 +14,11 @@ import zope.component
|
||||
import zope.interface
|
||||
|
||||
from acme import challenges
|
||||
from acme.magic_typing import DefaultDict # pylint: disable=unused-import, no-name-in-module
|
||||
from acme.magic_typing import Dict # pylint: disable=unused-import, no-name-in-module
|
||||
from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module
|
||||
from acme.magic_typing import Set # pylint: disable=unused-import, no-name-in-module
|
||||
from acme.magic_typing import Union # pylint: disable=unused-import, no-name-in-module
|
||||
from acme.magic_typing import DefaultDict
|
||||
from acme.magic_typing import Dict
|
||||
from acme.magic_typing import List
|
||||
from acme.magic_typing import Set
|
||||
from acme.magic_typing import Union
|
||||
from certbot import errors
|
||||
from certbot import interfaces
|
||||
from certbot import util
|
||||
@@ -792,7 +792,7 @@ class ApacheConfigurator(common.Installer):
|
||||
|
||||
return util.get_filtered_names(all_names)
|
||||
|
||||
def get_name_from_ip(self, addr): # pylint: disable=no-self-use
|
||||
def get_name_from_ip(self, addr):
|
||||
"""Returns a reverse dns name if available.
|
||||
|
||||
:param addr: IP Address
|
||||
@@ -1726,7 +1726,7 @@ class ApacheConfigurator(common.Installer):
|
||||
######################################################################
|
||||
# Enhancements
|
||||
######################################################################
|
||||
def supported_enhancements(self): # pylint: disable=no-self-use
|
||||
def supported_enhancements(self):
|
||||
"""Returns currently supported enhancements."""
|
||||
return ["redirect", "ensure-http-header", "staple-ocsp"]
|
||||
|
||||
@@ -1946,7 +1946,7 @@ class ApacheConfigurator(common.Installer):
|
||||
ssl_vhost.filep)
|
||||
|
||||
def _verify_no_matching_http_header(self, ssl_vhost, header_substring):
|
||||
"""Checks to see if an there is an existing Header directive that
|
||||
"""Checks to see if there is an existing Header directive that
|
||||
contains the string header_substring.
|
||||
|
||||
:param ssl_vhost: vhost to check
|
||||
@@ -2292,7 +2292,7 @@ class ApacheConfigurator(common.Installer):
|
||||
vhost.enabled = True
|
||||
return
|
||||
|
||||
def enable_mod(self, mod_name, temp=False): # pylint: disable=unused-argument
|
||||
def enable_mod(self, mod_name, temp=False):
|
||||
"""Enables module in Apache.
|
||||
|
||||
Both enables and reloads Apache so module is active.
|
||||
@@ -2350,7 +2350,7 @@ class ApacheConfigurator(common.Installer):
|
||||
error = str(err)
|
||||
raise errors.MisconfigurationError(error)
|
||||
|
||||
def config_test(self): # pylint: disable=no-self-use
|
||||
def config_test(self):
|
||||
"""Check the configuration of Apache for errors.
|
||||
|
||||
:raises .errors.MisconfigurationError: If config_test fails
|
||||
@@ -2400,7 +2400,7 @@ class ApacheConfigurator(common.Installer):
|
||||
###########################################################################
|
||||
# Challenges Section
|
||||
###########################################################################
|
||||
def get_chall_pref(self, unused_domain): # pylint: disable=no-self-use
|
||||
def get_chall_pref(self, unused_domain):
|
||||
"""Return list of challenge preferences."""
|
||||
return [challenges.HTTP01]
|
||||
|
||||
@@ -2471,7 +2471,7 @@ class ApacheConfigurator(common.Installer):
|
||||
:type _unused_lineage: certbot._internal.storage.RenewableCert
|
||||
|
||||
:param domains: List of domains in certificate to enhance
|
||||
:type domains: str
|
||||
:type domains: `list` of `str`
|
||||
"""
|
||||
|
||||
self._autohsts_fetch_state()
|
||||
|
||||
@@ -24,6 +24,8 @@ ALL_SSL_OPTIONS_HASHES = [
|
||||
'0fcdc81280cd179a07ec4d29d3595068b9326b455c488de4b09f585d5dafc137',
|
||||
'86cc09ad5415cd6d5f09a947fe2501a9344328b1e8a8b458107ea903e80baa6c',
|
||||
'06675349e457eae856120cdebb564efe546f0b87399f2264baeb41e442c724c7',
|
||||
'5cc003edd93fb9cd03d40c7686495f8f058f485f75b5e764b789245a386e6daf',
|
||||
'007cd497a56a3bb8b6a2c1aeb4997789e7e38992f74e44cc5d13a625a738ac73',
|
||||
]
|
||||
"""SHA256 hashes of the contents of previous versions of all versions of MOD_SSL_CONF_SRC"""
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
""" Entry point for Apache Plugin """
|
||||
# Pylint does not like disutils.version when running inside a venv.
|
||||
# See: https://github.com/PyCQA/pylint/issues/73
|
||||
from distutils.version import LooseVersion # pylint: disable=no-name-in-module,import-error
|
||||
from distutils.version import LooseVersion
|
||||
|
||||
from certbot import util
|
||||
from certbot_apache._internal import configurator
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
"""A class that performs HTTP-01 challenges for Apache"""
|
||||
import logging
|
||||
import errno
|
||||
|
||||
from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module
|
||||
from acme.magic_typing import Set # pylint: disable=unused-import, no-name-in-module
|
||||
from acme.magic_typing import List
|
||||
from acme.magic_typing import Set
|
||||
from certbot import errors
|
||||
from certbot.compat import filesystem
|
||||
from certbot.compat import os
|
||||
@@ -168,7 +169,15 @@ class ApacheHttp01(common.ChallengePerformer):
|
||||
|
||||
def _set_up_challenges(self):
|
||||
if not os.path.isdir(self.challenge_dir):
|
||||
filesystem.makedirs(self.challenge_dir, 0o755)
|
||||
old_umask = os.umask(0o022)
|
||||
try:
|
||||
filesystem.makedirs(self.challenge_dir, 0o755)
|
||||
except OSError as exception:
|
||||
if exception.errno not in (errno.EEXIST, errno.EISDIR):
|
||||
raise errors.PluginError(
|
||||
"Couldn't create root for http-01 challenge")
|
||||
finally:
|
||||
os.umask(old_umask)
|
||||
|
||||
responses = []
|
||||
for achall in self.achalls:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Module contains classes used by the Apache Configurator."""
|
||||
import re
|
||||
|
||||
from acme.magic_typing import Set # pylint: disable=unused-import, no-name-in-module
|
||||
from acme.magic_typing import Set
|
||||
from certbot.plugins import common
|
||||
|
||||
|
||||
|
||||
@@ -7,20 +7,12 @@
|
||||
SSLEngine on
|
||||
|
||||
# Intermediate configuration, tweak to your needs
|
||||
SSLProtocol all -SSLv2 -SSLv3
|
||||
SSLCipherSuite ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS
|
||||
SSLHonorCipherOrder on
|
||||
SSLCompression off
|
||||
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
|
||||
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
|
||||
SSLHonorCipherOrder off
|
||||
|
||||
SSLOptions +StrictRequire
|
||||
|
||||
# Add vhost name to log entries:
|
||||
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" vhost_combined
|
||||
LogFormat "%v %h %l %u %t \"%r\" %>s %b" vhost_common
|
||||
|
||||
#CustomLog /var/log/apache2/access.log vhost_combined
|
||||
#LogLevel warn
|
||||
#ErrorLog /var/log/apache2/error.log
|
||||
|
||||
# Always ensure Cookies have "Secure" set (JAH 2012/1)
|
||||
#Header edit Set-Cookie (?i)^(.*)(;\s*secure)??((\s*;)?(.*)) "$1; Secure$3$4"
|
||||
|
||||
@@ -4,7 +4,7 @@ import logging
|
||||
import pkg_resources
|
||||
import zope.interface
|
||||
|
||||
from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module
|
||||
from acme.magic_typing import List
|
||||
from certbot import errors
|
||||
from certbot import interfaces
|
||||
from certbot import util
|
||||
@@ -38,7 +38,7 @@ class CentOSConfigurator(configurator.ApacheConfigurator):
|
||||
handle_sites=False,
|
||||
challenge_location="/etc/httpd/conf.d",
|
||||
MOD_SSL_CONF_SRC=pkg_resources.resource_filename(
|
||||
"certbot_apache", os.path.join("_internal", "centos-options-ssl-apache.conf"))
|
||||
"certbot_apache", os.path.join("_internal", "options-ssl-apache.conf"))
|
||||
)
|
||||
|
||||
def config_test(self):
|
||||
|
||||
@@ -33,7 +33,7 @@ class FedoraConfigurator(configurator.ApacheConfigurator):
|
||||
challenge_location="/etc/httpd/conf.d",
|
||||
MOD_SSL_CONF_SRC=pkg_resources.resource_filename(
|
||||
# TODO: eventually newest version of Fedora will need their own config
|
||||
"certbot_apache", os.path.join("_internal", "centos-options-ssl-apache.conf"))
|
||||
"certbot_apache", os.path.join("_internal", "options-ssl-apache.conf"))
|
||||
)
|
||||
|
||||
def config_test(self):
|
||||
|
||||
@@ -7,9 +7,9 @@ import sys
|
||||
|
||||
import six
|
||||
|
||||
from acme.magic_typing import Dict # pylint: disable=unused-import, no-name-in-module
|
||||
from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module
|
||||
from acme.magic_typing import Set # pylint: disable=unused-import, no-name-in-module
|
||||
from acme.magic_typing import Dict
|
||||
from acme.magic_typing import List
|
||||
from acme.magic_typing import Set
|
||||
from certbot import errors
|
||||
from certbot.compat import os
|
||||
from certbot_apache._internal import apache_util
|
||||
@@ -321,7 +321,7 @@ class ApacheParser(object):
|
||||
for mod in matches:
|
||||
self.add_mod(mod.strip())
|
||||
|
||||
def filter_args_num(self, matches, args): # pylint: disable=no-self-use
|
||||
def filter_args_num(self, matches, args):
|
||||
"""Filter out directives with specific number of arguments.
|
||||
|
||||
This function makes the assumption that all related arguments are given
|
||||
@@ -705,7 +705,7 @@ class ApacheParser(object):
|
||||
split_arg = arg.split("/")
|
||||
for idx, split in enumerate(split_arg):
|
||||
if any(char in ApacheParser.fnmatch_chars for char in split):
|
||||
# Turn it into a augeas regex
|
||||
# Turn it into an augeas regex
|
||||
# TODO: Can this instead be an augeas glob instead of regex
|
||||
split_arg[idx] = ("* [label()=~regexp('%s')]" %
|
||||
self.fnmatch_to_re(split))
|
||||
@@ -715,7 +715,7 @@ class ApacheParser(object):
|
||||
|
||||
return get_aug_path(arg)
|
||||
|
||||
def fnmatch_to_re(self, clean_fn_match): # pylint: disable=no-self-use
|
||||
def fnmatch_to_re(self, clean_fn_match):
|
||||
"""Method converts Apache's basic fnmatch to regular expression.
|
||||
|
||||
Assumption - Configs are assumed to be well-formed and only writable by
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Remember to update setup.py to match the package versions below.
|
||||
acme[dev]==0.29.0
|
||||
-e certbot[dev]
|
||||
certbot[dev]==1.1.0
|
||||
|
||||
@@ -4,13 +4,13 @@ from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
from setuptools.command.test import test as TestCommand
|
||||
|
||||
version = '1.1.0.dev0'
|
||||
version = '1.3.0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
install_requires = [
|
||||
'acme>=0.29.0',
|
||||
'certbot>=1.0.0.dev0',
|
||||
'certbot>=1.1.0',
|
||||
'mock',
|
||||
'python-augeas',
|
||||
'setuptools',
|
||||
@@ -45,7 +45,7 @@ setup(
|
||||
author="Certbot Project",
|
||||
author_email='client-dev@letsencrypt.org',
|
||||
license='Apache License 2.0',
|
||||
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*',
|
||||
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
|
||||
classifiers=[
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Environment :: Plugins',
|
||||
@@ -56,7 +56,6 @@ setup(
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"""Test for certbot_apache._internal.http_01."""
|
||||
import unittest
|
||||
import errno
|
||||
|
||||
import mock
|
||||
|
||||
@@ -197,6 +198,12 @@ class ApacheHttp01Test(util.ApacheTest):
|
||||
|
||||
self.assertTrue(os.path.exists(challenge_dir))
|
||||
|
||||
@mock.patch("certbot_apache._internal.http_01.filesystem.makedirs")
|
||||
def test_failed_makedirs(self, mock_makedirs):
|
||||
mock_makedirs.side_effect = OSError(errno.EACCES, "msg")
|
||||
self.http.add_chall(self.achalls[0])
|
||||
self.assertRaises(errors.PluginError, self.http.perform)
|
||||
|
||||
def _test_challenge_conf(self):
|
||||
with open(self.http.challenge_conf_pre) as f:
|
||||
pre_conf_contents = f.read()
|
||||
|
||||
@@ -26,7 +26,7 @@ Listen 443
|
||||
|
||||
# Pass Phrase Dialog:
|
||||
# Configure the pass phrase gathering process.
|
||||
# The filtering dialog program (`builtin' is a internal
|
||||
# The filtering dialog program (`builtin' is an internal
|
||||
# terminal dialog) has to provide the pass phrase on stdout.
|
||||
SSLPassPhraseDialog builtin
|
||||
|
||||
|
||||
@@ -702,7 +702,7 @@ IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t
|
||||
# English (en) - Esperanto (eo) - Estonian (et) - French (fr) - German (de)
|
||||
# Greek-Modern (el) - Hebrew (he) - Italian (it) - Japanese (ja)
|
||||
# Korean (ko) - Luxembourgeois* (ltz) - Norwegian Nynorsk (nn)
|
||||
# Norwegian (no) - Polish (pl) - Portugese (pt)
|
||||
# Norwegian (no) - Polish (pl) - Portuguese (pt)
|
||||
# Brazilian Portuguese (pt-BR) - Russian (ru) - Swedish (sv)
|
||||
# Simplified Chinese (zh-CN) - Spanish (es) - Traditional Chinese (zh-TW)
|
||||
#
|
||||
|
||||
@@ -13,7 +13,7 @@ Listen 443 https
|
||||
|
||||
# Pass Phrase Dialog:
|
||||
# Configure the pass phrase gathering process.
|
||||
# The filtering dialog program (`builtin' is a internal
|
||||
# The filtering dialog program (`builtin' is an internal
|
||||
# terminal dialog) has to provide the pass phrase on stdout.
|
||||
SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
# Pass Phrase Dialog:
|
||||
# Configure the pass phrase gathering process.
|
||||
# The filtering dialog program (`builtin' is a internal
|
||||
# The filtering dialog program (`builtin' is an internal
|
||||
# terminal dialog) has to provide the pass phrase on stdout.
|
||||
SSLPassPhraseDialog exec:/usr/share/apache2/ask-for-passphrase
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
# Pass Phrase Dialog:
|
||||
# Configure the pass phrase gathering process.
|
||||
# The filtering dialog program (`builtin' is a internal
|
||||
# The filtering dialog program (`builtin' is an internal
|
||||
# terminal dialog) has to provide the pass phrase on stdout.
|
||||
SSLPassPhraseDialog exec:/usr/share/apache2/ask-for-passphrase
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
# Pass Phrase Dialog:
|
||||
# Configure the pass phrase gathering process.
|
||||
# The filtering dialog program (`builtin' is a internal
|
||||
# The filtering dialog program (`builtin' is an internal
|
||||
# terminal dialog) has to provide the pass phrase on stdout.
|
||||
SSLPassPhraseDialog exec:/usr/share/apache2/ask-for-passphrase
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
# English (en) - Esperanto (eo) - Estonian (et) - French (fr) - German (de)
|
||||
# Greek-Modern (el) - Hebrew (he) - Italian (it) - Japanese (ja)
|
||||
# Korean (ko) - Luxembourgeois* (ltz) - Norwegian Nynorsk (nn)
|
||||
# Norwegian (no) - Polish (pl) - Portugese (pt)
|
||||
# Norwegian (no) - Polish (pl) - Portuguese (pt)
|
||||
# Brazilian Portuguese (pt-BR) - Russian (ru) - Swedish (sv)
|
||||
# Simplified Chinese (zh-CN) - Spanish (es) - Traditional Chinese (zh-TW)
|
||||
AddLanguage ca .ca
|
||||
|
||||
@@ -43,7 +43,7 @@ SSLRandomSeed connect builtin
|
||||
|
||||
## Pass Phrase Dialog:
|
||||
# Configure the pass phrase gathering process. The filtering dialog program
|
||||
# (`builtin' is a internal terminal dialog) has to provide the pass phrase on
|
||||
# (`builtin' is an internal terminal dialog) has to provide the pass phrase on
|
||||
# stdout.
|
||||
SSLPassPhraseDialog builtin
|
||||
|
||||
|
||||
502
certbot-auto
502
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.0.0"
|
||||
LE_AUTO_VERSION="1.3.0"
|
||||
BASENAME=$(basename $0)
|
||||
USAGE="Usage: $BASENAME [OPTIONS]
|
||||
A self-updating wrapper script for the Certbot ACME client. When run, updates
|
||||
@@ -256,20 +256,28 @@ DeprecationBootstrap() {
|
||||
fi
|
||||
}
|
||||
|
||||
MIN_PYTHON_VERSION="2.7"
|
||||
MIN_PYVER=$(echo "$MIN_PYTHON_VERSION" | sed 's/\.//')
|
||||
MIN_PYTHON_2_VERSION="2.7"
|
||||
MIN_PYVER2=$(echo "$MIN_PYTHON_2_VERSION" | sed 's/\.//')
|
||||
MIN_PYTHON_3_VERSION="3.5"
|
||||
MIN_PYVER3=$(echo "$MIN_PYTHON_3_VERSION" | sed 's/\.//')
|
||||
# Sets LE_PYTHON to Python version string and PYVER to the first two
|
||||
# digits of the python version
|
||||
# digits of the python version.
|
||||
# MIN_PYVER and MIN_PYTHON_VERSION are also set by this function, and their
|
||||
# values depend on if we try to use Python 3 or Python 2.
|
||||
DeterminePythonVersion() {
|
||||
# Arguments: "NOCRASH" if we shouldn't crash if we don't find a good python
|
||||
#
|
||||
# If no Python is found, PYVER is set to 0.
|
||||
if [ "$USE_PYTHON_3" = 1 ]; then
|
||||
MIN_PYVER=$MIN_PYVER3
|
||||
MIN_PYTHON_VERSION=$MIN_PYTHON_3_VERSION
|
||||
for LE_PYTHON in "$LE_PYTHON" python3; do
|
||||
# Break (while keeping the LE_PYTHON value) if found.
|
||||
$EXISTS "$LE_PYTHON" > /dev/null && break
|
||||
done
|
||||
else
|
||||
MIN_PYVER=$MIN_PYVER2
|
||||
MIN_PYTHON_VERSION=$MIN_PYTHON_2_VERSION
|
||||
for LE_PYTHON in "$LE_PYTHON" python2.7 python27 python2 python; do
|
||||
# Break (while keeping the LE_PYTHON value) if found.
|
||||
$EXISTS "$LE_PYTHON" > /dev/null && break
|
||||
@@ -285,7 +293,7 @@ DeterminePythonVersion() {
|
||||
fi
|
||||
fi
|
||||
|
||||
PYVER=`"$LE_PYTHON" -V 2>&1 | cut -d" " -f 2 | cut -d. -f1,2 | sed 's/\.//'`
|
||||
PYVER=$("$LE_PYTHON" -V 2>&1 | cut -d" " -f 2 | cut -d. -f1,2 | sed 's/\.//')
|
||||
if [ "$PYVER" -lt "$MIN_PYVER" ]; then
|
||||
if [ "$1" != "NOCRASH" ]; then
|
||||
error "You have an ancient version of Python entombed in your operating system..."
|
||||
@@ -368,7 +376,9 @@ BootstrapDebCommon() {
|
||||
|
||||
# Sets TOOL to the name of the package manager
|
||||
# Sets appropriate values for YES_FLAG and QUIET_FLAG based on $ASSUME_YES and $QUIET_FLAG.
|
||||
# Enables EPEL if applicable and possible.
|
||||
# Note: this function is called both while selecting the bootstrap scripts and
|
||||
# during the actual bootstrap. Some things like prompting to user can be done in the latter
|
||||
# case, but not in the former one.
|
||||
InitializeRPMCommonBase() {
|
||||
if type dnf 2>/dev/null
|
||||
then
|
||||
@@ -388,26 +398,6 @@ InitializeRPMCommonBase() {
|
||||
if [ "$QUIET" = 1 ]; then
|
||||
QUIET_FLAG='--quiet'
|
||||
fi
|
||||
|
||||
if ! $TOOL list *virtualenv >/dev/null 2>&1; then
|
||||
echo "To use Certbot, packages from the EPEL repository need to be installed."
|
||||
if ! $TOOL list epel-release >/dev/null 2>&1; then
|
||||
error "Enable the EPEL repository and try running Certbot again."
|
||||
exit 1
|
||||
fi
|
||||
if [ "$ASSUME_YES" = 1 ]; then
|
||||
/bin/echo -n "Enabling the EPEL repository in 3 seconds..."
|
||||
sleep 1s
|
||||
/bin/echo -ne "\e[0K\rEnabling the EPEL repository in 2 seconds..."
|
||||
sleep 1s
|
||||
/bin/echo -e "\e[0K\rEnabling the EPEL repository in 1 second..."
|
||||
sleep 1s
|
||||
fi
|
||||
if ! $TOOL install $YES_FLAG $QUIET_FLAG epel-release; then
|
||||
error "Could not enable EPEL. Aborting bootstrap!"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
BootstrapRpmCommonBase() {
|
||||
@@ -488,13 +478,91 @@ BootstrapRpmCommon() {
|
||||
BootstrapRpmCommonBase "$python_pkgs"
|
||||
}
|
||||
|
||||
# If new packages are installed by BootstrapRpmPython3 below, this version
|
||||
# number must be increased.
|
||||
BOOTSTRAP_RPM_PYTHON3_LEGACY_VERSION=1
|
||||
|
||||
# Checks if rh-python36 can be installed.
|
||||
Python36SclIsAvailable() {
|
||||
InitializeRPMCommonBase >/dev/null 2>&1;
|
||||
|
||||
if "${TOOL}" list rh-python36 >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
if "${TOOL}" list centos-release-scl >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# Try to enable rh-python36 from SCL if it is necessary and possible.
|
||||
EnablePython36SCL() {
|
||||
if "$EXISTS" python3.6 > /dev/null 2> /dev/null; then
|
||||
return 0
|
||||
fi
|
||||
if [ ! -f /opt/rh/rh-python36/enable ]; then
|
||||
return 0
|
||||
fi
|
||||
set +e
|
||||
if ! . /opt/rh/rh-python36/enable; then
|
||||
error 'Unable to enable rh-python36!'
|
||||
exit 1
|
||||
fi
|
||||
set -e
|
||||
}
|
||||
|
||||
# This bootstrap concerns old RedHat-based distributions that do not ship by default
|
||||
# with Python 2.7, but only Python 2.6. We bootstrap them by enabling SCL and installing
|
||||
# Python 3.6. Some of these distributions are: CentOS/RHEL/OL/SL 6.
|
||||
BootstrapRpmPython3Legacy() {
|
||||
# Tested with:
|
||||
# - CentOS 6
|
||||
|
||||
InitializeRPMCommonBase
|
||||
|
||||
if ! "${TOOL}" list rh-python36 >/dev/null 2>&1; then
|
||||
echo "To use Certbot on this operating system, packages from the SCL repository need to be installed."
|
||||
if ! "${TOOL}" list centos-release-scl >/dev/null 2>&1; then
|
||||
error "Enable the SCL repository and try running Certbot again."
|
||||
exit 1
|
||||
fi
|
||||
if [ "${ASSUME_YES}" = 1 ]; then
|
||||
/bin/echo -n "Enabling the SCL repository in 3 seconds... (Press Ctrl-C to cancel)"
|
||||
sleep 1s
|
||||
/bin/echo -ne "\e[0K\rEnabling the SCL repository in 2 seconds... (Press Ctrl-C to cancel)"
|
||||
sleep 1s
|
||||
/bin/echo -e "\e[0K\rEnabling the SCL repository in 1 second... (Press Ctrl-C to cancel)"
|
||||
sleep 1s
|
||||
fi
|
||||
if ! "${TOOL}" install "${YES_FLAG}" "${QUIET_FLAG}" centos-release-scl; then
|
||||
error "Could not enable SCL. Aborting bootstrap!"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# CentOS 6 must use rh-python36 from SCL
|
||||
if "${TOOL}" list rh-python36 >/dev/null 2>&1; then
|
||||
python_pkgs="rh-python36-python
|
||||
rh-python36-python-virtualenv
|
||||
rh-python36-python-devel
|
||||
"
|
||||
else
|
||||
error "No supported Python package available to install. Aborting bootstrap!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BootstrapRpmCommonBase "${python_pkgs}"
|
||||
|
||||
# Enable SCL rh-python36 after bootstrapping.
|
||||
EnablePython36SCL
|
||||
}
|
||||
|
||||
# If new packages are installed by BootstrapRpmPython3 below, this version
|
||||
# number must be increased.
|
||||
BOOTSTRAP_RPM_PYTHON3_VERSION=1
|
||||
|
||||
BootstrapRpmPython3() {
|
||||
# Tested with:
|
||||
# - CentOS 6
|
||||
# - Fedora 29
|
||||
|
||||
InitializeRPMCommonBase
|
||||
@@ -505,12 +573,6 @@ BootstrapRpmPython3() {
|
||||
python3-virtualenv
|
||||
python3-devel
|
||||
"
|
||||
# EPEL uses python34
|
||||
elif $TOOL list python34 >/dev/null 2>&1; then
|
||||
python_pkgs="python34
|
||||
python34-devel
|
||||
python34-tools
|
||||
"
|
||||
else
|
||||
error "No supported Python package available to install. Aborting bootstrap!"
|
||||
exit 1
|
||||
@@ -758,6 +820,11 @@ elif [ -f /etc/redhat-release ]; then
|
||||
|
||||
RPM_DIST_NAME=`(. /etc/os-release 2> /dev/null && echo $ID) || echo "unknown"`
|
||||
|
||||
if [ "$PYVER" -eq 26 -a $(uname -m) != 'x86_64' ]; then
|
||||
# 32 bits CentOS 6 and affiliates are not supported anymore by certbot-auto.
|
||||
DEPRECATED_OS=1
|
||||
fi
|
||||
|
||||
# Set RPM_DIST_VERSION to VERSION_ID from /etc/os-release after splitting on
|
||||
# '.' characters (e.g. "8.0" becomes "8"). If the command exits with an
|
||||
# error, RPM_DIST_VERSION is set to "unknown".
|
||||
@@ -769,31 +836,50 @@ elif [ -f /etc/redhat-release ]; then
|
||||
RPM_DIST_VERSION=0
|
||||
fi
|
||||
|
||||
# Starting to Fedora 29, python2 is on a deprecation path. Let's move to python3 then.
|
||||
# RHEL 8 also uses python3 by default.
|
||||
if [ "$RPM_DIST_NAME" = "fedora" -a "$RPM_DIST_VERSION" -ge 29 -o "$PYVER" -eq 26 ]; then
|
||||
RPM_USE_PYTHON_3=1
|
||||
elif [ "$RPM_DIST_NAME" = "rhel" -a "$RPM_DIST_VERSION" -ge 8 ]; then
|
||||
RPM_USE_PYTHON_3=1
|
||||
elif [ "$RPM_DIST_NAME" = "centos" -a "$RPM_DIST_VERSION" -ge 8 ]; then
|
||||
RPM_USE_PYTHON_3=1
|
||||
else
|
||||
RPM_USE_PYTHON_3=0
|
||||
fi
|
||||
# Handle legacy RPM distributions
|
||||
if [ "$PYVER" -eq 26 ]; then
|
||||
# Check if an automated bootstrap can be achieved on this system.
|
||||
if ! Python36SclIsAvailable; then
|
||||
INTERACTIVE_BOOTSTRAP=1
|
||||
fi
|
||||
|
||||
if [ "$RPM_USE_PYTHON_3" = 1 ]; then
|
||||
Bootstrap() {
|
||||
BootstrapMessage "RedHat-based OSes that will use Python3"
|
||||
BootstrapRpmPython3
|
||||
BootstrapMessage "Legacy RedHat-based OSes that will use Python3"
|
||||
BootstrapRpmPython3Legacy
|
||||
}
|
||||
USE_PYTHON_3=1
|
||||
BOOTSTRAP_VERSION="BootstrapRpmPython3 $BOOTSTRAP_RPM_PYTHON3_VERSION"
|
||||
BOOTSTRAP_VERSION="BootstrapRpmPython3Legacy $BOOTSTRAP_RPM_PYTHON3_LEGACY_VERSION"
|
||||
|
||||
# Try now to enable SCL rh-python36 for systems already bootstrapped
|
||||
# NB: EnablePython36SCL has been defined along with BootstrapRpmPython3Legacy in certbot-auto
|
||||
EnablePython36SCL
|
||||
else
|
||||
Bootstrap() {
|
||||
BootstrapMessage "RedHat-based OSes"
|
||||
BootstrapRpmCommon
|
||||
}
|
||||
BOOTSTRAP_VERSION="BootstrapRpmCommon $BOOTSTRAP_RPM_COMMON_VERSION"
|
||||
# Starting to Fedora 29, python2 is on a deprecation path. Let's move to python3 then.
|
||||
# RHEL 8 also uses python3 by default.
|
||||
if [ "$RPM_DIST_NAME" = "fedora" -a "$RPM_DIST_VERSION" -ge 29 ]; then
|
||||
RPM_USE_PYTHON_3=1
|
||||
elif [ "$RPM_DIST_NAME" = "rhel" -a "$RPM_DIST_VERSION" -ge 8 ]; then
|
||||
RPM_USE_PYTHON_3=1
|
||||
elif [ "$RPM_DIST_NAME" = "centos" -a "$RPM_DIST_VERSION" -ge 8 ]; then
|
||||
RPM_USE_PYTHON_3=1
|
||||
else
|
||||
RPM_USE_PYTHON_3=0
|
||||
fi
|
||||
|
||||
if [ "$RPM_USE_PYTHON_3" = 1 ]; then
|
||||
Bootstrap() {
|
||||
BootstrapMessage "RedHat-based OSes that will use Python3"
|
||||
BootstrapRpmPython3
|
||||
}
|
||||
USE_PYTHON_3=1
|
||||
BOOTSTRAP_VERSION="BootstrapRpmPython3 $BOOTSTRAP_RPM_PYTHON3_VERSION"
|
||||
else
|
||||
Bootstrap() {
|
||||
BootstrapMessage "RedHat-based OSes"
|
||||
BootstrapRpmCommon
|
||||
}
|
||||
BOOTSTRAP_VERSION="BootstrapRpmCommon $BOOTSTRAP_RPM_COMMON_VERSION"
|
||||
fi
|
||||
fi
|
||||
|
||||
LE_PYTHON="$prev_le_python"
|
||||
@@ -870,6 +956,13 @@ if [ "$NO_BOOTSTRAP" = 1 ]; then
|
||||
unset BOOTSTRAP_VERSION
|
||||
fi
|
||||
|
||||
if [ "$DEPRECATED_OS" = 1 ]; then
|
||||
Bootstrap() {
|
||||
error "Skipping bootstrap because certbot-auto is deprecated on this system."
|
||||
}
|
||||
unset BOOTSTRAP_VERSION
|
||||
fi
|
||||
|
||||
# Sets PREV_BOOTSTRAP_VERSION to the identifier for the bootstrap script used
|
||||
# to install OS dependencies on this system. PREV_BOOTSTRAP_VERSION isn't set
|
||||
# if it is unknown how OS dependencies were installed on this system.
|
||||
@@ -1067,6 +1160,28 @@ if [ "$1" = "--le-auto-phase2" ]; then
|
||||
# Phase 2: Create venv, install LE, and run.
|
||||
|
||||
shift 1 # the --le-auto-phase2 arg
|
||||
|
||||
if [ "$DEPRECATED_OS" = 1 ]; then
|
||||
# Phase 2 damage control mode for deprecated OSes.
|
||||
# In this situation, we bypass any bootstrap or certbot venv setup.
|
||||
error "Your system is not supported by certbot-auto anymore."
|
||||
|
||||
if [ ! -d "$VENV_PATH" ] && OldVenvExists; then
|
||||
VENV_BIN="$OLD_VENV_PATH/bin"
|
||||
fi
|
||||
|
||||
if [ -f "$VENV_BIN/letsencrypt" -a "$INSTALL_ONLY" != 1 ]; then
|
||||
error "Certbot will no longer receive updates."
|
||||
error "Please visit https://certbot.eff.org/ to check for other alternatives."
|
||||
"$VENV_BIN/letsencrypt" "$@"
|
||||
exit 0
|
||||
else
|
||||
error "Certbot cannot be installed."
|
||||
error "Please visit https://certbot.eff.org/ to check for other alternatives."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
SetPrevBootstrapVersion
|
||||
|
||||
if [ -z "$PHASE_1_VERSION" -a "$USE_PYTHON_3" = 1 ]; then
|
||||
@@ -1078,8 +1193,15 @@ if [ "$1" = "--le-auto-phase2" ]; then
|
||||
# If the selected Bootstrap function isn't a noop and it differs from the
|
||||
# previously used version
|
||||
if [ -n "$BOOTSTRAP_VERSION" -a "$BOOTSTRAP_VERSION" != "$PREV_BOOTSTRAP_VERSION" ]; then
|
||||
# if non-interactive mode or stdin and stdout are connected to a terminal
|
||||
if [ \( "$NONINTERACTIVE" = 1 \) -o \( \( -t 0 \) -a \( -t 1 \) \) ]; then
|
||||
# Check if we can rebootstrap without manual user intervention: this requires that
|
||||
# certbot-auto is in non-interactive mode AND selected bootstrap does not claim to
|
||||
# require a manual user intervention.
|
||||
if [ "$NONINTERACTIVE" = 1 -a "$INTERACTIVE_BOOTSTRAP" != 1 ]; then
|
||||
CAN_REBOOTSTRAP=1
|
||||
fi
|
||||
# Check if rebootstrap can be done non-interactively and current shell is non-interactive
|
||||
# (true if stdin and stdout are not attached to a terminal).
|
||||
if [ \( "$CAN_REBOOTSTRAP" = 1 \) -o \( \( -t 0 \) -a \( -t 1 \) \) ]; then
|
||||
if [ -d "$VENV_PATH" ]; then
|
||||
rm -rf "$VENV_PATH"
|
||||
fi
|
||||
@@ -1090,12 +1212,21 @@ if [ "$1" = "--le-auto-phase2" ]; then
|
||||
ln -s "$VENV_PATH" "$OLD_VENV_PATH"
|
||||
fi
|
||||
RerunWithArgs "$@"
|
||||
# Otherwise bootstrap needs to be done manually by the user.
|
||||
else
|
||||
error "Skipping upgrade because new OS dependencies may need to be installed."
|
||||
error
|
||||
error "To upgrade to a newer version, please run this script again manually so you can"
|
||||
error "approve changes or with --non-interactive on the command line to automatically"
|
||||
error "install any required packages."
|
||||
# If it is because bootstrapping is interactive, --non-interactive will be of no use.
|
||||
if [ "$INTERACTIVE_BOOTSTRAP" = 1 ]; then
|
||||
error "Skipping upgrade because new OS dependencies may need to be installed."
|
||||
error "This requires manual user intervention: please run this script again manually."
|
||||
# If this is because of the environment (eg. non interactive shell without
|
||||
# --non-interactive flag set), help the user in that direction.
|
||||
else
|
||||
error "Skipping upgrade because new OS dependencies may need to be installed."
|
||||
error
|
||||
error "To upgrade to a newer version, please run this script again manually so you can"
|
||||
error "approve changes or with --non-interactive on the command line to automatically"
|
||||
error "install any required packages."
|
||||
fi
|
||||
# Set INSTALLED_VERSION to be the same so we don't update the venv
|
||||
INSTALLED_VERSION="$LE_AUTO_VERSION"
|
||||
# Continue to use OLD_VENV_PATH if the new venv doesn't exist
|
||||
@@ -1143,11 +1274,11 @@ if [ "$1" = "--le-auto-phase2" ]; then
|
||||
# pip install hashin
|
||||
# hashin -r dependency-requirements.txt cryptography==1.5.2
|
||||
# ```
|
||||
ConfigArgParse==0.14.0 \
|
||||
--hash=sha256:2e2efe2be3f90577aca9415e32cb629aa2ecd92078adbe27b53a03e53ff12e91
|
||||
certifi==2019.9.11 \
|
||||
--hash=sha256:e4f3620cfea4f83eedc95b24abd9cd56f3c4b146dd0177e83a21b4eb49e21e50 \
|
||||
--hash=sha256:fd7c7c74727ddcf00e9acd26bba8da604ffec95bf1c2144e67aff7a8b50e6cef
|
||||
ConfigArgParse==1.0 \
|
||||
--hash=sha256:bf378245bc9cdc403a527e5b7406b991680c2a530e7e81af747880b54eb57133
|
||||
certifi==2019.11.28 \
|
||||
--hash=sha256:017c25db2a153ce562900032d5bc68e9f191e44e9a0f762f373977de9df1fbb3 \
|
||||
--hash=sha256:25b64c7da4cd7479594d035c08c2d809eb4aab3a26e5a990ea98cc450c320f1f
|
||||
cffi==1.13.2 \
|
||||
--hash=sha256:0b49274afc941c626b605fb59b59c3485c17dc776dc3cc7cc14aca74cc19cc42 \
|
||||
--hash=sha256:0e3ea92942cb1168e38c05c1d56b0527ce31f1a370f6117f1d490b8dcd6b3a04 \
|
||||
@@ -1220,8 +1351,6 @@ enum34==1.1.6 \
|
||||
funcsigs==1.0.2 \
|
||||
--hash=sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca \
|
||||
--hash=sha256:a7bb0f2cf3a3fd1ab2732cb49eba4252c2af4240442415b4abce3b87022a8f50
|
||||
future==0.18.2 \
|
||||
--hash=sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d
|
||||
idna==2.8 \
|
||||
--hash=sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407 \
|
||||
--hash=sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c
|
||||
@@ -1234,40 +1363,40 @@ josepy==1.2.0 \
|
||||
mock==1.3.0 \
|
||||
--hash=sha256:1e247dbecc6ce057299eb7ee019ad68314bb93152e81d9a6110d35f4d5eca0f6 \
|
||||
--hash=sha256:3f573a18be94de886d1191f27c168427ef693e8dcfcecf95b170577b2eb69cbb
|
||||
parsedatetime==2.4 \
|
||||
--hash=sha256:3d817c58fb9570d1eec1dd46fa9448cd644eeed4fb612684b02dfda3a79cb84b \
|
||||
--hash=sha256:9ee3529454bf35c40a77115f5a596771e59e1aee8c53306f346c461b8e913094
|
||||
pbr==5.4.3 \
|
||||
--hash=sha256:2c8e420cd4ed4cec4e7999ee47409e876af575d4c35a45840d59e8b5f3155ab8 \
|
||||
--hash=sha256:b32c8ccaac7b1a20c0ce00ce317642e6cf231cf038f9875e0280e28af5bf7ac9
|
||||
pyOpenSSL==19.0.0 \
|
||||
--hash=sha256:aeca66338f6de19d1aa46ed634c3b9ae519a64b458f8468aec688e7e3c20f200 \
|
||||
--hash=sha256:c727930ad54b10fc157015014b666f2d8b41f70c0d03e83ab67624fd3dd5d1e6
|
||||
parsedatetime==2.5 \
|
||||
--hash=sha256:3b835fc54e472c17ef447be37458b400e3fefdf14bb1ffdedb5d2c853acf4ba1 \
|
||||
--hash=sha256:d2e9ddb1e463de871d32088a3f3cea3dc8282b1b2800e081bd0ef86900451667
|
||||
pbr==5.4.4 \
|
||||
--hash=sha256:139d2625547dbfa5fb0b81daebb39601c478c21956dc57e2e07b74450a8c506b \
|
||||
--hash=sha256:61aa52a0f18b71c5cc58232d2cf8f8d09cd67fcad60b742a60124cb8d6951488
|
||||
pyOpenSSL==19.1.0 \
|
||||
--hash=sha256:621880965a720b8ece2f1b2f54ea2071966ab00e2970ad2ce11d596102063504 \
|
||||
--hash=sha256:9a24494b2602aaf402be5c9e30a0b82d4a5c67528fe8fb475e3f3bc00dd69507
|
||||
pyRFC3339==1.1 \
|
||||
--hash=sha256:67196cb83b470709c580bb4738b83165e67c6cc60e1f2e4f286cfcb402a926f4 \
|
||||
--hash=sha256:81b8cbe1519cdb79bed04910dd6fa4e181faf8c88dff1e1b987b5f7ab23a5b1a
|
||||
pycparser==2.19 \
|
||||
--hash=sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3
|
||||
pyparsing==2.4.5 \
|
||||
--hash=sha256:20f995ecd72f2a1f4bf6b072b63b22e2eb457836601e76d6e5dfcd75436acc1f \
|
||||
--hash=sha256:4ca62001be367f01bd3e92ecbb79070272a9d4964dce6a48a82ff0b8bc7e683a
|
||||
pyparsing==2.4.6 \
|
||||
--hash=sha256:4c830582a84fb022400b85429791bc551f1f4871c33f23e44f353119e92f969f \
|
||||
--hash=sha256:c342dccb5250c08d45fd6f8b4a559613ca603b57498511740e65cd11a2e7dcec
|
||||
python-augeas==0.5.0 \
|
||||
--hash=sha256:67d59d66cdba8d624e0389b87b2a83a176f21f16a87553b50f5703b23f29bac2
|
||||
pytz==2019.3 \
|
||||
--hash=sha256:1c557d7d0e871de1f5ccd5833f60fb2550652da6be2693c1e02300743d21500d \
|
||||
--hash=sha256:b02c06db6cf09c12dd25137e563b31700d3b80fcc4ad23abb7a315f2789819be
|
||||
requests==2.21.0 \
|
||||
--hash=sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e \
|
||||
--hash=sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b
|
||||
requests==2.22.0 \
|
||||
--hash=sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4 \
|
||||
--hash=sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31
|
||||
requests-toolbelt==0.9.1 \
|
||||
--hash=sha256:380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f \
|
||||
--hash=sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0
|
||||
six==1.13.0 \
|
||||
--hash=sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd \
|
||||
--hash=sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66
|
||||
urllib3==1.24.3 \
|
||||
--hash=sha256:2393a695cd12afedd0dcb26fe5d50d0cf248e5a66f75dbd89a3d4eb333a61af4 \
|
||||
--hash=sha256:a637e5fae88995b256e3409dc4d52c2e2e0ba32c42a6365fee8bbd2238de3cfb
|
||||
six==1.14.0 \
|
||||
--hash=sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a \
|
||||
--hash=sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c
|
||||
urllib3==1.25.8 \
|
||||
--hash=sha256:2f3db8b19923a873b3e5256dc9c2dedfa883e33d87c690d9c7913e1f40673cdc \
|
||||
--hash=sha256:87716c2d2a7121198ebcb7ce7cccf6ce5e9ba539041cfbaeecfb641dc0bf6acc
|
||||
zope.component==4.6 \
|
||||
--hash=sha256:ec2afc5bbe611dcace98bb39822c122d44743d635dafc7315b9aef25097db9e6
|
||||
zope.deferredimport==4.3.1 \
|
||||
@@ -1279,47 +1408,86 @@ zope.deprecation==4.4.0 \
|
||||
zope.event==4.4 \
|
||||
--hash=sha256:69c27debad9bdacd9ce9b735dad382142281ac770c4a432b533d6d65c4614bcf \
|
||||
--hash=sha256:d8e97d165fd5a0997b45f5303ae11ea3338becfe68c401dd88ffd2113fe5cae7
|
||||
zope.hookable==4.2.0 \
|
||||
--hash=sha256:22886e421234e7e8cedc21202e1d0ab59960e40a47dd7240e9659a2d82c51370 \
|
||||
--hash=sha256:39912f446e45b4e1f1951b5ffa2d5c8b074d25727ec51855ae9eab5408f105ab \
|
||||
--hash=sha256:3adb7ea0871dbc56b78f62c4f5c024851fc74299f4f2a95f913025b076cde220 \
|
||||
--hash=sha256:3d7c4b96341c02553d8b8d71065a9366ef67e6c6feca714f269894646bb8268b \
|
||||
--hash=sha256:4e826a11a529ed0464ffcecf34b0b7bd1b4928dd5848c5c61bedd7833e8f4801 \
|
||||
--hash=sha256:700d68cc30728de1c4c62088a981c6daeaefdf20a0d81995d2c0b7f442c5f88c \
|
||||
--hash=sha256:77c82a430cedfbf508d1aa406b2f437363c24fa90c73f577ead0fb5295749b83 \
|
||||
--hash=sha256:c1df3929a3666fc5a0c80d60a0c1e6f6ef97c7f6ed2f1b7cf49f3e6f3d4dde15 \
|
||||
--hash=sha256:dba8b2dd2cd41cb5f37bfa3f3d82721b8ae10e492944e48ddd90a439227f2893 \
|
||||
--hash=sha256:f492540305b15b5591bd7195d61f28946bb071de071cee5d68b6b8414da90fd2
|
||||
zope.interface==4.6.0 \
|
||||
--hash=sha256:086707e0f413ff8800d9c4bc26e174f7ee4c9c8b0302fbad68d083071822316c \
|
||||
--hash=sha256:1157b1ec2a1f5bf45668421e3955c60c610e31913cc695b407a574efdbae1f7b \
|
||||
--hash=sha256:11ebddf765bff3bbe8dbce10c86884d87f90ed66ee410a7e6c392086e2c63d02 \
|
||||
--hash=sha256:14b242d53f6f35c2d07aa2c0e13ccb710392bcd203e1b82a1828d216f6f6b11f \
|
||||
--hash=sha256:1b3d0dcabc7c90b470e59e38a9acaa361be43b3a6ea644c0063951964717f0e5 \
|
||||
--hash=sha256:20a12ab46a7e72b89ce0671e7d7a6c3c1ca2c2766ac98112f78c5bddaa6e4375 \
|
||||
--hash=sha256:298f82c0ab1b182bd1f34f347ea97dde0fffb9ecf850ecf7f8904b8442a07487 \
|
||||
--hash=sha256:2f6175722da6f23dbfc76c26c241b67b020e1e83ec7fe93c9e5d3dd18667ada2 \
|
||||
--hash=sha256:3b877de633a0f6d81b600624ff9137312d8b1d0f517064dfc39999352ab659f0 \
|
||||
--hash=sha256:4265681e77f5ac5bac0905812b828c9fe1ce80c6f3e3f8574acfb5643aeabc5b \
|
||||
--hash=sha256:550695c4e7313555549aa1cdb978dc9413d61307531f123558e438871a883d63 \
|
||||
--hash=sha256:5f4d42baed3a14c290a078e2696c5f565501abde1b2f3f1a1c0a94fbf6fbcc39 \
|
||||
--hash=sha256:62dd71dbed8cc6a18379700701d959307823b3b2451bdc018594c48956ace745 \
|
||||
--hash=sha256:7040547e5b882349c0a2cc9b50674b1745db551f330746af434aad4f09fba2cc \
|
||||
--hash=sha256:7e099fde2cce8b29434684f82977db4e24f0efa8b0508179fce1602d103296a2 \
|
||||
--hash=sha256:7e5c9a5012b2b33e87980cee7d1c82412b2ebabcb5862d53413ba1a2cfde23aa \
|
||||
--hash=sha256:81295629128f929e73be4ccfdd943a0906e5fe3cdb0d43ff1e5144d16fbb52b1 \
|
||||
--hash=sha256:95cc574b0b83b85be9917d37cd2fad0ce5a0d21b024e1a5804d044aabea636fc \
|
||||
--hash=sha256:968d5c5702da15c5bf8e4a6e4b67a4d92164e334e9c0b6acf080106678230b98 \
|
||||
--hash=sha256:9e998ba87df77a85c7bed53240a7257afe51a07ee6bc3445a0bf841886da0b97 \
|
||||
--hash=sha256:a0c39e2535a7e9c195af956610dba5a1073071d2d85e9d2e5d789463f63e52ab \
|
||||
--hash=sha256:a15e75d284178afe529a536b0e8b28b7e107ef39626a7809b4ee64ff3abc9127 \
|
||||
--hash=sha256:a6a6ff82f5f9b9702478035d8f6fb6903885653bff7ec3a1e011edc9b1a7168d \
|
||||
--hash=sha256:b639f72b95389620c1f881d94739c614d385406ab1d6926a9ffe1c8abbea23fe \
|
||||
--hash=sha256:bad44274b151d46619a7567010f7cde23a908c6faa84b97598fd2f474a0c6891 \
|
||||
--hash=sha256:bbcef00d09a30948756c5968863316c949d9cedbc7aabac5e8f0ffbdb632e5f1 \
|
||||
--hash=sha256:d788a3999014ddf416f2dc454efa4a5dbeda657c6aba031cf363741273804c6b \
|
||||
--hash=sha256:eed88ae03e1ef3a75a0e96a55a99d7937ed03e53d0cffc2451c208db445a2966 \
|
||||
--hash=sha256:f99451f3a579e73b5dd58b1b08d1179791d49084371d9a47baad3b22417f0317
|
||||
zope.hookable==5.0.0 \
|
||||
--hash=sha256:0992a0dd692003c09fb958e1480cebd1a28f2ef32faa4857d864f3ca8e9d6952 \
|
||||
--hash=sha256:0f325838dbac827a1e2ed5d482c1f2656b6844dc96aa098f7727e76395fcd694 \
|
||||
--hash=sha256:22a317ba00f61bac99eac1a5e330be7cb8c316275a21269ec58aa396b602af0c \
|
||||
--hash=sha256:25531cb5e7b35e8a6d1d6eddef624b9a22ce5dcf8f4448ef0f165acfa8c3fc21 \
|
||||
--hash=sha256:30890892652766fc80d11f078aca9a5b8150bef6b88aba23799581a53515c404 \
|
||||
--hash=sha256:342d682d93937e5b8c232baffb32a87d5eee605d44f74566657c64a239b7f342 \
|
||||
--hash=sha256:46b2fddf1f5aeb526e02b91f7e62afbb9fff4ffd7aafc97cdb00a0d717641567 \
|
||||
--hash=sha256:523318ff96df9b8d378d997c00c5d4cbfbff68dc48ff5ee5addabdb697d27528 \
|
||||
--hash=sha256:53aa02eb8921d4e667c69d76adeed8fe426e43870c101cb08dcd2f3468aff742 \
|
||||
--hash=sha256:62e79e8fdde087cb20822d7874758f5acbedbffaf3c0fbe06309eb8a41ee4e06 \
|
||||
--hash=sha256:74bf2f757f7385b56dc3548adae508d8b3ef952d600b4b12b88f7d1706b05dcc \
|
||||
--hash=sha256:751ee9d89eb96e00c1d7048da9725ce392a708ed43406416dc5ed61e4d199764 \
|
||||
--hash=sha256:7b83bc341e682771fe810b360cd5d9c886a948976aea4b979ff214e10b8b523b \
|
||||
--hash=sha256:81eeeb27dbb0ddaed8070daee529f0d1bfe4f74c7351cce2aaca3ea287c4cc32 \
|
||||
--hash=sha256:856509191e16930335af4d773c0fc31a17bae8991eb6f167a09d5eddf25b56cc \
|
||||
--hash=sha256:8853e81fd07b18fa9193b19e070dc0557848d9945b1d2dac3b7782543458c87d \
|
||||
--hash=sha256:94506a732da2832029aecdfe6ea07eb1b70ee06d802fff34e1b3618fe7cdf026 \
|
||||
--hash=sha256:95ad874a8cc94e786969215d660143817f745225579bfe318c4676e218d3147c \
|
||||
--hash=sha256:9758ec9174966ffe5c499b6c3d149f80aa0a9238020006a2b87c6af5963fcf48 \
|
||||
--hash=sha256:a169823e331da939aa7178fc152e65699aeb78957e46c6f80ccb50ee4c3616c2 \
|
||||
--hash=sha256:a67878a798f6ca292729a28c2226592b3d000dc6ee7825d31887b553686c7ac7 \
|
||||
--hash=sha256:a9a6d9eb2319a09905670810e2de971d6c49013843700b4975e2fc0afe96c8db \
|
||||
--hash=sha256:b3e118b58a3d2301960e6f5f25736d92f6b9f861728d3b8c26d69f54d8a157d2 \
|
||||
--hash=sha256:ca6705c2a1fb5059a4efbe9f5426be4cdf71b3c9564816916fc7aa7902f19ede \
|
||||
--hash=sha256:cf711527c9d4ae72085f137caffb4be74fc007ffb17cd103628c7d5ba17e205f \
|
||||
--hash=sha256:d087602a6845ebe9d5a1c5a949fedde2c45f372d77fbce4f7fe44b68b28a1d03 \
|
||||
--hash=sha256:d1080e1074ddf75ad6662a9b34626650759c19a9093e1a32a503d37e48da135b \
|
||||
--hash=sha256:db9c60368aff2b7e6c47115f3ad9bd6e96aa298b12ed5f8cb13f5673b30be565 \
|
||||
--hash=sha256:dbeb127a04473f5a989169eb400b67beb921c749599b77650941c21fe39cb8d9 \
|
||||
--hash=sha256:dca336ca3682d869d291d7cd18284f6ff6876e4244eb1821430323056b000e2c \
|
||||
--hash=sha256:dd69a9be95346d10c853b6233fcafe3c0315b89424b378f2ad45170d8e161568 \
|
||||
--hash=sha256:dd79f8fae5894f1ee0a0042214685f2d039341250c994b825c10a4cd075d80f6 \
|
||||
--hash=sha256:e647d850aa1286d98910133cee12bd87c354f7b7bb3f3cd816a62ba7fa2f7007 \
|
||||
--hash=sha256:f37a210b5c04b2d4e4bac494ab15b70196f219a1e1649ddca78560757d4278fb \
|
||||
--hash=sha256:f67820b6d33a705dc3c1c457156e51686f7b350ff57f2112e1a9a4dad38ec268 \
|
||||
--hash=sha256:f68969978ccf0e6123902f7365aae5b7a9e99169d4b9105c47cf28e788116894 \
|
||||
--hash=sha256:f717a0b34460ae1ac0064e91b267c0588ac2c098ffd695992e72cd5462d97a67 \
|
||||
--hash=sha256:f9d58ccec8684ca276d5a4e7b0dfacca028336300a8f715d616d9f0ce9ae8096 \
|
||||
--hash=sha256:fcc3513a54e656067cbf7b98bab0d6b9534b9eabc666d1f78aad6acdf0962736
|
||||
zope.interface==4.7.1 \
|
||||
--hash=sha256:048b16ac882a05bc7ef534e8b9f15c9d7a6c190e24e8938a19b7617af4ed854a \
|
||||
--hash=sha256:05816cf8e7407cf62f2ec95c0a5d69ec4fa5741d9ccd10db9f21691916a9a098 \
|
||||
--hash=sha256:065d6a1ac89d35445168813bed45048ed4e67a4cdfc5a68fdb626a770378869f \
|
||||
--hash=sha256:14157421f4121a57625002cc4f48ac7521ea238d697c4a4459a884b62132b977 \
|
||||
--hash=sha256:18dc895945694f397a0be86be760ff664b790f95d8e7752d5bab80284ff9105d \
|
||||
--hash=sha256:1962c9f838bd6ae4075d0014f72697510daefc7e1c7e48b2607df0b6e157989c \
|
||||
--hash=sha256:1a67408cacd198c7e6274a19920bb4568d56459e659e23c4915528686ac1763a \
|
||||
--hash=sha256:21bf781076dd616bd07cf0223f79d61ab4f45176076f90bc2890e18c48195da4 \
|
||||
--hash=sha256:21c0a5d98650aebb84efa16ce2c8df1a46bdc4fe8a9e33237d0ca0b23f416ead \
|
||||
--hash=sha256:23cfeea25d1e42ff3bf4f9a0c31e9d5950aa9e7c4b12f0c4bd086f378f7b7a71 \
|
||||
--hash=sha256:24b6fce1fb71abf9f4093e3259084efcc0ef479f89356757780685bd2b06ef37 \
|
||||
--hash=sha256:24f84ce24eb6b5fcdcb38ad9761524f1ae96f7126abb5e597f8a3973d9921409 \
|
||||
--hash=sha256:25e0ef4a824017809d6d8b0ce4ab3288594ba283e4d4f94d8cfb81d73ed65114 \
|
||||
--hash=sha256:2e8fdd625e9aba31228e7ddbc36bad5c38dc3ee99a86aa420f89a290bd987ce9 \
|
||||
--hash=sha256:2f3bc2f49b67b1bea82b942d25bc958d4f4ea6709b411cb2b6b9718adf7914ce \
|
||||
--hash=sha256:35d24be9d04d50da3a6f4d61de028c1dd087045385a0ff374d93ef85af61b584 \
|
||||
--hash=sha256:35dbe4e8c73003dff40dfaeb15902910a4360699375e7b47d3c909a83ff27cd0 \
|
||||
--hash=sha256:3dfce831b824ab5cf446ed0c350b793ac6fa5fe33b984305cb4c966a86a8fb79 \
|
||||
--hash=sha256:3f7866365df5a36a7b8de8056cd1c605648f56f9a226d918ed84c85d25e8d55f \
|
||||
--hash=sha256:455cc8c01de3bac6f9c223967cea41f4449f58b4c2e724ec8177382ddd183ab4 \
|
||||
--hash=sha256:4bb937e998be9d5e345f486693e477ba79e4344674484001a0b646be1d530487 \
|
||||
--hash=sha256:52303a20902ca0888dfb83230ca3ee6fbe63c0ad1dd60aa0bba7958ccff454d8 \
|
||||
--hash=sha256:6e0a897d4e09859cc80c6a16a29697406ead752292ace17f1805126a4f63c838 \
|
||||
--hash=sha256:6e1816e7c10966330d77af45f77501f9a68818c065dec0ad11d22b50a0e212e7 \
|
||||
--hash=sha256:73b5921c5c6ce3358c836461b5470bf675601c96d5e5d8f2a446951470614f67 \
|
||||
--hash=sha256:8093cd45cdb5f6c8591cfd1af03d32b32965b0f79b94684cd0c9afdf841982bb \
|
||||
--hash=sha256:864b4a94b60db301899cf373579fd9ef92edddbf0fb2cd5ae99f53ef423ccc56 \
|
||||
--hash=sha256:8a27b4d3ea9c6d086ce8e7cdb3e8d319b6752e2a03238a388ccc83ccbe165f50 \
|
||||
--hash=sha256:91b847969d4784abd855165a2d163f72ac1e58e6dce09a5e46c20e58f19cc96d \
|
||||
--hash=sha256:b47b1028be4758c3167e474884ccc079b94835f058984b15c145966c4df64d27 \
|
||||
--hash=sha256:b68814a322835d8ad671b7acc23a3b2acecba527bb14f4b53fc925f8a27e44d8 \
|
||||
--hash=sha256:bcb50a032c3b6ec7fb281b3a83d2b31ab5246c5b119588725b1350d3a1d9f6a3 \
|
||||
--hash=sha256:c56db7d10b25ce8918b6aec6b08ac401842b47e6c136773bfb3b590753f7fb67 \
|
||||
--hash=sha256:c94b77a13d4f47883e4f97f9fa00f5feadd38af3e6b3c7be45cfdb0a14c7149b \
|
||||
--hash=sha256:db381f6fdaef483ad435f778086ccc4890120aff8df2ba5cfeeac24d280b3145 \
|
||||
--hash=sha256:e6487d01c8b7ed86af30ea141fcc4f93f8a7dde26f94177c1ad637c353bd5c07 \
|
||||
--hash=sha256:e86923fa728dfba39c5bb6046a450bd4eec8ad949ac404eca728cfce320d1732 \
|
||||
--hash=sha256:f6ca36dc1e9eeb46d779869c60001b3065fb670b5775c51421c099ea2a77c3c9 \
|
||||
--hash=sha256:fb62f2cbe790a50d95593fb40e8cca261c31a2f5637455ea39440d6457c2ba25
|
||||
zope.proxy==4.3.3 \
|
||||
--hash=sha256:04646ac04ffa9c8e32fb2b5c3cd42995b2548ea14251f3c21ca704afae88e42c \
|
||||
--hash=sha256:07b6bceea232559d24358832f1cd2ed344bbf05ca83855a5b9698b5f23c5ed60 \
|
||||
@@ -1372,18 +1540,18 @@ letsencrypt==0.7.0 \
|
||||
--hash=sha256:105a5fb107e45bcd0722eb89696986dcf5f08a86a321d6aef25a0c7c63375ade \
|
||||
--hash=sha256:c36e532c486a7e92155ee09da54b436a3c420813ec1c590b98f635d924720de9
|
||||
|
||||
certbot==1.0.0 \
|
||||
--hash=sha256:8d074cff89dee002dec1c47cb0da04ea8e0ede8d68838b6d54aa41580d9262df \
|
||||
--hash=sha256:86b82d31db19fffffb0d6b218951e2121ef514e3ff659aa042deaf92a33e302a
|
||||
acme==1.0.0 \
|
||||
--hash=sha256:f6972e436e76f7f1e395e81e149f8713ca8462d465b14993bddc53fb18a40644 \
|
||||
--hash=sha256:6a08f12f848ce563b50bca421ba9db653df9f82cfefeaf8aba517f046d1386c2
|
||||
certbot-apache==1.0.0 \
|
||||
--hash=sha256:e591d0cf773ad33ee978f7adb1b69288eac2c8847c643b06e70260e707626f8e \
|
||||
--hash=sha256:7335ab5687a0a47d9041d9e13f3a2d67d0e8372da97ab639edb31c14b787cd68
|
||||
certbot-nginx==1.0.0 \
|
||||
--hash=sha256:ce8a2e51165da7c15bfdc059cd6572d0f368c078f1e1a77633a2773310b2f231 \
|
||||
--hash=sha256:63b4ae09d4f1c9ef0a1a2a49c3f651d8a7cb30303ec6f954239e987c5da45dc4
|
||||
certbot==1.3.0 \
|
||||
--hash=sha256:979793b36151be26c159f1946d065a0cbbcaed3e9ac452c19a142b0d2d2b42e3 \
|
||||
--hash=sha256:bc2091cbbc2f432872ed69309046e79771d9c81cd441bde3e6a6553ecd04b1d8
|
||||
acme==1.3.0 \
|
||||
--hash=sha256:b888757c750e393407a3cdf0eb5c2d06036951e10c41db4c83537617568561b6 \
|
||||
--hash=sha256:c0de9e1fbcb4a28509825a4d19ab5455910862b23fa338acebc7bbe7c0abd20d
|
||||
certbot-apache==1.3.0 \
|
||||
--hash=sha256:1050cd262bcc598957c45a6fa1febdf5e41e87176c0aebad3a1ab7268b0d82d9 \
|
||||
--hash=sha256:4a6bb818a7a70803127590a54bb25c1e79810761c9d4c92cf9f16a56b518bd52
|
||||
certbot-nginx==1.3.0 \
|
||||
--hash=sha256:46106b96429d1aaf3765635056352d2372941027a3bc26bbf964e4329202adc7 \
|
||||
--hash=sha256:9aa0869c1250b7ea0a1eb1df6bdb5d0d6190d6ca0400da1033a8decc0df6f65b
|
||||
|
||||
UNLIKELY_EOF
|
||||
# -------------------------------------------------------------------------
|
||||
@@ -1617,6 +1785,9 @@ UNLIKELY_EOF
|
||||
say "Installation succeeded."
|
||||
fi
|
||||
|
||||
# If you're modifying any of the code after this point in this current `if` block, you
|
||||
# may need to update the "$DEPRECATED_OS" = 1 case at the beginning of phase 2 as well.
|
||||
|
||||
if [ "$INSTALL_ONLY" = 1 ]; then
|
||||
say "Certbot is installed."
|
||||
exit 0
|
||||
@@ -1828,30 +1999,35 @@ UNLIKELY_EOF
|
||||
error "WARNING: unable to check for updates."
|
||||
fi
|
||||
|
||||
LE_VERSION_STATE=`CompareVersions "$LE_PYTHON" "$LE_AUTO_VERSION" "$REMOTE_VERSION"`
|
||||
if [ "$LE_VERSION_STATE" = "UNOFFICIAL" ]; then
|
||||
say "Unofficial certbot-auto version detected, self-upgrade is disabled: $LE_AUTO_VERSION"
|
||||
elif [ "$LE_VERSION_STATE" = "OUTDATED" ]; then
|
||||
say "Upgrading certbot-auto $LE_AUTO_VERSION to $REMOTE_VERSION..."
|
||||
# If for any reason REMOTE_VERSION is not set, let's assume certbot-auto is up-to-date,
|
||||
# and do not go into the self-upgrading process.
|
||||
if [ -n "$REMOTE_VERSION" ]; then
|
||||
LE_VERSION_STATE=`CompareVersions "$LE_PYTHON" "$LE_AUTO_VERSION" "$REMOTE_VERSION"`
|
||||
|
||||
# Now we drop into Python so we don't have to install even more
|
||||
# dependencies (curl, etc.), for better flow control, and for the option of
|
||||
# future Windows compatibility.
|
||||
"$LE_PYTHON" "$TEMP_DIR/fetch.py" --le-auto-script "v$REMOTE_VERSION"
|
||||
if [ "$LE_VERSION_STATE" = "UNOFFICIAL" ]; then
|
||||
say "Unofficial certbot-auto version detected, self-upgrade is disabled: $LE_AUTO_VERSION"
|
||||
elif [ "$LE_VERSION_STATE" = "OUTDATED" ]; then
|
||||
say "Upgrading certbot-auto $LE_AUTO_VERSION to $REMOTE_VERSION..."
|
||||
|
||||
# Install new copy of certbot-auto.
|
||||
# TODO: Deal with quotes in pathnames.
|
||||
say "Replacing certbot-auto..."
|
||||
# Clone permissions with cp. chmod and chown don't have a --reference
|
||||
# option on macOS or BSD, and stat -c on Linux is stat -f on macOS and BSD:
|
||||
cp -p "$0" "$TEMP_DIR/letsencrypt-auto.permission-clone"
|
||||
cp "$TEMP_DIR/letsencrypt-auto" "$TEMP_DIR/letsencrypt-auto.permission-clone"
|
||||
# Using mv rather than cp leaves the old file descriptor pointing to the
|
||||
# original copy so the shell can continue to read it unmolested. mv across
|
||||
# filesystems is non-atomic, doing `rm dest, cp src dest, rm src`, but the
|
||||
# cp is unlikely to fail if the rm doesn't.
|
||||
mv -f "$TEMP_DIR/letsencrypt-auto.permission-clone" "$0"
|
||||
fi # A newer version is available.
|
||||
# Now we drop into Python so we don't have to install even more
|
||||
# dependencies (curl, etc.), for better flow control, and for the option of
|
||||
# future Windows compatibility.
|
||||
"$LE_PYTHON" "$TEMP_DIR/fetch.py" --le-auto-script "v$REMOTE_VERSION"
|
||||
|
||||
# Install new copy of certbot-auto.
|
||||
# TODO: Deal with quotes in pathnames.
|
||||
say "Replacing certbot-auto..."
|
||||
# Clone permissions with cp. chmod and chown don't have a --reference
|
||||
# option on macOS or BSD, and stat -c on Linux is stat -f on macOS and BSD:
|
||||
cp -p "$0" "$TEMP_DIR/letsencrypt-auto.permission-clone"
|
||||
cp "$TEMP_DIR/letsencrypt-auto" "$TEMP_DIR/letsencrypt-auto.permission-clone"
|
||||
# Using mv rather than cp leaves the old file descriptor pointing to the
|
||||
# original copy so the shell can continue to read it unmolested. mv across
|
||||
# filesystems is non-atomic, doing `rm dest, cp src dest, rm src`, but the
|
||||
# cp is unlikely to fail if the rm doesn't.
|
||||
mv -f "$TEMP_DIR/letsencrypt-auto.permission-clone" "$0"
|
||||
fi # A newer version is available.
|
||||
fi
|
||||
fi # Self-upgrading is allowed.
|
||||
|
||||
RerunWithArgs --le-auto-phase2 "$@"
|
||||
|
||||
@@ -595,6 +595,23 @@ def test_ocsp_status_live(context):
|
||||
assert output.count('REVOKED') == 1, 'Expected {0} to be REVOKED'.format(cert)
|
||||
|
||||
|
||||
def test_ocsp_renew(context):
|
||||
"""Test that revoked certificates are renewed."""
|
||||
# Obtain a certificate
|
||||
certname = context.get_domain('ocsp-renew')
|
||||
context.certbot(['--domains', certname])
|
||||
|
||||
# Test that "certbot renew" does not renew the certificate
|
||||
assert_cert_count_for_lineage(context.config_dir, certname, 1)
|
||||
context.certbot(['renew'], force_renew=False)
|
||||
assert_cert_count_for_lineage(context.config_dir, certname, 1)
|
||||
|
||||
# Revoke the certificate and test that it does renew the certificate
|
||||
context.certbot(['revoke', '--cert-name', certname, '--no-delete-after-revoke'])
|
||||
context.certbot(['renew'], force_renew=False)
|
||||
assert_cert_count_for_lineage(context.config_dir, certname, 2)
|
||||
|
||||
|
||||
def test_dry_run_deactivate_authzs(context):
|
||||
"""Test that Certbot deactivates authorizations when performing a dry run"""
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ def _setup_primary_node(config):
|
||||
"""
|
||||
Setup the environment for integration tests.
|
||||
Will:
|
||||
- check runtime compatiblity (Docker, docker-compose, Nginx)
|
||||
- check runtime compatibility (Docker, docker-compose, Nginx)
|
||||
- create a temporary workspace and the persistent GIT repositories space
|
||||
- configure and start paralleled ACME CA servers using Docker
|
||||
- transfer ACME CA servers configurations to pytest nodes using env variables
|
||||
|
||||
@@ -189,7 +189,7 @@ class ACMEServer(object):
|
||||
print('=> Finished configuring the HTTP proxy.')
|
||||
|
||||
def _launch_process(self, command, cwd=os.getcwd(), env=None):
|
||||
"""Launch silently an subprocess OS command"""
|
||||
"""Launch silently a subprocess OS command"""
|
||||
if not env:
|
||||
env = os.environ
|
||||
process = subprocess.Popen(command, stdout=self._stdout, stderr=subprocess.STDOUT, cwd=cwd, env=env)
|
||||
|
||||
@@ -40,7 +40,7 @@ setup(
|
||||
author="Certbot Project",
|
||||
author_email='client-dev@letsencrypt.org',
|
||||
license='Apache License 2.0',
|
||||
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*',
|
||||
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
|
||||
classifiers=[
|
||||
'Development Status :: 3 - Alpha',
|
||||
'Intended Audience :: Developers',
|
||||
@@ -49,7 +49,6 @@ setup(
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
|
||||
38
certbot-ci/windows_installer_integration_tests/conftest.py
Normal file
38
certbot-ci/windows_installer_integration_tests/conftest.py
Normal file
@@ -0,0 +1,38 @@
|
||||
"""
|
||||
General conftest for pytest execution of all integration tests lying
|
||||
in the window_installer_integration tests package.
|
||||
As stated by pytest documentation, conftest module is used to set on
|
||||
for a directory a specific configuration using built-in pytest hooks.
|
||||
|
||||
See https://docs.pytest.org/en/latest/reference.html#hook-reference
|
||||
"""
|
||||
from __future__ import print_function
|
||||
import os
|
||||
|
||||
import pytest
|
||||
|
||||
ROOT_PATH = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
|
||||
|
||||
|
||||
def pytest_addoption(parser):
|
||||
"""
|
||||
Standard pytest hook to add options to the pytest parser.
|
||||
:param parser: current pytest parser that will be used on the CLI
|
||||
"""
|
||||
parser.addoption('--installer-path',
|
||||
default=os.path.join(ROOT_PATH, 'windows-installer', 'build',
|
||||
'nsis', 'certbot-beta-installer-win32.exe'),
|
||||
help='set the path of the windows installer to use, default to '
|
||||
'CERTBOT_ROOT_PATH\\windows-installer\\build\\nsis\\certbot-beta-installer-win32.exe')
|
||||
parser.addoption('--allow-persistent-changes', action='store_true',
|
||||
help='needs to be set, and confirm that the test will make persistent changes on this machine')
|
||||
|
||||
|
||||
def pytest_configure(config):
|
||||
"""
|
||||
Standard pytest hook used to add a configuration logic for each node of a pytest run.
|
||||
:param config: the current pytest configuration
|
||||
"""
|
||||
if not config.option.allow_persistent_changes:
|
||||
raise RuntimeError('This integration test would install Certbot on your machine. '
|
||||
'Please run it again with the `--allow-persistent-changes` flag set to acknowledge.')
|
||||
61
certbot-ci/windows_installer_integration_tests/test_main.py
Normal file
61
certbot-ci/windows_installer_integration_tests/test_main.py
Normal file
@@ -0,0 +1,61 @@
|
||||
import os
|
||||
import time
|
||||
import unittest
|
||||
import subprocess
|
||||
import re
|
||||
|
||||
|
||||
@unittest.skipIf(os.name != 'nt', reason='Windows installer tests must be run on Windows.')
|
||||
def test_it(request):
|
||||
try:
|
||||
subprocess.check_call(['certbot', '--version'])
|
||||
except (subprocess.CalledProcessError, OSError):
|
||||
pass
|
||||
else:
|
||||
raise AssertionError('Expect certbot to not be available in the PATH.')
|
||||
|
||||
try:
|
||||
# Install certbot
|
||||
subprocess.check_call([request.config.option.installer_path, '/S'])
|
||||
|
||||
# Assert certbot is installed and runnable
|
||||
output = subprocess.check_output(['certbot', '--version'], universal_newlines=True)
|
||||
assert re.match(r'^certbot \d+\.\d+\.\d+.*$', output), 'Flag --version does not output a version.'
|
||||
|
||||
# Assert renew task is installed and ready
|
||||
output = _ps('(Get-ScheduledTask -TaskName "Certbot Renew Task").State', capture_stdout=True)
|
||||
assert output.strip() == 'Ready'
|
||||
|
||||
# Assert renew task is working
|
||||
now = time.time()
|
||||
_ps('Start-ScheduledTask -TaskName "Certbot Renew Task"')
|
||||
|
||||
status = 'Running'
|
||||
while status != 'Ready':
|
||||
status = _ps('(Get-ScheduledTask -TaskName "Certbot Renew Task").State', capture_stdout=True).strip()
|
||||
time.sleep(1)
|
||||
|
||||
log_path = os.path.join('C:\\', 'Certbot', 'log', 'letsencrypt.log')
|
||||
|
||||
modification_time = os.path.getmtime(log_path)
|
||||
assert now < modification_time, 'Certbot log file has not been modified by the renew task.'
|
||||
|
||||
with open(log_path) as file_h:
|
||||
data = file_h.read()
|
||||
assert 'no renewal failures' in data, 'Renew task did not execute properly.'
|
||||
|
||||
finally:
|
||||
# Sadly this command cannot work in non interactive mode: uninstaller will ask explicitly permission in an UAC prompt
|
||||
# print('Uninstalling Certbot ...')
|
||||
# uninstall_path = _ps('(gci "HKLM:\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall"'
|
||||
# ' | foreach { gp $_.PSPath }'
|
||||
# ' | ? { $_ -match "Certbot" }'
|
||||
# ' | select UninstallString)'
|
||||
# '.UninstallString', capture_stdout=True)
|
||||
# subprocess.check_call([uninstall_path, '/S'])
|
||||
pass
|
||||
|
||||
|
||||
def _ps(powershell_str, capture_stdout=False):
|
||||
fn = subprocess.check_output if capture_stdout else subprocess.check_call
|
||||
return fn(['powershell.exe', '-c', powershell_str], universal_newlines=True)
|
||||
@@ -31,7 +31,7 @@ COPY certbot-nginx /opt/certbot/src/certbot-nginx/
|
||||
COPY certbot-compatibility-test /opt/certbot/src/certbot-compatibility-test/
|
||||
COPY tools /opt/certbot/src/tools
|
||||
|
||||
RUN VIRTUALENV_NO_DOWNLOAD=1 virtualenv --no-site-packages -p python2 /opt/certbot/venv && \
|
||||
RUN VIRTUALENV_NO_DOWNLOAD=1 virtualenv -p python2 /opt/certbot/venv && \
|
||||
/opt/certbot/venv/bin/pip install -U setuptools && \
|
||||
/opt/certbot/venv/bin/pip install -U pip
|
||||
ENV PATH /opt/certbot/venv/bin:$PATH
|
||||
|
||||
@@ -5,7 +5,7 @@ import subprocess
|
||||
|
||||
import zope.interface
|
||||
|
||||
from acme.magic_typing import Set # pylint: disable=unused-import, no-name-in-module
|
||||
from acme.magic_typing import Set
|
||||
from certbot._internal import configuration
|
||||
from certbot_compatibility_test import errors
|
||||
from certbot_compatibility_test import interfaces
|
||||
|
||||
@@ -15,8 +15,8 @@ from urllib3.util import connection
|
||||
from acme import challenges
|
||||
from acme import crypto_util
|
||||
from acme import messages
|
||||
from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module
|
||||
from acme.magic_typing import Tuple # pylint: disable=unused-import, no-name-in-module
|
||||
from acme.magic_typing import List
|
||||
from acme.magic_typing import Tuple
|
||||
from certbot import achallenges
|
||||
from certbot import errors as le_errors
|
||||
from certbot.tests import acme_util
|
||||
|
||||
@@ -4,7 +4,7 @@ import socket
|
||||
|
||||
import requests
|
||||
import six
|
||||
from six.moves import xrange # pylint: disable=import-error, redefined-builtin
|
||||
from six.moves import xrange
|
||||
|
||||
from acme import crypto_util
|
||||
from acme import errors as acme_errors
|
||||
@@ -13,7 +13,6 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Validator(object):
|
||||
# pylint: disable=no-self-use
|
||||
"""Collection of functions to test a live webserver's configuration"""
|
||||
|
||||
def certificate(self, cert, name, alt_host=None, port=443):
|
||||
|
||||
@@ -39,7 +39,7 @@ class ValidatorTest(unittest.TestCase):
|
||||
cert, "test.com", "127.0.0.1"))
|
||||
|
||||
@mock.patch("certbot_compatibility_test.validator.requests.get")
|
||||
def test_succesful_redirect(self, mock_get_request):
|
||||
def test_successful_redirect(self, mock_get_request):
|
||||
mock_get_request.return_value = create_response(
|
||||
301, {"location": "https://test.com"})
|
||||
self.assertTrue(self.validator.redirect("test.com"))
|
||||
|
||||
@@ -3,7 +3,7 @@ import sys
|
||||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
version = '1.1.0.dev0'
|
||||
version = '1.3.0'
|
||||
|
||||
install_requires = [
|
||||
'certbot',
|
||||
@@ -28,7 +28,7 @@ setup(
|
||||
author="Certbot Project",
|
||||
author_email='client-dev@letsencrypt.org',
|
||||
license='Apache License 2.0',
|
||||
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*',
|
||||
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
|
||||
classifiers=[
|
||||
'Development Status :: 3 - Alpha',
|
||||
'Intended Audience :: Developers',
|
||||
@@ -37,7 +37,6 @@ setup(
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
|
||||
@@ -22,17 +22,40 @@ Credentials
|
||||
|
||||
Use of this plugin requires a configuration file containing Cloudflare API
|
||||
credentials, obtained from your Cloudflare
|
||||
`account page <https://www.cloudflare.com/a/account/my-account>`_. This plugin
|
||||
does not currently support Cloudflare's "API Tokens", so please ensure you use
|
||||
the "Global API Key" for authentication.
|
||||
`account page <https://dash.cloudflare.com/profile/api-tokens>`_.
|
||||
|
||||
Previously, Cloudflare's "Global API Key" was used for authentication, however
|
||||
this key can access the entire Cloudflare API for all domains in your account,
|
||||
meaning it could cause a lot of damage if leaked.
|
||||
|
||||
Cloudflare's newer API Tokens can be restricted to specific domains and
|
||||
operations, and are therefore now the recommended authentication option.
|
||||
|
||||
However, due to some shortcomings in Cloudflare's implementation of Tokens,
|
||||
Tokens created for Certbot currently require ``Zone:Zone:Read`` and ``Zone:DNS:Edit``
|
||||
permissions for **all** zones in your account. While this is not ideal, your Token
|
||||
will still have fewer permission than the Global key, so it's still worth doing.
|
||||
Hopefully Cloudflare will improve this in the future.
|
||||
|
||||
Using Cloudflare Tokens also requires at least version 2.3.1 of the ``cloudflare``
|
||||
python module. If the version that automatically installed with this plugin is
|
||||
older than that, and you can't upgrade it on your system, you'll have to stick to
|
||||
the Global key.
|
||||
|
||||
.. code-block:: ini
|
||||
:name: credentials.ini
|
||||
:caption: Example credentials file:
|
||||
:name: certbot_cloudflare_token.ini
|
||||
:caption: Example credentials file using restricted API Token (recommended):
|
||||
|
||||
# Cloudflare API token used by Certbot
|
||||
dns_cloudflare_api_token = 0123456789abcdef0123456789abcdef01234567
|
||||
|
||||
.. code-block:: ini
|
||||
:name: certbot_cloudflare_key.ini
|
||||
:caption: Example credentials file using Global API Key (not recommended):
|
||||
|
||||
# Cloudflare API credentials used by Certbot
|
||||
dns_cloudflare_email = cloudflare@example.com
|
||||
dns_cloudflare_api_key = 0123456789abcdef0123456789abcdef01234567
|
||||
dns_cloudflare_api_key = 0123456789abcdef0123456789abcdef01234
|
||||
|
||||
The path to this file can be provided interactively or using the
|
||||
``--dns-cloudflare-credentials`` command-line argument. Certbot records the path
|
||||
|
||||
@@ -4,6 +4,10 @@ import logging
|
||||
import CloudFlare
|
||||
import zope.interface
|
||||
|
||||
from acme.magic_typing import Any
|
||||
from acme.magic_typing import Dict
|
||||
from acme.magic_typing import List
|
||||
|
||||
from certbot import errors
|
||||
from certbot import interfaces
|
||||
from certbot.plugins import dns_common
|
||||
@@ -34,18 +38,39 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
super(Authenticator, cls).add_parser_arguments(add)
|
||||
add('credentials', help='Cloudflare credentials INI file.')
|
||||
|
||||
def more_info(self): # pylint: disable=missing-docstring,no-self-use
|
||||
def more_info(self): # pylint: disable=missing-function-docstring
|
||||
return 'This plugin configures a DNS TXT record to respond to a dns-01 challenge using ' + \
|
||||
'the Cloudflare API.'
|
||||
|
||||
def _validate_credentials(self, credentials):
|
||||
token = credentials.conf('api-token')
|
||||
email = credentials.conf('email')
|
||||
key = credentials.conf('api-key')
|
||||
if token:
|
||||
if email or key:
|
||||
raise errors.PluginError('{}: dns_cloudflare_email and dns_cloudflare_api_key are '
|
||||
'not needed when using an API Token'
|
||||
.format(credentials.confobj.filename))
|
||||
elif email or key:
|
||||
if not email:
|
||||
raise errors.PluginError('{}: dns_cloudflare_email is required when using a Global '
|
||||
'API Key. (should be email address associated with '
|
||||
'Cloudflare account)'.format(credentials.confobj.filename))
|
||||
if not key:
|
||||
raise errors.PluginError('{}: dns_cloudflare_api_key is required when using a '
|
||||
'Global API Key. (see {})'
|
||||
.format(credentials.confobj.filename, ACCOUNT_URL))
|
||||
else:
|
||||
raise errors.PluginError('{}: Either dns_cloudflare_api_token (recommended), or '
|
||||
'dns_cloudflare_email and dns_cloudflare_api_key are required.'
|
||||
' (see {})'.format(credentials.confobj.filename, ACCOUNT_URL))
|
||||
|
||||
def _setup_credentials(self):
|
||||
self.credentials = self._configure_credentials(
|
||||
'credentials',
|
||||
'Cloudflare credentials INI file',
|
||||
{
|
||||
'email': 'email address associated with Cloudflare account',
|
||||
'api-key': 'API key for Cloudflare account, obtained from {0}'.format(ACCOUNT_URL)
|
||||
}
|
||||
None,
|
||||
self._validate_credentials
|
||||
)
|
||||
|
||||
def _perform(self, domain, validation_name, validation):
|
||||
@@ -55,6 +80,8 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
self._get_cloudflare_client().del_txt_record(domain, validation_name, validation)
|
||||
|
||||
def _get_cloudflare_client(self):
|
||||
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'))
|
||||
|
||||
|
||||
@@ -88,8 +115,15 @@ class _CloudflareClient(object):
|
||||
logger.debug('Attempting to add record to zone %s: %s', zone_id, data)
|
||||
self.cf.zones.dns_records.post(zone_id, data=data) # zones | pylint: disable=no-member
|
||||
except CloudFlare.exceptions.CloudFlareAPIError as e:
|
||||
code = int(e)
|
||||
hint = None
|
||||
|
||||
if code == 9109:
|
||||
hint = 'Does your API token have "Zone:DNS:Edit" permissions?'
|
||||
|
||||
logger.error('Encountered CloudFlareAPIError adding TXT record: %d %s', e, e)
|
||||
raise errors.PluginError('Error communicating with the Cloudflare API: {0}'.format(e))
|
||||
raise errors.PluginError('Error communicating with the Cloudflare API: {0}{1}'
|
||||
.format(e, ' ({0})'.format(hint) if hint else ''))
|
||||
|
||||
record_id = self._find_txt_record_id(zone_id, record_name, record_content)
|
||||
logger.debug('Successfully added TXT record with record_id: %s', record_id)
|
||||
@@ -139,6 +173,8 @@ class _CloudflareClient(object):
|
||||
"""
|
||||
|
||||
zone_name_guesses = dns_common.base_domain_name_guesses(domain)
|
||||
zones = [] # type: List[Dict[str, Any]]
|
||||
code = msg = None
|
||||
|
||||
for zone_name in zone_name_guesses:
|
||||
params = {'name': zone_name,
|
||||
@@ -148,16 +184,26 @@ class _CloudflareClient(object):
|
||||
zones = self.cf.zones.get(params=params) # zones | pylint: disable=no-member
|
||||
except CloudFlare.exceptions.CloudFlareAPIError as e:
|
||||
code = int(e)
|
||||
msg = str(e)
|
||||
hint = None
|
||||
|
||||
if code == 6003:
|
||||
hint = 'Did you copy your entire API key?'
|
||||
hint = ('Did you copy your entire API token/key? To use Cloudflare tokens, '
|
||||
'you\'ll need the python package cloudflare>=2.3.1.{}'
|
||||
.format(' This certbot is running cloudflare ' + str(CloudFlare.__version__)
|
||||
if hasattr(CloudFlare, '__version__') else ''))
|
||||
elif code == 9103:
|
||||
hint = 'Did you enter the correct email address?'
|
||||
hint = 'Did you enter the correct email address and Global key?'
|
||||
elif code == 9109:
|
||||
hint = 'Did you enter a valid Cloudflare Token?'
|
||||
|
||||
raise errors.PluginError('Error determining zone_id: {0} {1}. Please confirm that '
|
||||
'you have supplied valid Cloudflare API credentials.{2}'
|
||||
.format(code, e, ' ({0})'.format(hint) if hint else ''))
|
||||
if hint:
|
||||
raise errors.PluginError('Error determining zone_id: {0} {1}. Please confirm '
|
||||
'that you have supplied valid Cloudflare API credentials. ({2})'
|
||||
.format(code, msg, hint))
|
||||
else:
|
||||
logger.debug('Unrecognised CloudFlareAPIError while finding zone_id: %d %s. '
|
||||
'Continuing with next zone guess...', e, e)
|
||||
|
||||
if zones:
|
||||
zone_id = zones[0]['id']
|
||||
@@ -165,9 +211,10 @@ class _CloudflareClient(object):
|
||||
return zone_id
|
||||
|
||||
raise errors.PluginError('Unable to determine zone_id for {0} using zone names: {1}. '
|
||||
'Please confirm that the domain name has been entered correctly '
|
||||
'and is already associated with the supplied Cloudflare account.'
|
||||
.format(domain, zone_name_guesses))
|
||||
'Please confirm that the domain name has been entered correctly '
|
||||
'and is already associated with the supplied Cloudflare account.{2}'
|
||||
.format(domain, zone_name_guesses, ' The error from Cloudflare was:'
|
||||
' {0} {1}'.format(code, msg) if code is not None else ''))
|
||||
|
||||
def _find_txt_record_id(self, zone_id, record_name, record_content):
|
||||
"""
|
||||
|
||||
@@ -38,7 +38,7 @@ extensions = ['sphinx.ext.autodoc',
|
||||
'sphinx.ext.viewcode']
|
||||
|
||||
autodoc_member_order = 'bysource'
|
||||
autodoc_default_flags = ['show-inheritance', 'private-members']
|
||||
autodoc_default_flags = ['show-inheritance']
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
@@ -84,7 +84,7 @@ default_role = 'py:obj'
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||
todo_include_todos = True
|
||||
todo_include_todos = False
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Remember to update setup.py to match the package versions below.
|
||||
acme[dev]==0.29.0
|
||||
-e certbot[dev]
|
||||
certbot[dev]==1.1.0
|
||||
|
||||
@@ -4,13 +4,13 @@ from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
from setuptools.command.test import test as TestCommand
|
||||
|
||||
version = '1.1.0.dev0'
|
||||
version = '1.3.0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
install_requires = [
|
||||
'acme>=0.29.0',
|
||||
'certbot>=1.0.0.dev0',
|
||||
'certbot>=1.1.0',
|
||||
'cloudflare>=1.5.1',
|
||||
'mock',
|
||||
'setuptools',
|
||||
@@ -44,7 +44,7 @@ setup(
|
||||
author="Certbot Project",
|
||||
author_email='client-dev@letsencrypt.org',
|
||||
license='Apache License 2.0',
|
||||
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*',
|
||||
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
|
||||
classifiers=[
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Environment :: Plugins',
|
||||
@@ -55,7 +55,6 @@ setup(
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
|
||||
@@ -12,6 +12,9 @@ from certbot.plugins.dns_test_common import DOMAIN
|
||||
from certbot.tests import util as test_util
|
||||
|
||||
API_ERROR = CloudFlare.exceptions.CloudFlareAPIError(1000, '', '')
|
||||
|
||||
API_TOKEN = 'an-api-token'
|
||||
|
||||
API_KEY = 'an-api-key'
|
||||
EMAIL = 'example@example.com'
|
||||
|
||||
@@ -49,6 +52,50 @@ class AuthenticatorTest(test_util.TempDirTestCase, dns_test_common.BaseAuthentic
|
||||
expected = [mock.call.del_txt_record(DOMAIN, '_acme-challenge.'+DOMAIN, mock.ANY)]
|
||||
self.assertEqual(expected, self.mock_client.mock_calls)
|
||||
|
||||
def test_api_token(self):
|
||||
dns_test_common.write({"cloudflare_api_token": API_TOKEN},
|
||||
self.config.cloudflare_credentials)
|
||||
self.auth.perform([self.achall])
|
||||
|
||||
expected = [mock.call.add_txt_record(DOMAIN, '_acme-challenge.'+DOMAIN, mock.ANY, mock.ANY)]
|
||||
self.assertEqual(expected, self.mock_client.mock_calls)
|
||||
|
||||
def test_no_creds(self):
|
||||
dns_test_common.write({}, self.config.cloudflare_credentials)
|
||||
self.assertRaises(errors.PluginError,
|
||||
self.auth.perform,
|
||||
[self.achall])
|
||||
|
||||
def test_missing_email_or_key(self):
|
||||
dns_test_common.write({"cloudflare_api_key": API_KEY}, self.config.cloudflare_credentials)
|
||||
self.assertRaises(errors.PluginError,
|
||||
self.auth.perform,
|
||||
[self.achall])
|
||||
|
||||
dns_test_common.write({"cloudflare_email": EMAIL}, self.config.cloudflare_credentials)
|
||||
self.assertRaises(errors.PluginError,
|
||||
self.auth.perform,
|
||||
[self.achall])
|
||||
|
||||
def test_email_or_key_with_token(self):
|
||||
dns_test_common.write({"cloudflare_api_token": API_TOKEN, "cloudflare_email": EMAIL},
|
||||
self.config.cloudflare_credentials)
|
||||
self.assertRaises(errors.PluginError,
|
||||
self.auth.perform,
|
||||
[self.achall])
|
||||
|
||||
dns_test_common.write({"cloudflare_api_token": API_TOKEN, "cloudflare_api_key": API_KEY},
|
||||
self.config.cloudflare_credentials)
|
||||
self.assertRaises(errors.PluginError,
|
||||
self.auth.perform,
|
||||
[self.achall])
|
||||
|
||||
dns_test_common.write({"cloudflare_api_token": API_TOKEN, "cloudflare_email": EMAIL,
|
||||
"cloudflare_api_key": API_KEY}, self.config.cloudflare_credentials)
|
||||
self.assertRaises(errors.PluginError,
|
||||
self.auth.perform,
|
||||
[self.achall])
|
||||
|
||||
|
||||
class CloudflareClientTest(unittest.TestCase):
|
||||
record_name = "foo"
|
||||
@@ -83,7 +130,7 @@ class CloudflareClientTest(unittest.TestCase):
|
||||
def test_add_txt_record_error(self):
|
||||
self.cf.zones.get.return_value = [{'id': self.zone_id}]
|
||||
|
||||
self.cf.zones.dns_records.post.side_effect = API_ERROR
|
||||
self.cf.zones.dns_records.post.side_effect = CloudFlare.exceptions.CloudFlareAPIError(9109, '', '')
|
||||
|
||||
self.assertRaises(
|
||||
errors.PluginError,
|
||||
@@ -106,6 +153,25 @@ class CloudflareClientTest(unittest.TestCase):
|
||||
self.cloudflare_client.add_txt_record,
|
||||
DOMAIN, self.record_name, self.record_content, self.record_ttl)
|
||||
|
||||
def test_add_txt_record_bad_creds(self):
|
||||
self.cf.zones.get.side_effect = CloudFlare.exceptions.CloudFlareAPIError(6003, '', '')
|
||||
self.assertRaises(
|
||||
errors.PluginError,
|
||||
self.cloudflare_client.add_txt_record,
|
||||
DOMAIN, self.record_name, self.record_content, self.record_ttl)
|
||||
|
||||
self.cf.zones.get.side_effect = CloudFlare.exceptions.CloudFlareAPIError(9103, '', '')
|
||||
self.assertRaises(
|
||||
errors.PluginError,
|
||||
self.cloudflare_client.add_txt_record,
|
||||
DOMAIN, self.record_name, self.record_content, self.record_ttl)
|
||||
|
||||
self.cf.zones.get.side_effect = CloudFlare.exceptions.CloudFlareAPIError(9109, '', '')
|
||||
self.assertRaises(
|
||||
errors.PluginError,
|
||||
self.cloudflare_client.add_txt_record,
|
||||
DOMAIN, self.record_name, self.record_content, self.record_ttl)
|
||||
|
||||
def test_del_txt_record(self):
|
||||
self.cf.zones.get.return_value = [{'id': self.zone_id}]
|
||||
self.cf.zones.dns_records.get.return_value = [{'id': self.record_id}]
|
||||
|
||||
@@ -34,7 +34,7 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
super(Authenticator, cls).add_parser_arguments(add, default_propagation_seconds=30)
|
||||
add('credentials', help='CloudXNS credentials INI file.')
|
||||
|
||||
def more_info(self): # pylint: disable=missing-docstring,no-self-use
|
||||
def more_info(self): # pylint: disable=missing-function-docstring
|
||||
return 'This plugin configures a DNS TXT record to respond to a dns-01 challenge using ' + \
|
||||
'the CloudXNS API.'
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ extensions = ['sphinx.ext.autodoc',
|
||||
'sphinx.ext.viewcode']
|
||||
|
||||
autodoc_member_order = 'bysource'
|
||||
autodoc_default_flags = ['show-inheritance', 'private-members']
|
||||
autodoc_default_flags = ['show-inheritance']
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
@@ -84,7 +84,7 @@ default_role = 'py:obj'
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||
todo_include_todos = True
|
||||
todo_include_todos = False
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Remember to update setup.py to match the package versions below.
|
||||
acme[dev]==0.31.0
|
||||
-e certbot[dev]
|
||||
certbot[dev]==1.1.0
|
||||
|
||||
@@ -4,13 +4,13 @@ from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
from setuptools.command.test import test as TestCommand
|
||||
|
||||
version = '1.1.0.dev0'
|
||||
version = '1.3.0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
install_requires = [
|
||||
'acme>=0.31.0',
|
||||
'certbot>=1.0.0.dev0',
|
||||
'certbot>=1.1.0',
|
||||
'dns-lexicon>=2.2.1', # Support for >1 TXT record per name
|
||||
'mock',
|
||||
'setuptools',
|
||||
@@ -44,7 +44,7 @@ setup(
|
||||
author="Certbot Project",
|
||||
author_email='client-dev@letsencrypt.org',
|
||||
license='Apache License 2.0',
|
||||
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*',
|
||||
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
|
||||
classifiers=[
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Environment :: Plugins',
|
||||
@@ -55,7 +55,6 @@ setup(
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
|
||||
@@ -30,7 +30,7 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
super(Authenticator, cls).add_parser_arguments(add)
|
||||
add('credentials', help='DigitalOcean credentials INI file.')
|
||||
|
||||
def more_info(self): # pylint: disable=missing-docstring,no-self-use
|
||||
def more_info(self): # pylint: disable=missing-function-docstring
|
||||
return 'This plugin configures a DNS TXT record to respond to a dns-01 challenge using ' + \
|
||||
'the DigitalOcean API.'
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ extensions = ['sphinx.ext.autodoc',
|
||||
'sphinx.ext.viewcode']
|
||||
|
||||
autodoc_member_order = 'bysource'
|
||||
autodoc_default_flags = ['show-inheritance', 'private-members']
|
||||
autodoc_default_flags = ['show-inheritance']
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
@@ -84,7 +84,7 @@ default_role = 'py:obj'
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||
todo_include_todos = True
|
||||
todo_include_todos = False
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Remember to update setup.py to match the package versions below.
|
||||
acme[dev]==0.29.0
|
||||
-e certbot[dev]
|
||||
certbot[dev]==1.1.0
|
||||
|
||||
@@ -4,13 +4,13 @@ from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
from setuptools.command.test import test as TestCommand
|
||||
|
||||
version = '1.1.0.dev0'
|
||||
version = '1.3.0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
install_requires = [
|
||||
'acme>=0.29.0',
|
||||
'certbot>=1.0.0.dev0',
|
||||
'certbot>=1.1.0',
|
||||
'mock',
|
||||
'python-digitalocean>=1.11',
|
||||
'setuptools',
|
||||
@@ -45,7 +45,7 @@ setup(
|
||||
author="Certbot Project",
|
||||
author_email='client-dev@letsencrypt.org',
|
||||
license='Apache License 2.0',
|
||||
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*',
|
||||
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
|
||||
classifiers=[
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Environment :: Plugins',
|
||||
@@ -56,7 +56,6 @@ setup(
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
|
||||
@@ -34,7 +34,7 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
super(Authenticator, cls).add_parser_arguments(add, default_propagation_seconds=30)
|
||||
add('credentials', help='DNSimple credentials INI file.')
|
||||
|
||||
def more_info(self): # pylint: disable=missing-docstring,no-self-use
|
||||
def more_info(self): # pylint: disable=missing-function-docstring
|
||||
return 'This plugin configures a DNS TXT record to respond to a dns-01 challenge using ' + \
|
||||
'the DNSimple API.'
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ extensions = ['sphinx.ext.autodoc',
|
||||
'sphinx.ext.viewcode']
|
||||
|
||||
autodoc_member_order = 'bysource'
|
||||
autodoc_default_flags = ['show-inheritance', 'private-members']
|
||||
autodoc_default_flags = ['show-inheritance']
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
@@ -84,7 +84,7 @@ default_role = 'py:obj'
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||
todo_include_todos = True
|
||||
todo_include_todos = False
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Remember to update setup.py to match the package versions below.
|
||||
acme[dev]==0.31.0
|
||||
-e certbot[dev]
|
||||
certbot[dev]==1.1.0
|
||||
|
||||
@@ -5,13 +5,13 @@ from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
from setuptools.command.test import test as TestCommand
|
||||
|
||||
version = '1.1.0.dev0'
|
||||
version = '1.3.0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
install_requires = [
|
||||
'acme>=0.31.0',
|
||||
'certbot>=1.0.0.dev0',
|
||||
'certbot>=1.1.0',
|
||||
'mock',
|
||||
'setuptools',
|
||||
'zope.interface',
|
||||
@@ -56,7 +56,7 @@ setup(
|
||||
author="Certbot Project",
|
||||
author_email='client-dev@letsencrypt.org',
|
||||
license='Apache License 2.0',
|
||||
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*',
|
||||
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
|
||||
classifiers=[
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Environment :: Plugins',
|
||||
@@ -67,7 +67,6 @@ setup(
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
|
||||
@@ -35,7 +35,7 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
super(Authenticator, cls).add_parser_arguments(add, default_propagation_seconds=60)
|
||||
add('credentials', help='DNS Made Easy credentials INI file.')
|
||||
|
||||
def more_info(self): # pylint: disable=missing-docstring,no-self-use
|
||||
def more_info(self): # pylint: disable=missing-function-docstring
|
||||
return 'This plugin configures a DNS TXT record to respond to a dns-01 challenge using ' + \
|
||||
'the DNS Made Easy API.'
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ extensions = ['sphinx.ext.autodoc',
|
||||
'sphinx.ext.viewcode']
|
||||
|
||||
autodoc_member_order = 'bysource'
|
||||
autodoc_default_flags = ['show-inheritance', 'private-members']
|
||||
autodoc_default_flags = ['show-inheritance']
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
@@ -84,7 +84,7 @@ default_role = 'py:obj'
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||
todo_include_todos = True
|
||||
todo_include_todos = False
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Remember to update setup.py to match the package versions below.
|
||||
acme[dev]==0.31.0
|
||||
-e certbot[dev]
|
||||
certbot[dev]==1.1.0
|
||||
|
||||
@@ -4,13 +4,13 @@ from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
from setuptools.command.test import test as TestCommand
|
||||
|
||||
version = '1.1.0.dev0'
|
||||
version = '1.3.0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
install_requires = [
|
||||
'acme>=0.31.0',
|
||||
'certbot>=1.0.0.dev0',
|
||||
'certbot>=1.1.0',
|
||||
'dns-lexicon>=2.2.1', # Support for >1 TXT record per name
|
||||
'mock',
|
||||
'setuptools',
|
||||
@@ -44,7 +44,7 @@ setup(
|
||||
author="Certbot Project",
|
||||
author_email='client-dev@letsencrypt.org',
|
||||
license='Apache License 2.0',
|
||||
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*',
|
||||
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
|
||||
classifiers=[
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Environment :: Plugins',
|
||||
@@ -55,7 +55,6 @@ setup(
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
|
||||
@@ -1 +1 @@
|
||||
Gehirn Infrastracture Service DNS Authenticator plugin for Certbot
|
||||
Gehirn Infrastructure Service DNS Authenticator plugin for Certbot
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
"""
|
||||
The `~certbot_dns_gehirn.dns_gehirn` plugin automates the process of completing
|
||||
a ``dns-01`` challenge (`~acme.challenges.DNS01`) by creating, and subsequently
|
||||
removing, TXT records using the Gehirn Infrastracture Service DNS API.
|
||||
removing, TXT records using the Gehirn Infrastructure Service DNS API.
|
||||
|
||||
|
||||
Named Arguments
|
||||
---------------
|
||||
|
||||
======================================== =====================================
|
||||
``--dns-gehirn-credentials`` Gehirn Infrastracture Service
|
||||
``--dns-gehirn-credentials`` Gehirn Infrastructure Service
|
||||
credentials_ INI file.
|
||||
(Required)
|
||||
``--dns-gehirn-propagation-seconds`` The number of seconds to wait for DNS
|
||||
@@ -22,15 +22,15 @@ Credentials
|
||||
-----------
|
||||
|
||||
Use of this plugin requires a configuration file containing
|
||||
Gehirn Infrastracture Service DNS API credentials,
|
||||
obtained from your Gehirn Infrastracture Service
|
||||
Gehirn Infrastructure Service DNS API credentials,
|
||||
obtained from your Gehirn Infrastructure Service
|
||||
`dashboard <https://gis.gehirn.jp/>`_.
|
||||
|
||||
.. code-block:: ini
|
||||
:name: credentials.ini
|
||||
:caption: Example credentials file:
|
||||
|
||||
# Gehirn Infrastracture Service API credentials used by Certbot
|
||||
# Gehirn Infrastructure Service API credentials used by Certbot
|
||||
dns_gehirn_api_token = 00000000-0000-0000-0000-000000000000
|
||||
dns_gehirn_api_secret = MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw
|
||||
|
||||
@@ -40,7 +40,7 @@ to this file for use during renewal, but does not store the file's contents.
|
||||
|
||||
.. caution::
|
||||
You should protect these API credentials as you would the password to your
|
||||
Gehirn Infrastracture Service account. Users who can read this file can use
|
||||
Gehirn Infrastructure Service account. Users who can read this file can use
|
||||
these credentials to issue arbitrary API calls on your behalf. Users who can
|
||||
cause Certbot to run using these credentials can complete a ``dns-01``
|
||||
challenge to acquire new certificates or revoke existing certificates for
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""DNS Authenticator for Gehirn Infrastracture Service DNS."""
|
||||
"""DNS Authenticator for Gehirn Infrastructure Service DNS."""
|
||||
import logging
|
||||
|
||||
from lexicon.providers import gehirn
|
||||
@@ -15,14 +15,14 @@ DASHBOARD_URL = "https://gis.gehirn.jp/"
|
||||
@zope.interface.implementer(interfaces.IAuthenticator)
|
||||
@zope.interface.provider(interfaces.IPluginFactory)
|
||||
class Authenticator(dns_common.DNSAuthenticator):
|
||||
"""DNS Authenticator for Gehirn Infrastracture Service DNS
|
||||
"""DNS Authenticator for Gehirn Infrastructure Service DNS
|
||||
|
||||
This Authenticator uses the Gehirn Infrastracture Service API to fulfill
|
||||
This Authenticator uses the Gehirn Infrastructure Service API to fulfill
|
||||
a dns-01 challenge.
|
||||
"""
|
||||
|
||||
description = 'Obtain certificates using a DNS TXT record ' + \
|
||||
'(if you are using Gehirn Infrastracture Service for DNS).'
|
||||
'(if you are using Gehirn Infrastructure Service for DNS).'
|
||||
ttl = 60
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -32,20 +32,20 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
@classmethod
|
||||
def add_parser_arguments(cls, add): # pylint: disable=arguments-differ
|
||||
super(Authenticator, cls).add_parser_arguments(add, default_propagation_seconds=30)
|
||||
add('credentials', help='Gehirn Infrastracture Service credentials file.')
|
||||
add('credentials', help='Gehirn Infrastructure Service credentials file.')
|
||||
|
||||
def more_info(self): # pylint: disable=missing-docstring,no-self-use
|
||||
def more_info(self): # pylint: disable=missing-function-docstring
|
||||
return 'This plugin configures a DNS TXT record to respond to a dns-01 challenge using ' + \
|
||||
'the Gehirn Infrastracture Service API.'
|
||||
'the Gehirn Infrastructure Service API.'
|
||||
|
||||
def _setup_credentials(self):
|
||||
self.credentials = self._configure_credentials(
|
||||
'credentials',
|
||||
'Gehirn Infrastracture Service credentials file',
|
||||
'Gehirn Infrastructure Service credentials file',
|
||||
{
|
||||
'api-token': 'API token for Gehirn Infrastracture Service ' + \
|
||||
'api-token': 'API token for Gehirn Infrastructure Service ' + \
|
||||
'API obtained from {0}'.format(DASHBOARD_URL),
|
||||
'api-secret': 'API secret for Gehirn Infrastracture Service ' + \
|
||||
'api-secret': 'API secret for Gehirn Infrastructure Service ' + \
|
||||
'API obtained from {0}'.format(DASHBOARD_URL),
|
||||
}
|
||||
)
|
||||
@@ -66,7 +66,7 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
|
||||
class _GehirnLexiconClient(dns_common_lexicon.LexiconClient):
|
||||
"""
|
||||
Encapsulates all communication with the Gehirn Infrastracture Service via Lexicon.
|
||||
Encapsulates all communication with the Gehirn Infrastructure Service via Lexicon.
|
||||
"""
|
||||
|
||||
def __init__(self, api_token, api_secret, ttl):
|
||||
|
||||
@@ -38,7 +38,7 @@ extensions = ['sphinx.ext.autodoc',
|
||||
'sphinx.ext.viewcode']
|
||||
|
||||
autodoc_member_order = 'bysource'
|
||||
autodoc_default_flags = ['show-inheritance', 'private-members']
|
||||
autodoc_default_flags = ['show-inheritance']
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
@@ -84,7 +84,7 @@ default_role = 'py:obj'
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||
todo_include_todos = True
|
||||
todo_include_todos = False
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Remember to update setup.py to match the package versions below.
|
||||
acme[dev]==0.31.0
|
||||
-e certbot[dev]
|
||||
certbot[dev]==1.1.0
|
||||
|
||||
@@ -4,12 +4,12 @@ from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
from setuptools.command.test import test as TestCommand
|
||||
|
||||
version = '1.1.0.dev0'
|
||||
version = '1.3.0'
|
||||
|
||||
# Please update tox.ini when modifying dependency version requirements
|
||||
install_requires = [
|
||||
'acme>=0.31.0',
|
||||
'certbot>=1.0.0.dev0',
|
||||
'certbot>=1.1.0',
|
||||
'dns-lexicon>=2.1.22',
|
||||
'mock',
|
||||
'setuptools',
|
||||
@@ -38,12 +38,12 @@ class PyTest(TestCommand):
|
||||
setup(
|
||||
name='certbot-dns-gehirn',
|
||||
version=version,
|
||||
description="Gehirn Infrastracture Service DNS Authenticator plugin for Certbot",
|
||||
description="Gehirn Infrastructure Service DNS Authenticator plugin for Certbot",
|
||||
url='https://github.com/certbot/certbot',
|
||||
author="Certbot Project",
|
||||
author_email='client-dev@letsencrypt.org',
|
||||
license='Apache License 2.0',
|
||||
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*',
|
||||
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
|
||||
classifiers=[
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Environment :: Plugins',
|
||||
@@ -54,7 +54,6 @@ setup(
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
|
||||
@@ -45,7 +45,7 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
'required permissions.)').format(ACCT_URL, PERMISSIONS_URL),
|
||||
default=None)
|
||||
|
||||
def more_info(self): # pylint: disable=missing-docstring,no-self-use
|
||||
def more_info(self): # pylint: disable=missing-function-docstring
|
||||
return 'This plugin configures a DNS TXT record to respond to a dns-01 challenge using ' + \
|
||||
'the Google Cloud DNS API.'
|
||||
|
||||
@@ -148,7 +148,7 @@ class _GoogleClient(object):
|
||||
},
|
||||
]
|
||||
|
||||
changes = self.dns.changes() # changes | pylint: disable=no-member
|
||||
changes = self.dns.changes()
|
||||
|
||||
try:
|
||||
request = changes.create(project=self.project_id, managedZone=zone_id, body=data)
|
||||
@@ -213,7 +213,7 @@ class _GoogleClient(object):
|
||||
},
|
||||
]
|
||||
|
||||
changes = self.dns.changes() # changes | pylint: disable=no-member
|
||||
changes = self.dns.changes()
|
||||
|
||||
try:
|
||||
request = changes.create(project=self.project_id, managedZone=zone_id, body=data)
|
||||
@@ -264,7 +264,7 @@ class _GoogleClient(object):
|
||||
|
||||
zone_dns_name_guesses = dns_common.base_domain_name_guesses(domain)
|
||||
|
||||
mz = self.dns.managedZones() # managedZones | pylint: disable=no-member
|
||||
mz = self.dns.managedZones()
|
||||
for zone_name in zone_dns_name_guesses:
|
||||
try:
|
||||
request = mz.list(project=self.project_id, dnsName=zone_name + '.')
|
||||
|
||||
@@ -39,7 +39,7 @@ extensions = ['sphinx.ext.autodoc',
|
||||
'jsonlexer']
|
||||
|
||||
autodoc_member_order = 'bysource'
|
||||
autodoc_default_flags = ['show-inheritance', 'private-members']
|
||||
autodoc_default_flags = ['show-inheritance']
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
@@ -85,7 +85,7 @@ default_role = 'py:obj'
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||
todo_include_todos = True
|
||||
todo_include_todos = False
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Remember to update setup.py to match the package versions below.
|
||||
acme[dev]==0.29.0
|
||||
-e certbot[dev]
|
||||
certbot[dev]==1.1.0
|
||||
|
||||
@@ -4,13 +4,13 @@ from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
from setuptools.command.test import test as TestCommand
|
||||
|
||||
version = '1.1.0.dev0'
|
||||
version = '1.3.0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
install_requires = [
|
||||
'acme>=0.29.0',
|
||||
'certbot>=1.0.0.dev0',
|
||||
'certbot>=1.1.0',
|
||||
'google-api-python-client>=1.5.5',
|
||||
'mock',
|
||||
'oauth2client>=4.0',
|
||||
@@ -47,7 +47,7 @@ setup(
|
||||
author="Certbot Project",
|
||||
author_email='client-dev@letsencrypt.org',
|
||||
license='Apache License 2.0',
|
||||
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*',
|
||||
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
|
||||
classifiers=[
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Environment :: Plugins',
|
||||
@@ -58,7 +58,6 @@ setup(
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
|
||||
@@ -35,7 +35,7 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
super(Authenticator, cls).add_parser_arguments(add, default_propagation_seconds=1200)
|
||||
add('credentials', help='Linode credentials INI file.')
|
||||
|
||||
def more_info(self): # pylint: disable=missing-docstring,no-self-use
|
||||
def more_info(self): # pylint: disable=missing-function-docstring
|
||||
return 'This plugin configures a DNS TXT record to respond to a dns-01 challenge using ' + \
|
||||
'the Linode API.'
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ extensions = ['sphinx.ext.autodoc',
|
||||
'sphinx.ext.viewcode']
|
||||
|
||||
autodoc_member_order = 'bysource'
|
||||
autodoc_default_flags = ['show-inheritance', 'private-members']
|
||||
autodoc_default_flags = ['show-inheritance']
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
@@ -84,7 +84,7 @@ default_role = 'py:obj'
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||
todo_include_todos = True
|
||||
todo_include_todos = False
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Remember to update setup.py to match the package versions below.
|
||||
acme[dev]==0.31.0
|
||||
-e certbot[dev]
|
||||
certbot[dev]==1.1.0
|
||||
dns-lexicon==2.2.3
|
||||
|
||||
@@ -4,12 +4,12 @@ from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
from setuptools.command.test import test as TestCommand
|
||||
|
||||
version = '1.1.0.dev0'
|
||||
version = '1.3.0'
|
||||
|
||||
# Please update tox.ini when modifying dependency version requirements
|
||||
install_requires = [
|
||||
'acme>=0.31.0',
|
||||
'certbot>=1.0.0.dev0',
|
||||
'certbot>=1.1.0',
|
||||
'dns-lexicon>=2.2.3',
|
||||
'mock',
|
||||
'setuptools',
|
||||
@@ -43,7 +43,7 @@ setup(
|
||||
author="Certbot Project",
|
||||
author_email='client-dev@letsencrypt.org',
|
||||
license='Apache License 2.0',
|
||||
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*',
|
||||
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
|
||||
classifiers=[
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Environment :: Plugins',
|
||||
@@ -54,7 +54,6 @@ setup(
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
|
||||
@@ -34,7 +34,7 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
super(Authenticator, cls).add_parser_arguments(add, default_propagation_seconds=30)
|
||||
add('credentials', help='LuaDNS credentials INI file.')
|
||||
|
||||
def more_info(self): # pylint: disable=missing-docstring,no-self-use
|
||||
def more_info(self): # pylint: disable=missing-function-docstring
|
||||
return 'This plugin configures a DNS TXT record to respond to a dns-01 challenge using ' + \
|
||||
'the LuaDNS API.'
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ extensions = ['sphinx.ext.autodoc',
|
||||
'sphinx.ext.viewcode']
|
||||
|
||||
autodoc_member_order = 'bysource'
|
||||
autodoc_default_flags = ['show-inheritance', 'private-members']
|
||||
autodoc_default_flags = ['show-inheritance']
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
@@ -84,7 +84,7 @@ default_role = 'py:obj'
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||
todo_include_todos = True
|
||||
todo_include_todos = False
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Remember to update setup.py to match the package versions below.
|
||||
acme[dev]==0.31.0
|
||||
-e certbot[dev]
|
||||
certbot[dev]==1.1.0
|
||||
|
||||
@@ -4,13 +4,13 @@ from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
from setuptools.command.test import test as TestCommand
|
||||
|
||||
version = '1.1.0.dev0'
|
||||
version = '1.3.0'
|
||||
|
||||
# Remember to update local-oldest-requirements.txt when changing the minimum
|
||||
# acme/certbot version.
|
||||
install_requires = [
|
||||
'acme>=0.31.0',
|
||||
'certbot>=1.0.0.dev0',
|
||||
'certbot>=1.1.0',
|
||||
'dns-lexicon>=2.2.1', # Support for >1 TXT record per name
|
||||
'mock',
|
||||
'setuptools',
|
||||
@@ -44,7 +44,7 @@ setup(
|
||||
author="Certbot Project",
|
||||
author_email='client-dev@letsencrypt.org',
|
||||
license='Apache License 2.0',
|
||||
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*',
|
||||
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
|
||||
classifiers=[
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Environment :: Plugins',
|
||||
@@ -55,7 +55,6 @@ setup(
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
|
||||
@@ -34,7 +34,7 @@ class Authenticator(dns_common.DNSAuthenticator):
|
||||
super(Authenticator, cls).add_parser_arguments(add, default_propagation_seconds=30)
|
||||
add('credentials', help='NS1 credentials file.')
|
||||
|
||||
def more_info(self): # pylint: disable=missing-docstring,no-self-use
|
||||
def more_info(self): # pylint: disable=missing-function-docstring
|
||||
return 'This plugin configures a DNS TXT record to respond to a dns-01 challenge using ' + \
|
||||
'the NS1 API.'
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ extensions = ['sphinx.ext.autodoc',
|
||||
'sphinx.ext.viewcode']
|
||||
|
||||
autodoc_member_order = 'bysource'
|
||||
autodoc_default_flags = ['show-inheritance', 'private-members']
|
||||
autodoc_default_flags = ['show-inheritance']
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
@@ -84,7 +84,7 @@ default_role = 'py:obj'
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||
todo_include_todos = True
|
||||
todo_include_todos = False
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Remember to update setup.py to match the package versions below.
|
||||
acme[dev]==0.31.0
|
||||
-e certbot[dev]
|
||||
certbot[dev]==1.1.0
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user